LibreOffice Module vcl (master)  1
bmpfast.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <bmpfast.hxx>
21 #include <vcl/bitmapaccess.hxx>
22 #include <vcl/salgtype.hxx>
23 #include <bitmapwriteaccess.hxx>
24 
25 #include <sal/log.hxx>
26 
27 typedef unsigned char PIXBYTE;
28 
29 namespace {
30 
31 class BasePixelPtr
32 {
33 public:
34  explicit BasePixelPtr( PIXBYTE* p = nullptr ) : mpPixel( p ) {}
35  void SetRawPtr( PIXBYTE* pRawPtr ) { mpPixel = pRawPtr; }
36  void AddByteOffset( int nByteOffset ) { mpPixel += nByteOffset; }
37 
38 protected:
39  PIXBYTE* mpPixel;
40 };
41 
42 template <ScanlineFormat PIXFMT>
43 class TrueColorPixelPtr : public BasePixelPtr
44 {
45 public:
46  PIXBYTE GetRed() const;
47  PIXBYTE GetGreen() const;
48  PIXBYTE GetBlue() const;
49  PIXBYTE GetAlpha() const;
50 
51  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const;
52  void SetAlpha( PIXBYTE a ) const;
53 };
54 
55 // template specializations for truecolor pixel formats
56 template <>
57 class TrueColorPixelPtr<ScanlineFormat::N24BitTcRgb> : public BasePixelPtr
58 {
59 public:
60  void operator++() { mpPixel += 3; }
61 
62  PIXBYTE GetRed() const { return mpPixel[0]; }
63  PIXBYTE GetGreen() const { return mpPixel[1]; }
64  PIXBYTE GetBlue() const { return mpPixel[2]; }
65  static PIXBYTE GetAlpha() { return 0; }
66  static void SetAlpha( PIXBYTE ) {}
67 
68  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
69  {
70  mpPixel[0] = r;
71  mpPixel[1] = g;
72  mpPixel[2] = b;
73  }
74 };
75 
76 template <>
77 class TrueColorPixelPtr<ScanlineFormat::N24BitTcBgr> : public BasePixelPtr
78 {
79 public:
80  void operator++() { mpPixel += 3; }
81 
82  PIXBYTE GetRed() const { return mpPixel[2]; }
83  PIXBYTE GetGreen() const { return mpPixel[1]; }
84  PIXBYTE GetBlue() const { return mpPixel[0]; }
85  static PIXBYTE GetAlpha() { return 0; }
86  static void SetAlpha( PIXBYTE ) {}
87 
88  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
89  {
90  mpPixel[0] = b;
91  mpPixel[1] = g;
92  mpPixel[2] = r;
93  }
94 };
95 
96 template <>
97 class TrueColorPixelPtr<ScanlineFormat::N32BitTcArgb> : public BasePixelPtr
98 {
99 public:
100  void operator++() { mpPixel += 4; }
101 
102  PIXBYTE GetRed() const { return mpPixel[1]; }
103  PIXBYTE GetGreen() const { return mpPixel[2]; }
104  PIXBYTE GetBlue() const { return mpPixel[3]; }
105  PIXBYTE GetAlpha() const { return mpPixel[0]; }
106  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
107 
108  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
109  {
110  mpPixel[1] = r;
111  mpPixel[2] = g;
112  mpPixel[3] = b;
113  }
114 };
115 
116 template <>
117 class TrueColorPixelPtr<ScanlineFormat::N32BitTcAbgr> : public BasePixelPtr
118 {
119 public:
120  void operator++() { mpPixel += 4; }
121 
122  PIXBYTE GetRed() const { return mpPixel[3]; }
123  PIXBYTE GetGreen() const { return mpPixel[2]; }
124  PIXBYTE GetBlue() const { return mpPixel[1]; }
125  PIXBYTE GetAlpha() const { return mpPixel[0]; }
126  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
127 
128  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
129  {
130  mpPixel[1] = b;
131  mpPixel[2] = g;
132  mpPixel[3] = r;
133  }
134 };
135 
136 template <>
137 class TrueColorPixelPtr<ScanlineFormat::N32BitTcRgba> : public BasePixelPtr
138 {
139 public:
140  void operator++() { mpPixel += 4; }
141 
142  PIXBYTE GetRed() const { return mpPixel[0]; }
143  PIXBYTE GetGreen() const { return mpPixel[1]; }
144  PIXBYTE GetBlue() const { return mpPixel[2]; }
145  PIXBYTE GetAlpha() const { return mpPixel[3]; }
146  void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
147 
148  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
149  {
150  mpPixel[0] = r;
151  mpPixel[1] = g;
152  mpPixel[2] = b;
153  }
154 };
155 
156 template <>
157 class TrueColorPixelPtr<ScanlineFormat::N32BitTcBgra> : public BasePixelPtr
158 {
159 public:
160  void operator++() { mpPixel += 4; }
161 
162  PIXBYTE GetRed() const { return mpPixel[2]; }
163  PIXBYTE GetGreen() const { return mpPixel[1]; }
164  PIXBYTE GetBlue() const { return mpPixel[0]; }
165  PIXBYTE GetAlpha() const { return mpPixel[3]; }
166  void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
167 
168  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
169  {
170  mpPixel[0] = b;
171  mpPixel[1] = g;
172  mpPixel[2] = r;
173  }
174 };
175 
176 template <>
177 class TrueColorPixelPtr<ScanlineFormat::N8BitTcMask> : public BasePixelPtr
178 {
179 public:
180  void operator++() { mpPixel += 1; }
181  PIXBYTE GetAlpha() const { return mpPixel[0]; }
182 };
183 
184 // TODO: for some reason many Alpha maps are ScanlineFormat::N8BitPal
185 // they should be ScanlineFormat::N8BitTcMask
186 template <>
187 class TrueColorPixelPtr<ScanlineFormat::N8BitPal>
188 : public TrueColorPixelPtr<ScanlineFormat::N8BitTcMask>
189 {};
190 
191 }
192 
193 // converting truecolor formats
194 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
195 static void ImplConvertPixel( const TrueColorPixelPtr<DSTFMT>& rDst,
196  const TrueColorPixelPtr<SRCFMT>& rSrc )
197 {
198  rDst.SetColor( rSrc.GetRed(), rSrc.GetGreen(), rSrc.GetBlue() );
199  rDst.SetAlpha( rSrc.GetAlpha() );
200 }
201 
202 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
203 static void ImplConvertLine( const TrueColorPixelPtr<DSTFMT>& rDst,
204  const TrueColorPixelPtr<SRCFMT>& rSrc, int nPixelCount )
205 {
206  TrueColorPixelPtr<DSTFMT> aDst( rDst );
207  TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
208  while( --nPixelCount >= 0 )
209  {
210  ImplConvertPixel( aDst, aSrc );
211  ++aSrc;
212  ++aDst;
213  }
214 }
215 
216 // alpha blending truecolor pixels
217 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
218 static void ImplBlendPixels( const TrueColorPixelPtr<DSTFMT>& rDst,
219  const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal )
220 {
221  static const unsigned nAlphaShift = 8;
222  if( !nAlphaVal )
223  ImplConvertPixel( rDst, rSrc );
224  else if( nAlphaVal != ~(~0U << nAlphaShift) )
225  {
226  int nR = rDst.GetRed();
227  int nS = rSrc.GetRed();
228  nR = nS + (((nR - nS) * nAlphaVal) >> nAlphaShift);
229 
230  int nG = rDst.GetGreen();
231  nS = rSrc.GetGreen();
232  nG = nS + (((nG - nS) * nAlphaVal) >> nAlphaShift);
233 
234  int nB = rDst.GetBlue();
235  nS = rSrc.GetBlue();
236  nB = nS + (((nB - nS) * nAlphaVal) >> nAlphaShift);
237 
238  rDst.SetColor( sal::static_int_cast<PIXBYTE>(nR),
239  sal::static_int_cast<PIXBYTE>(nG),
240  sal::static_int_cast<PIXBYTE>(nB) );
241  }
242 }
243 
244 template <ScanlineFormat MASKFMT, ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
245 static void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst,
246  const TrueColorPixelPtr<SRCFMT>& rSrc, const TrueColorPixelPtr<MASKFMT>& rMsk,
247  int nPixelCount )
248 {
249  TrueColorPixelPtr<MASKFMT> aMsk( rMsk );
250  TrueColorPixelPtr<DSTFMT> aDst( rDst );
251  TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
252  while( --nPixelCount >= 0 )
253  {
254  ImplBlendPixels(aDst, aSrc, aMsk.GetAlpha());
255  ++aDst;
256  ++aSrc;
257  ++aMsk;
258  }
259 }
260 
261 static bool ImplCopyImage( BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
262 {
263  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
264  int nDstLinestep = rDstBuffer.mnScanlineSize;
265 
266  const PIXBYTE* pRawSrc = rSrcBuffer.mpBits;
267  PIXBYTE* pRawDst = rDstBuffer.mpBits;
268 
269  // source and destination don't match upside down
270  if( ScanlineFormat::TopDown & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
271  {
272  pRawDst += (rSrcBuffer.mnHeight - 1) * nDstLinestep;
273  nDstLinestep = -rDstBuffer.mnScanlineSize;
274  }
275  else if( nSrcLinestep == nDstLinestep )
276  {
277  memcpy( pRawDst, pRawSrc, rSrcBuffer.mnHeight * nDstLinestep );
278  return true;
279  }
280 
281  int nByteWidth = nSrcLinestep;
282  if( nByteWidth > rDstBuffer.mnScanlineSize )
283  nByteWidth = rDstBuffer.mnScanlineSize;
284 
285  for( int y = rSrcBuffer.mnHeight; --y >= 0; )
286  {
287  memcpy( pRawDst, pRawSrc, nByteWidth );
288  pRawSrc += nSrcLinestep;
289  pRawDst += nDstLinestep;
290  }
291 
292  return true;
293 }
294 
295 template <ScanlineFormat DSTFMT,ScanlineFormat SRCFMT>
296 static bool ImplConvertToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine,
297  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
298 {
299  // help the compiler to avoid instantiations of unneeded conversions
300  SAL_WARN_IF( SRCFMT == DSTFMT, "vcl.gdi", "ImplConvertToBitmap into same format");
301  if( SRCFMT == DSTFMT )
302  return false;
303 
304  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
305  int nDstLinestep = rDstBuffer.mnScanlineSize;
306 
307  TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
308 
309  // source and destination don't match upside down
310  if( ScanlineFormat::TopDown & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
311  {
312  aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep );
313  nDstLinestep = -nDstLinestep;
314  }
315 
316  for( int y = rSrcBuffer.mnHeight; --y >= 0; )
317  {
318  ImplConvertLine( aDstLine, rSrcLine, rSrcBuffer.mnWidth );
319  rSrcLine.AddByteOffset( nSrcLinestep );
320  aDstLine.AddByteOffset( nDstLinestep );
321  }
322 
323  return true;
324 }
325 
326 template <ScanlineFormat SRCFMT>
327 static bool ImplConvertFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc )
328 {
329  TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
330 
331  // select the matching instantiation for the destination's bitmap format
332  switch (RemoveScanline(rDst.mnFormat))
333  {
339  break;
340 
342 // return ImplConvertToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc );
344 // return ImplConvertToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc );
345  break;
346 
348  return ImplConvertToBitmap<ScanlineFormat::N24BitTcBgr>( aSrcType, rDst, rSrc );
350  return ImplConvertToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDst, rSrc );
351 
353  return ImplConvertToBitmap<ScanlineFormat::N32BitTcAbgr>( aSrcType, rDst, rSrc );
355  return ImplConvertToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDst, rSrc );
357  return ImplConvertToBitmap<ScanlineFormat::N32BitTcBgra>( aSrcType, rDst, rSrc );
359  return ImplConvertToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDst, rSrc );
360  default: break;
361  }
362 
363  static int nNotAccelerated = 0;
364  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
365  "vcl.gdi",
366  "ImplConvertFromBitmap for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
367 
368  return false;
369 }
370 
371 // A universal stretching conversion is overkill in most common situations
372 // => performance benefits for speeding up the non-stretching cases
374  const SalTwoRect& rTR )
375 {
376  // TODO:horizontal mirroring not implemented yet
377  if( rTR.mnDestWidth < 0 )
378  return false;
379  // vertical mirroring
380  if( rTR.mnDestHeight < 0 )
381  // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
382  return false;
383 
384  // offsetted conversion is not implemented yet
385  if( rTR.mnSrcX || rTR.mnSrcY )
386  return false;
387  if( rTR.mnDestX || rTR.mnDestY )
388  return false;
389 
390  // stretched conversion is not implemented yet
391  if( rTR.mnDestWidth != rTR.mnSrcWidth )
392  return false;
393  if( rTR.mnDestHeight!= rTR.mnSrcHeight )
394  return false;
395 
396  // check source image size
397  if( rSrc.mnWidth < rTR.mnSrcX + rTR.mnSrcWidth )
398  return false;
399  if( rSrc.mnHeight < rTR.mnSrcY + rTR.mnSrcHeight )
400  return false;
401 
402  // check dest image size
403  if( rDst.mnWidth < rTR.mnDestX + rTR.mnDestWidth )
404  return false;
405  if( rDst.mnHeight < rTR.mnDestY + rTR.mnDestHeight )
406  return false;
407 
408  const ScanlineFormat nSrcFormat = RemoveScanline(rSrc.mnFormat);
409  const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
410 
411  // special handling of trivial cases
412  if( nSrcFormat == nDstFormat )
413  {
414  // accelerated palette conversions not yet implemented
415  if( rSrc.maPalette != rDst.maPalette )
416  return false;
417  return ImplCopyImage( rDst, rSrc );
418  }
419 
420  // select the matching instantiation for the source's bitmap format
421  switch( nSrcFormat )
422  {
428  break;
429 
431 // return ImplConvertFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
433 // return ImplConvertFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
434  break;
435 
437  return ImplConvertFromBitmap<ScanlineFormat::N24BitTcBgr>( rDst, rSrc );
439  return ImplConvertFromBitmap<ScanlineFormat::N24BitTcRgb>( rDst, rSrc );
440 
442  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcAbgr>( rDst, rSrc );
444  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcArgb>( rDst, rSrc );
446  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcBgra>( rDst, rSrc );
448  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcRgba>( rDst, rSrc );
449  default: break;
450  }
451 
452  static int nNotAccelerated = 0;
453  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
454  "vcl.gdi",
455  "ImplFastBitmapConversion for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
456 
457  return false;
458 }
459 
460 template <ScanlineFormat DSTFMT, ScanlineFormat SRCFMT> //,sal_uLong MSKFMT>
461 static bool ImplBlendToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine,
462  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
463  const BitmapBuffer& rMskBuffer )
464 {
465  SAL_WARN_IF( rMskBuffer.mnFormat != ScanlineFormat::N8BitPal, "vcl.gdi", "FastBmp BlendImage: unusual MSKFMT" );
466 
467  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
468  int nMskLinestep = rMskBuffer.mnScanlineSize;
469  int nDstLinestep = rDstBuffer.mnScanlineSize;
470 
471  TrueColorPixelPtr<ScanlineFormat::N8BitPal> aMskLine; aMskLine.SetRawPtr( rMskBuffer.mpBits );
472  TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
473 
474  // special case for single line masks
475  if( rMskBuffer.mnHeight == 1 )
476  nMskLinestep = 0;
477 
478  // source and mask don't match: upside down
479  if( (rSrcBuffer.mnFormat ^ rMskBuffer.mnFormat) & ScanlineFormat::TopDown )
480  {
481  aMskLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nMskLinestep );
482  nMskLinestep = -nMskLinestep;
483  }
484 
485  // source and destination don't match: upside down
486  if( (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) & ScanlineFormat::TopDown )
487  {
488  aDstLine.AddByteOffset( (rDstBuffer.mnHeight - 1) * nDstLinestep );
489  nDstLinestep = -nDstLinestep;
490  }
491 
492  assert(rDstBuffer.mnHeight <= rSrcBuffer.mnHeight && "not sure about that?");
493  for (int y = rDstBuffer.mnHeight; --y >= 0;)
494  {
495  ImplBlendLines(aDstLine, rSrcLine, aMskLine, rDstBuffer.mnWidth);
496  aDstLine.AddByteOffset( nDstLinestep );
497  rSrcLine.AddByteOffset( nSrcLinestep );
498  aMskLine.AddByteOffset( nMskLinestep );
499  }
500 
501  return true;
502 }
503 
504 // some specializations to reduce the code size
505 template <>
506 bool ImplBlendToBitmap<ScanlineFormat::N24BitTcBgr,ScanlineFormat::N24BitTcBgr>(
507  TrueColorPixelPtr<ScanlineFormat::N24BitTcBgr>&,
508  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
509  const BitmapBuffer& rMskBuffer )
510  {
511  TrueColorPixelPtr<ScanlineFormat::N24BitTcRgb> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
512  return ImplBlendToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
513  }
514 
515 template <>
516 bool ImplBlendToBitmap<ScanlineFormat::N32BitTcAbgr,ScanlineFormat::N32BitTcAbgr>(
517  TrueColorPixelPtr<ScanlineFormat::N32BitTcAbgr>&,
518  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
519  const BitmapBuffer& rMskBuffer )
520  {
521  TrueColorPixelPtr<ScanlineFormat::N32BitTcArgb> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
522  return ImplBlendToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
523  }
524 
525 template <>
526 bool ImplBlendToBitmap<ScanlineFormat::N32BitTcBgra,ScanlineFormat::N32BitTcBgra>(
527  TrueColorPixelPtr<ScanlineFormat::N32BitTcBgra>&,
528  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
529  const BitmapBuffer& rMskBuffer )
530  {
531  TrueColorPixelPtr<ScanlineFormat::N32BitTcRgba> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
532  return ImplBlendToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
533  }
534 
535 template <ScanlineFormat SRCFMT>
536 static bool ImplBlendFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc, const BitmapBuffer& rMsk )
537 {
538  TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
539 
540  // select the matching instantiation for the destination's bitmap format
541  switch (RemoveScanline(rDst.mnFormat))
542  {
548  break;
549 
551 // return ImplBlendToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc, rMsk );
553 // return ImplBlendToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc, rMsk );
554  break;
555 
557  return ImplBlendToBitmap<ScanlineFormat::N24BitTcBgr>( aSrcType, rDst, rSrc, rMsk );
559  return ImplBlendToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDst, rSrc, rMsk );
560 
562  return ImplBlendToBitmap<ScanlineFormat::N32BitTcAbgr>( aSrcType, rDst, rSrc, rMsk );
564  return ImplBlendToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDst, rSrc, rMsk );
566  return ImplBlendToBitmap<ScanlineFormat::N32BitTcBgra>( aSrcType, rDst, rSrc, rMsk );
568  return ImplBlendToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDst, rSrc, rMsk );
569  default: break;
570  }
571 
572  static int nNotAccelerated = 0;
573  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
574  "vcl.gdi",
575  "ImplBlendFromBitmap for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "*" << static_cast<int>(rMsk.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) );
576  return false;
577 }
578 
580  const BitmapReadAccess& rSrcRA, const BitmapReadAccess& rMskRA,
581  const SalTwoRect& rTR )
582 {
583  // accelerated blending of paletted bitmaps not implemented yet
584  if( rSrcRA.HasPalette() )
585  return false;
586  if( rDstWA.HasPalette() )
587  return false;
588  // TODO: either get rid of mask's use of 8BIT_PAL or check the palette
589 
590  // horizontal mirroring not implemented yet
591  if( rTR.mnDestWidth < 0 )
592  return false;
593  // vertical mirroring
594  if( rTR.mnDestHeight < 0 )
595  // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
596  return false;
597 
598  // offsetted blending is not implemented yet
599  if( rTR.mnSrcX || rTR.mnSrcY )
600  return false;
601  if( rTR.mnDestX || rTR.mnDestY )
602  return false;
603 
604  // stretched blending is not implemented yet
605  if( rTR.mnDestWidth != rTR.mnSrcWidth )
606  return false;
607  if( rTR.mnDestHeight!= rTR.mnSrcHeight )
608  return false;
609 
610  // check source image size
611  if( rSrcRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
612  return false;
613  if( rSrcRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
614  return false;
615 
616  // check mask image size
617  if( rMskRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
618  return false;
619  if( rMskRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
620  if( rMskRA.Height() != 1 )
621  return false;
622 
623  // check dest image size
624  if( rDstWA.Width() < rTR.mnDestX + rTR.mnDestWidth )
625  return false;
626  if( rDstWA.Height() < rTR.mnDestY + rTR.mnDestHeight )
627  return false;
628 
629  BitmapBuffer& rDst = *rDstWA.ImplGetBitmapBuffer();
630  const BitmapBuffer& rSrc = *rSrcRA.ImplGetBitmapBuffer();
631  const BitmapBuffer& rMsk = *rMskRA.ImplGetBitmapBuffer();
632 
633  const ScanlineFormat nSrcFormat = RemoveScanline(rSrc.mnFormat);
634 
635  // select the matching instantiation for the source's bitmap format
636  switch( nSrcFormat )
637  {
643  break;
644 
646 // return ImplBlendFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
648 // return ImplBlendFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
649  break;
650 
652  return ImplBlendFromBitmap<ScanlineFormat::N24BitTcBgr>( rDst, rSrc, rMsk );
654  return ImplBlendFromBitmap<ScanlineFormat::N24BitTcRgb>( rDst, rSrc, rMsk );
655 
657  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcAbgr>( rDst, rSrc, rMsk );
659  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcArgb>( rDst, rSrc, rMsk );
661  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcBgra>( rDst, rSrc, rMsk );
663  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcRgba>( rDst, rSrc, rMsk );
664  default: break;
665  }
666 
667  static int nNotAccelerated = 0;
668  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
669  "vcl.gdi",
670  "ImplFastBlend for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "*" << static_cast<int>(rMsk.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
671 
672  return false;
673 }
674 
675 bool ImplFastEraseBitmap( BitmapBuffer& rDst, const BitmapColor& rColor )
676 {
677  const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
678 
679  // erasing a bitmap is often just a byte-wise memory fill
680  bool bByteFill = true;
681  sal_uInt8 nFillByte;
682 
683  switch( nDstFormat )
684  {
687  nFillByte = rColor.GetIndex();
688  nFillByte = static_cast<sal_uInt8>( -(nFillByte & 1) ); // 0x00 or 0xFF
689  break;
692  nFillByte = rColor.GetIndex();
693  nFillByte &= 0x0F;
694  nFillByte |= (nFillByte << 4);
695  break;
698  nFillByte = rColor.GetIndex();
699  break;
700 
703  nFillByte = rColor.GetRed();
704  if( (nFillByte != rColor.GetGreen())
705  || (nFillByte != rColor.GetBlue()) )
706  bByteFill = false;
707  break;
708 
709  default:
710  bByteFill = false;
711  nFillByte = 0x00;
712  break;
713  }
714 
715  if( bByteFill )
716  {
717  long nByteCount = rDst.mnHeight * rDst.mnScanlineSize;
718  memset( rDst.mpBits, nFillByte, nByteCount );
719  return true;
720  }
721 
722  // TODO: handle other bitmap formats
723  switch( nDstFormat )
724  {
726 
729 
734  break;
735 
736  default:
737  break;
738  }
739 
740  return false;
741 }
742 
743 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long mnSrcWidth
Definition: salgtype.hxx:52
sal_uInt8 GetIndex() const
Definition: BitmapColor.hxx:61
sal_uInt8 GetRed() const
long mnSrcHeight
Definition: salgtype.hxx:53
static void ImplConvertPixel(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc)
Definition: bmpfast.cxx:195
static void ImplBlendPixels(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, unsigned nAlphaVal)
Definition: bmpfast.cxx:218
long mnDestWidth
Definition: salgtype.hxx:56
long mnSrcX
Definition: salgtype.hxx:50
long Width() const
SotClipboardFormatId & operator++(SotClipboardFormatId &eFormat)
long mnDestY
Definition: salgtype.hxx:55
ScanlineFormat
Definition: Scanline.hxx:28
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
static bool ImplCopyImage(BitmapBuffer &rDstBuffer, const BitmapBuffer &rSrcBuffer)
Definition: bmpfast.cxx:261
static void ImplBlendLines(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, const TrueColorPixelPtr< MASKFMT > &rMsk, int nPixelCount)
Definition: bmpfast.cxx:245
SAL_DLLPRIVATE BitmapBuffer * ImplGetBitmapBuffer() const
sal_uInt8 GetBlue() const
ScanlineFormat mnFormat
float y
bool HasPalette() const
uno_Any a
static bool ImplBlendToBitmap(TrueColorPixelPtr< SRCFMT > &rSrcLine, BitmapBuffer &rDstBuffer, const BitmapBuffer &rSrcBuffer, const BitmapBuffer &rMskBuffer)
Definition: bmpfast.cxx:461
bool ImplFastBitmapBlending(BitmapWriteAccess const &rDstWA, const BitmapReadAccess &rSrcRA, const BitmapReadAccess &rMskRA, const SalTwoRect &rTR)
Definition: bmpfast.cxx:579
sal_uInt8 * mpBits
long mnSrcY
Definition: salgtype.hxx:51
sal_uInt8 GetGreen() const
unsigned char PIXBYTE
Definition: bmpfast.cxx:27
long Height() const
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
long mnDestX
Definition: salgtype.hxx:54
static bool ImplConvertToBitmap(TrueColorPixelPtr< SRCFMT > &rSrcLine, BitmapBuffer &rDstBuffer, const BitmapBuffer &rSrcBuffer)
Definition: bmpfast.cxx:296
void * p
static bool ImplConvertFromBitmap(BitmapBuffer &rDst, const BitmapBuffer &rSrc)
Definition: bmpfast.cxx:327
ScanlineFormat RemoveScanline(ScanlineFormat nFormat)
Definition: Scanline.hxx:57
BitmapPalette maPalette
long mnDestHeight
Definition: salgtype.hxx:57
static void ImplConvertLine(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, int nPixelCount)
Definition: bmpfast.cxx:203
static bool ImplBlendFromBitmap(BitmapBuffer &rDst, const BitmapBuffer &rSrc, const BitmapBuffer &rMsk)
Definition: bmpfast.cxx:536
bool ImplFastEraseBitmap(BitmapBuffer &rDst, const BitmapColor &rColor)
Definition: bmpfast.cxx:675
bool ImplFastBitmapConversion(BitmapBuffer &rDst, const BitmapBuffer &rSrc, const SalTwoRect &rTR)
Definition: bmpfast.cxx:373