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 
30 {
31 public:
32  explicit BasePixelPtr( PIXBYTE* p = nullptr ) : mpPixel( p ) {}
33  void SetRawPtr( PIXBYTE* pRawPtr ) { mpPixel = pRawPtr; }
34  void AddByteOffset( int nByteOffset ) { mpPixel += nByteOffset; }
35 
36 protected:
38 };
39 
40 template <ScanlineFormat PIXFMT>
42 {
43 public:
44  PIXBYTE GetRed() const;
45  PIXBYTE GetGreen() const;
46  PIXBYTE GetBlue() const;
47  PIXBYTE GetAlpha() const;
48 
49  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const;
50  void SetAlpha( PIXBYTE a ) const;
51 };
52 
53 // template specializations for truecolor pixel formats
54 template <>
56 {
57 public:
58  void operator++() { mpPixel += 3; }
59 
60  PIXBYTE GetRed() const { return mpPixel[0]; }
61  PIXBYTE GetGreen() const { return mpPixel[1]; }
62  PIXBYTE GetBlue() const { return mpPixel[2]; }
63  static PIXBYTE GetAlpha() { return 0; }
64  static void SetAlpha( PIXBYTE ) {}
65 
66  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
67  {
68  mpPixel[0] = r;
69  mpPixel[1] = g;
70  mpPixel[2] = b;
71  }
72 };
73 
74 template <>
76 {
77 public:
78  void operator++() { mpPixel += 3; }
79 
80  PIXBYTE GetRed() const { return mpPixel[2]; }
81  PIXBYTE GetGreen() const { return mpPixel[1]; }
82  PIXBYTE GetBlue() const { return mpPixel[0]; }
83  static PIXBYTE GetAlpha() { return 0; }
84  static void SetAlpha( PIXBYTE ) {}
85 
86  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
87  {
88  mpPixel[0] = b;
89  mpPixel[1] = g;
90  mpPixel[2] = r;
91  }
92 };
93 
94 template <>
96 {
97 public:
98  void operator++() { mpPixel += 4; }
99 
100  PIXBYTE GetRed() const { return mpPixel[1]; }
101  PIXBYTE GetGreen() const { return mpPixel[2]; }
102  PIXBYTE GetBlue() const { return mpPixel[3]; }
103  PIXBYTE GetAlpha() const { return mpPixel[0]; }
104  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
105 
106  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
107  {
108  mpPixel[1] = r;
109  mpPixel[2] = g;
110  mpPixel[3] = b;
111  }
112 };
113 
114 template <>
116 {
117 public:
118  void operator++() { mpPixel += 4; }
119 
120  PIXBYTE GetRed() const { return mpPixel[3]; }
121  PIXBYTE GetGreen() const { return mpPixel[2]; }
122  PIXBYTE GetBlue() const { return mpPixel[1]; }
123  PIXBYTE GetAlpha() const { return mpPixel[0]; }
124  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
125 
126  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
127  {
128  mpPixel[1] = b;
129  mpPixel[2] = g;
130  mpPixel[3] = r;
131  }
132 };
133 
134 template <>
136 {
137 public:
138  void operator++() { mpPixel += 4; }
139 
140  PIXBYTE GetRed() const { return mpPixel[0]; }
141  PIXBYTE GetGreen() const { return mpPixel[1]; }
142  PIXBYTE GetBlue() const { return mpPixel[2]; }
143  PIXBYTE GetAlpha() const { return mpPixel[3]; }
144  void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
145 
146  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
147  {
148  mpPixel[0] = r;
149  mpPixel[1] = g;
150  mpPixel[2] = b;
151  }
152 };
153 
154 template <>
156 {
157 public:
158  void operator++() { mpPixel += 4; }
159 
160  PIXBYTE GetRed() const { return mpPixel[2]; }
161  PIXBYTE GetGreen() const { return mpPixel[1]; }
162  PIXBYTE GetBlue() const { return mpPixel[0]; }
163  PIXBYTE GetAlpha() const { return mpPixel[3]; }
164  void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
165 
166  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
167  {
168  mpPixel[0] = b;
169  mpPixel[1] = g;
170  mpPixel[2] = r;
171  }
172 };
173 
174 template <>
176 {
177 public:
178  void operator++() { mpPixel += 1; }
179  PIXBYTE GetAlpha() const { return mpPixel[0]; }
180  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
181 };
182 
183 // TODO: for some reason many Alpha maps are ScanlineFormat::N8BitPal
184 // they should be ScanlineFormat::N8BitTcMask
185 template <>
187 : public TrueColorPixelPtr<ScanlineFormat::N8BitTcMask>
188 {};
189 
190 // converting truecolor formats
191 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
193  const TrueColorPixelPtr<SRCFMT>& rSrc )
194 {
195  rDst.SetColor( rSrc.GetRed(), rSrc.GetGreen(), rSrc.GetBlue() );
196  rDst.SetAlpha( rSrc.GetAlpha() );
197 }
198 
199 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
201  const TrueColorPixelPtr<SRCFMT>& rSrc, int nPixelCount )
202 {
203  TrueColorPixelPtr<DSTFMT> aDst( rDst );
204  TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
205  while( --nPixelCount >= 0 )
206  {
207  ImplConvertPixel( aDst, aSrc );
208  ++aSrc;
209  ++aDst;
210  }
211 }
212 
213 // alpha blending truecolor pixels
214 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
216  const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal )
217 {
218  static const unsigned nAlphaShift = 8;
219  if( !nAlphaVal )
220  ImplConvertPixel( rDst, rSrc );
221  else if( nAlphaVal != ~(~0U << nAlphaShift) )
222  {
223  int nR = rDst.GetRed();
224  int nS = rSrc.GetRed();
225  nR = nS + (((nR - nS) * nAlphaVal) >> nAlphaShift);
226 
227  int nG = rDst.GetGreen();
228  nS = rSrc.GetGreen();
229  nG = nS + (((nG - nS) * nAlphaVal) >> nAlphaShift);
230 
231  int nB = rDst.GetBlue();
232  nS = rSrc.GetBlue();
233  nB = nS + (((nB - nS) * nAlphaVal) >> nAlphaShift);
234 
235  rDst.SetColor( sal::static_int_cast<PIXBYTE>(nR),
236  sal::static_int_cast<PIXBYTE>(nG),
237  sal::static_int_cast<PIXBYTE>(nB) );
238  }
239 }
240 
241 template <ScanlineFormat MASKFMT, ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
242 static void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst,
243  const TrueColorPixelPtr<SRCFMT>& rSrc, const TrueColorPixelPtr<MASKFMT>& rMsk,
244  int nPixelCount )
245 {
246  TrueColorPixelPtr<MASKFMT> aMsk( rMsk );
247  TrueColorPixelPtr<DSTFMT> aDst( rDst );
248  TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
249  while( --nPixelCount >= 0 )
250  {
251  ImplBlendPixels(aDst, aSrc, aMsk.GetAlpha());
252  ++aDst;
253  ++aSrc;
254  ++aMsk;
255  }
256 }
257 
258 static bool ImplCopyImage( BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
259 {
260  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
261  int nDstLinestep = rDstBuffer.mnScanlineSize;
262 
263  const PIXBYTE* pRawSrc = rSrcBuffer.mpBits;
264  PIXBYTE* pRawDst = rDstBuffer.mpBits;
265 
266  // source and destination don't match upside down
267  if( ScanlineFormat::TopDown & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
268  {
269  pRawDst += (rSrcBuffer.mnHeight - 1) * nDstLinestep;
270  nDstLinestep = -rDstBuffer.mnScanlineSize;
271  }
272  else if( nSrcLinestep == nDstLinestep )
273  {
274  memcpy( pRawDst, pRawSrc, rSrcBuffer.mnHeight * nDstLinestep );
275  return true;
276  }
277 
278  int nByteWidth = nSrcLinestep;
279  if( nByteWidth > rDstBuffer.mnScanlineSize )
280  nByteWidth = rDstBuffer.mnScanlineSize;
281 
282  for( int y = rSrcBuffer.mnHeight; --y >= 0; )
283  {
284  memcpy( pRawDst, pRawSrc, nByteWidth );
285  pRawSrc += nSrcLinestep;
286  pRawDst += nDstLinestep;
287  }
288 
289  return true;
290 }
291 
292 template <ScanlineFormat DSTFMT,ScanlineFormat SRCFMT>
294  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
295 {
296  // help the compiler to avoid instantiations of unneeded conversions
297  SAL_WARN_IF( SRCFMT == DSTFMT, "vcl.gdi", "ImplConvertToBitmap into same format");
298  if( SRCFMT == DSTFMT )
299  return false;
300 
301  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
302  int nDstLinestep = rDstBuffer.mnScanlineSize;
303 
304  TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
305 
306  // source and destination don't match upside down
307  if( ScanlineFormat::TopDown & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
308  {
309  aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep );
310  nDstLinestep = -nDstLinestep;
311  }
312 
313  for( int y = rSrcBuffer.mnHeight; --y >= 0; )
314  {
315  ImplConvertLine( aDstLine, rSrcLine, rSrcBuffer.mnWidth );
316  rSrcLine.AddByteOffset( nSrcLinestep );
317  aDstLine.AddByteOffset( nDstLinestep );
318  }
319 
320  return true;
321 }
322 
323 template <ScanlineFormat SRCFMT>
324 static bool ImplConvertFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc )
325 {
326  TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
327 
328  // select the matching instantiation for the destination's bitmap format
329  switch (RemoveScanline(rDst.mnFormat))
330  {
336  break;
337 
339 // return ImplConvertToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc );
341 // return ImplConvertToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc );
342  break;
343 
345  return ImplConvertToBitmap<ScanlineFormat::N24BitTcBgr>( aSrcType, rDst, rSrc );
347  return ImplConvertToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDst, rSrc );
348 
350  return ImplConvertToBitmap<ScanlineFormat::N32BitTcAbgr>( aSrcType, rDst, rSrc );
352  return ImplConvertToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDst, rSrc );
354  return ImplConvertToBitmap<ScanlineFormat::N32BitTcBgra>( aSrcType, rDst, rSrc );
356  return ImplConvertToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDst, rSrc );
357  default: break;
358  }
359 
360  static int nNotAccelerated = 0;
361  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
362  "vcl.gdi",
363  "ImplConvertFromBitmap for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
364 
365  return false;
366 }
367 
368 // A universal stretching conversion is overkill in most common situations
369 // => performance benefits for speeding up the non-stretching cases
371  const SalTwoRect& rTR )
372 {
373  // TODO:horizontal mirroring not implemented yet
374  if( rTR.mnDestWidth < 0 )
375  return false;
376  // vertical mirroring
377  if( rTR.mnDestHeight < 0 )
378  // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
379  return false;
380 
381  // offsetted conversion is not implemented yet
382  if( rTR.mnSrcX || rTR.mnSrcY )
383  return false;
384  if( rTR.mnDestX || rTR.mnDestY )
385  return false;
386 
387  // stretched conversion is not implemented yet
388  if( rTR.mnDestWidth != rTR.mnSrcWidth )
389  return false;
390  if( rTR.mnDestHeight!= rTR.mnSrcHeight )
391  return false;
392 
393  // check source image size
394  if( rSrc.mnWidth < rTR.mnSrcX + rTR.mnSrcWidth )
395  return false;
396  if( rSrc.mnHeight < rTR.mnSrcY + rTR.mnSrcHeight )
397  return false;
398 
399  // check dest image size
400  if( rDst.mnWidth < rTR.mnDestX + rTR.mnDestWidth )
401  return false;
402  if( rDst.mnHeight < rTR.mnDestY + rTR.mnDestHeight )
403  return false;
404 
405  const ScanlineFormat nSrcFormat = RemoveScanline(rSrc.mnFormat);
406  const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
407 
408  // special handling of trivial cases
409  if( nSrcFormat == nDstFormat )
410  {
411  // accelerated palette conversions not yet implemented
412  if( rSrc.maPalette != rDst.maPalette )
413  return false;
414  return ImplCopyImage( rDst, rSrc );
415  }
416 
417  // select the matching instantiation for the source's bitmap format
418  switch( nSrcFormat )
419  {
425  break;
426 
428 // return ImplConvertFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
430 // return ImplConvertFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
431  break;
432 
434  return ImplConvertFromBitmap<ScanlineFormat::N24BitTcBgr>( rDst, rSrc );
436  return ImplConvertFromBitmap<ScanlineFormat::N24BitTcRgb>( rDst, rSrc );
437 
439  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcAbgr>( rDst, rSrc );
441  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcArgb>( rDst, rSrc );
443  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcBgra>( rDst, rSrc );
445  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcRgba>( rDst, rSrc );
446  default: break;
447  }
448 
449  static int nNotAccelerated = 0;
450  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
451  "vcl.gdi",
452  "ImplFastBitmapConversion for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
453 
454  return false;
455 }
456 
457 template <ScanlineFormat DSTFMT, ScanlineFormat SRCFMT> //,sal_uLong MSKFMT>
459  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
460  const BitmapBuffer& rMskBuffer )
461 {
462  SAL_WARN_IF( rMskBuffer.mnFormat != ScanlineFormat::N8BitPal, "vcl.gdi", "FastBmp BlendImage: unusual MSKFMT" );
463 
464  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
465  int nMskLinestep = rMskBuffer.mnScanlineSize;
466  int nDstLinestep = rDstBuffer.mnScanlineSize;
467 
468  TrueColorPixelPtr<ScanlineFormat::N8BitPal> aMskLine; aMskLine.SetRawPtr( rMskBuffer.mpBits );
469  TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
470 
471  // special case for single line masks
472  if( rMskBuffer.mnHeight == 1 )
473  nMskLinestep = 0;
474 
475  // source and mask don't match: upside down
476  if( (rSrcBuffer.mnFormat ^ rMskBuffer.mnFormat) & ScanlineFormat::TopDown )
477  {
478  aMskLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nMskLinestep );
479  nMskLinestep = -nMskLinestep;
480  }
481 
482  // source and destination don't match: upside down
483  if( (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) & ScanlineFormat::TopDown )
484  {
485  aDstLine.AddByteOffset( (rDstBuffer.mnHeight - 1) * nDstLinestep );
486  nDstLinestep = -nDstLinestep;
487  }
488 
489  assert(rDstBuffer.mnHeight <= rSrcBuffer.mnHeight && "not sure about that?");
490  for (int y = rDstBuffer.mnHeight; --y >= 0;)
491  {
492  ImplBlendLines(aDstLine, rSrcLine, aMskLine, rDstBuffer.mnWidth);
493  aDstLine.AddByteOffset( nDstLinestep );
494  rSrcLine.AddByteOffset( nSrcLinestep );
495  aMskLine.AddByteOffset( nMskLinestep );
496  }
497 
498  return true;
499 }
500 
501 // some specializations to reduce the code size
502 template <>
503 bool ImplBlendToBitmap<ScanlineFormat::N24BitTcBgr,ScanlineFormat::N24BitTcBgr>(
505  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
506  const BitmapBuffer& rMskBuffer )
507  {
508  TrueColorPixelPtr<ScanlineFormat::N24BitTcRgb> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
509  return ImplBlendToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
510  }
511 
512 template <>
513 bool ImplBlendToBitmap<ScanlineFormat::N32BitTcAbgr,ScanlineFormat::N32BitTcAbgr>(
515  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
516  const BitmapBuffer& rMskBuffer )
517  {
518  TrueColorPixelPtr<ScanlineFormat::N32BitTcArgb> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
519  return ImplBlendToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
520  }
521 
522 template <>
523 bool ImplBlendToBitmap<ScanlineFormat::N32BitTcBgra,ScanlineFormat::N32BitTcBgra>(
525  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
526  const BitmapBuffer& rMskBuffer )
527  {
528  TrueColorPixelPtr<ScanlineFormat::N32BitTcRgba> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
529  return ImplBlendToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
530  }
531 
532 template <ScanlineFormat SRCFMT>
533 static bool ImplBlendFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc, const BitmapBuffer& rMsk )
534 {
535  TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
536 
537  // select the matching instantiation for the destination's bitmap format
538  switch (RemoveScanline(rDst.mnFormat))
539  {
545  break;
546 
548 // return ImplBlendToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc, rMsk );
550 // return ImplBlendToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc, rMsk );
551  break;
552 
554  return ImplBlendToBitmap<ScanlineFormat::N24BitTcBgr>( aSrcType, rDst, rSrc, rMsk );
556  return ImplBlendToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDst, rSrc, rMsk );
557 
559  return ImplBlendToBitmap<ScanlineFormat::N32BitTcAbgr>( aSrcType, rDst, rSrc, rMsk );
561  return ImplBlendToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDst, rSrc, rMsk );
563  return ImplBlendToBitmap<ScanlineFormat::N32BitTcBgra>( aSrcType, rDst, rSrc, rMsk );
565  return ImplBlendToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDst, rSrc, rMsk );
566  default: break;
567  }
568 
569  static int nNotAccelerated = 0;
570  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
571  "vcl.gdi",
572  "ImplBlendFromBitmap for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "*" << static_cast<int>(rMsk.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) );
573  return false;
574 }
575 
577  const BitmapReadAccess& rSrcRA, const BitmapReadAccess& rMskRA,
578  const SalTwoRect& rTR )
579 {
580  // accelerated blending of paletted bitmaps not implemented yet
581  if( rSrcRA.HasPalette() )
582  return false;
583  if( rDstWA.HasPalette() )
584  return false;
585  // TODO: either get rid of mask's use of 8BIT_PAL or check the palette
586 
587  // horizontal mirroring not implemented yet
588  if( rTR.mnDestWidth < 0 )
589  return false;
590  // vertical mirroring
591  if( rTR.mnDestHeight < 0 )
592  // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
593  return false;
594 
595  // offsetted blending is not implemented yet
596  if( rTR.mnSrcX || rTR.mnSrcY )
597  return false;
598  if( rTR.mnDestX || rTR.mnDestY )
599  return false;
600 
601  // stretched blending is not implemented yet
602  if( rTR.mnDestWidth != rTR.mnSrcWidth )
603  return false;
604  if( rTR.mnDestHeight!= rTR.mnSrcHeight )
605  return false;
606 
607  // check source image size
608  if( rSrcRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
609  return false;
610  if( rSrcRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
611  return false;
612 
613  // check mask image size
614  if( rMskRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
615  return false;
616  if( rMskRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
617  if( rMskRA.Height() != 1 )
618  return false;
619 
620  // check dest image size
621  if( rDstWA.Width() < rTR.mnDestX + rTR.mnDestWidth )
622  return false;
623  if( rDstWA.Height() < rTR.mnDestY + rTR.mnDestHeight )
624  return false;
625 
626  BitmapBuffer& rDst = *rDstWA.ImplGetBitmapBuffer();
627  const BitmapBuffer& rSrc = *rSrcRA.ImplGetBitmapBuffer();
628  const BitmapBuffer& rMsk = *rMskRA.ImplGetBitmapBuffer();
629 
630  const ScanlineFormat nSrcFormat = RemoveScanline(rSrc.mnFormat);
631 
632  // select the matching instantiation for the source's bitmap format
633  switch( nSrcFormat )
634  {
640  break;
641 
643 // return ImplBlendFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
645 // return ImplBlendFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
646  break;
647 
649  return ImplBlendFromBitmap<ScanlineFormat::N24BitTcBgr>( rDst, rSrc, rMsk );
651  return ImplBlendFromBitmap<ScanlineFormat::N24BitTcRgb>( rDst, rSrc, rMsk );
652 
654  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcAbgr>( rDst, rSrc, rMsk );
656  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcArgb>( rDst, rSrc, rMsk );
658  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcBgra>( rDst, rSrc, rMsk );
660  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcRgba>( rDst, rSrc, rMsk );
661  default: break;
662  }
663 
664  static int nNotAccelerated = 0;
665  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
666  "vcl.gdi",
667  "ImplFastBlend for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "*" << static_cast<int>(rMsk.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
668 
669  return false;
670 }
671 
672 bool ImplFastEraseBitmap( BitmapBuffer& rDst, const BitmapColor& rColor )
673 {
674  const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
675 
676  // erasing a bitmap is often just a byte-wise memory fill
677  bool bByteFill = true;
678  sal_uInt8 nFillByte;
679 
680  switch( nDstFormat )
681  {
684  nFillByte = rColor.GetIndex();
685  nFillByte = static_cast<sal_uInt8>( -(nFillByte & 1) ); // 0x00 or 0xFF
686  break;
689  nFillByte = rColor.GetIndex();
690  nFillByte &= 0x0F;
691  nFillByte |= (nFillByte << 4);
692  break;
695  nFillByte = rColor.GetIndex();
696  break;
697 
700  nFillByte = rColor.GetRed();
701  if( (nFillByte != rColor.GetGreen())
702  || (nFillByte != rColor.GetBlue()) )
703  bByteFill = false;
704  break;
705 
706  default:
707  bByteFill = false;
708  nFillByte = 0x00;
709  break;
710  }
711 
712  if( bByteFill )
713  {
714  long nByteCount = rDst.mnHeight * rDst.mnScanlineSize;
715  memset( rDst.mpBits, nFillByte, nByteCount );
716  return true;
717  }
718 
719  // TODO: handle other bitmap formats
720  switch( nDstFormat )
721  {
723 
726 
731  break;
732 
733  default:
734  break;
735  }
736 
737  return false;
738 }
739 
740 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long mnSrcWidth
Definition: salgtype.hxx:52
PIXBYTE GetAlpha() const
sal_uInt8 GetIndex() const
Definition: BitmapColor.hxx:61
sal_uInt8 GetRed() const
long mnSrcHeight
Definition: salgtype.hxx:53
PIXBYTE GetRed() const
static void ImplConvertPixel(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc)
Definition: bmpfast.cxx:192
PIXBYTE GetBlue() const
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:66
void AddByteOffset(int nByteOffset)
Definition: bmpfast.cxx:34
static void ImplBlendPixels(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, unsigned nAlphaVal)
Definition: bmpfast.cxx:215
long mnDestWidth
Definition: salgtype.hxx:56
long mnSrcX
Definition: salgtype.hxx:50
long Width() const
void SetAlpha(PIXBYTE a) const
BasePixelPtr(PIXBYTE *p=nullptr)
Definition: bmpfast.cxx:32
void SetRawPtr(PIXBYTE *pRawPtr)
Definition: bmpfast.cxx:33
long mnDestY
Definition: salgtype.hxx:55
ScanlineFormat
Definition: Scanline.hxx:28
static bool ImplCopyImage(BitmapBuffer &rDstBuffer, const BitmapBuffer &rSrcBuffer)
Definition: bmpfast.cxx:258
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:86
static void ImplBlendLines(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, const TrueColorPixelPtr< MASKFMT > &rMsk, int nPixelCount)
Definition: bmpfast.cxx:242
SAL_DLLPRIVATE BitmapBuffer * ImplGetBitmapBuffer() const
sal_uInt8 GetBlue() const
ScanlineFormat mnFormat
float y
bool HasPalette() const
PIXBYTE GetGreen() const
PIXBYTE * mpPixel
Definition: bmpfast.cxx:37
static bool ImplBlendToBitmap(TrueColorPixelPtr< SRCFMT > &rSrcLine, BitmapBuffer &rDstBuffer, const BitmapBuffer &rSrcBuffer, const BitmapBuffer &rMskBuffer)
Definition: bmpfast.cxx:458
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:166
bool ImplFastBitmapBlending(BitmapWriteAccess const &rDstWA, const BitmapReadAccess &rSrcRA, const BitmapReadAccess &rMskRA, const SalTwoRect &rTR)
Definition: bmpfast.cxx:576
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:293
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:126
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:146
static bool ImplConvertFromBitmap(BitmapBuffer &rDst, const BitmapBuffer &rSrc)
Definition: bmpfast.cxx:324
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:200
static bool ImplBlendFromBitmap(BitmapBuffer &rDst, const BitmapBuffer &rSrc, const BitmapBuffer &rMsk)
Definition: bmpfast.cxx:533
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:106
bool ImplFastEraseBitmap(BitmapBuffer &rDst, const BitmapColor &rColor)
Definition: bmpfast.cxx:672
bool ImplFastBitmapConversion(BitmapBuffer &rDst, const BitmapBuffer &rSrc, const SalTwoRect &rTR)
Definition: bmpfast.cxx:370