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  PIXBYTE* GetRawPtr() const { return mpPixel; }
35  void AddByteOffset( int nByteOffset ) { mpPixel += nByteOffset; }
36 
37 protected:
39 };
40 
41 template <ScanlineFormat PIXFMT>
43 {
44 public:
45  PIXBYTE GetRed() const;
46  PIXBYTE GetGreen() const;
47  PIXBYTE GetBlue() const;
48  PIXBYTE GetAlpha() const;
49 
50  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const;
51  void SetAlpha( PIXBYTE a ) const;
52 };
53 
54 // template specializations for truecolor pixel formats
55 template <>
57 {
58 public:
59  void operator++() { mpPixel += 3; }
60 
61  PIXBYTE GetRed() const { return mpPixel[0]; }
62  PIXBYTE GetGreen() const { return mpPixel[1]; }
63  PIXBYTE GetBlue() const { return mpPixel[2]; }
64  static PIXBYTE GetAlpha() { return 0; }
65  static void SetAlpha( PIXBYTE ) {}
66 
67  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
68  {
69  mpPixel[0] = r;
70  mpPixel[1] = g;
71  mpPixel[2] = b;
72  }
73 };
74 
75 template <>
77 {
78 public:
79  void operator++() { mpPixel += 3; }
80 
81  PIXBYTE GetRed() const { return mpPixel[2]; }
82  PIXBYTE GetGreen() const { return mpPixel[1]; }
83  PIXBYTE GetBlue() const { return mpPixel[0]; }
84  static PIXBYTE GetAlpha() { return 0; }
85  static void SetAlpha( PIXBYTE ) {}
86 
87  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
88  {
89  mpPixel[0] = b;
90  mpPixel[1] = g;
91  mpPixel[2] = r;
92  }
93 };
94 
95 template <>
97 {
98 public:
99  void operator++() { mpPixel += 4; }
100 
101  PIXBYTE GetRed() const { return mpPixel[1]; }
102  PIXBYTE GetGreen() const { return mpPixel[2]; }
103  PIXBYTE GetBlue() const { return mpPixel[3]; }
104  PIXBYTE GetAlpha() const { return mpPixel[0]; }
105  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
106 
107  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
108  {
109  mpPixel[1] = r;
110  mpPixel[2] = g;
111  mpPixel[3] = b;
112  }
113 };
114 
115 template <>
117 {
118 public:
119  void operator++() { mpPixel += 4; }
120 
121  PIXBYTE GetRed() const { return mpPixel[3]; }
122  PIXBYTE GetGreen() const { return mpPixel[2]; }
123  PIXBYTE GetBlue() const { return mpPixel[1]; }
124  PIXBYTE GetAlpha() const { return mpPixel[0]; }
125  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
126 
127  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
128  {
129  mpPixel[1] = b;
130  mpPixel[2] = g;
131  mpPixel[3] = r;
132  }
133 };
134 
135 template <>
137 {
138 public:
139  void operator++() { mpPixel += 4; }
140 
141  PIXBYTE GetRed() const { return mpPixel[0]; }
142  PIXBYTE GetGreen() const { return mpPixel[1]; }
143  PIXBYTE GetBlue() const { return mpPixel[2]; }
144  PIXBYTE GetAlpha() const { return mpPixel[3]; }
145  void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
146 
147  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
148  {
149  mpPixel[0] = r;
150  mpPixel[1] = g;
151  mpPixel[2] = b;
152  }
153 };
154 
155 template <>
157 {
158 public:
159  void operator++() { mpPixel += 4; }
160 
161  PIXBYTE GetRed() const { return mpPixel[2]; }
162  PIXBYTE GetGreen() const { return mpPixel[1]; }
163  PIXBYTE GetBlue() const { return mpPixel[0]; }
164  PIXBYTE GetAlpha() const { return mpPixel[3]; }
165  void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
166 
167  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
168  {
169  mpPixel[0] = b;
170  mpPixel[1] = g;
171  mpPixel[2] = r;
172  }
173 };
174 
175 template <>
177 {
178 public:
179  void operator++() { mpPixel += 2; }
180 
181  // TODO: non565-RGB
182  PIXBYTE GetRed() const { return (mpPixel[0] & 0xF8U); }
183  PIXBYTE GetGreen() const { return (mpPixel[0]<<5U) | ((mpPixel[1]>>3U)&28U); }
184  PIXBYTE GetBlue() const { return (mpPixel[1]<<3U); }
185  static PIXBYTE GetAlpha() { return 0; }
186  static void SetAlpha( PIXBYTE ) {}
187 
188  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
189  {
190  mpPixel[0] = ((g >> 5U) & 7U) | (r & 0xF8U);
191  mpPixel[1] = ((g & 28U)<< 3U) | (b >> 3U);
192  }
193 };
194 
195 template <>
197 {
198 public:
199  void operator++() { mpPixel += 2; }
200 
201  // TODO: non565-RGB
202  PIXBYTE GetRed() const { return (mpPixel[1] & 0xF8U); }
203  PIXBYTE GetGreen() const { return (mpPixel[1]<<5U) | ((mpPixel[0]>>3U)&28U); }
204  PIXBYTE GetBlue() const { return (mpPixel[0]<<3U); }
205  static PIXBYTE GetAlpha() { return 0; }
206  static void SetAlpha( PIXBYTE ) {}
207 
208  void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
209  {
210  mpPixel[0] = ((g & 28U)<< 3U) | (b >> 3U);
211  mpPixel[1] = ((g >> 5U) & 7U) | (r & 0xF8U);
212  }
213 };
214 
215 template <>
217 {
218 public:
219  void operator++() { mpPixel += 1; }
220  PIXBYTE GetAlpha() const { return mpPixel[0]; }
221  void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
222 };
223 
224 // TODO: for some reason many Alpha maps are ScanlineFormat::N8BitPal
225 // they should be ScanlineFormat::N8BitTcMask
226 template <>
228 : public TrueColorPixelPtr<ScanlineFormat::N8BitTcMask>
229 {};
230 
231 // converting truecolor formats
232 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
234  const TrueColorPixelPtr<SRCFMT>& rSrc )
235 {
236  rDst.SetColor( rSrc.GetRed(), rSrc.GetGreen(), rSrc.GetBlue() );
237  rDst.SetAlpha( rSrc.GetAlpha() );
238 }
239 
240 template <>
241 void ImplConvertPixel<ScanlineFormat::N16BitTcLsbMask, ScanlineFormat::N16BitTcMsbMask> (
244 {
245  // byte swapping
246  const PIXBYTE* pSrc = rSrc.GetRawPtr();
247  PIXBYTE* pDst = rDst.GetRawPtr();
248  pDst[1] = pSrc[0];
249  pDst[0] = pSrc[1];
250 }
251 
252 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
254  const TrueColorPixelPtr<SRCFMT>& rSrc, int nPixelCount )
255 {
256  TrueColorPixelPtr<DSTFMT> aDst( rDst );
257  TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
258  while( --nPixelCount >= 0 )
259  {
260  ImplConvertPixel( aDst, aSrc );
261  ++aSrc;
262  ++aDst;
263  }
264 }
265 
266 // alpha blending truecolor pixels
267 template <ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
269  const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal )
270 {
271  static const unsigned nAlphaShift = 8;
272  if( !nAlphaVal )
273  ImplConvertPixel( rDst, rSrc );
274  else if( nAlphaVal != ~(~0U << nAlphaShift) )
275  {
276  int nR = rDst.GetRed();
277  int nS = rSrc.GetRed();
278  nR = nS + (((nR - nS) * nAlphaVal) >> nAlphaShift);
279 
280  int nG = rDst.GetGreen();
281  nS = rSrc.GetGreen();
282  nG = nS + (((nG - nS) * nAlphaVal) >> nAlphaShift);
283 
284  int nB = rDst.GetBlue();
285  nS = rSrc.GetBlue();
286  nB = nS + (((nB - nS) * nAlphaVal) >> nAlphaShift);
287 
288  rDst.SetColor( sal::static_int_cast<PIXBYTE>(nR),
289  sal::static_int_cast<PIXBYTE>(nG),
290  sal::static_int_cast<PIXBYTE>(nB) );
291  }
292 }
293 
294 template <ScanlineFormat MASKFMT, ScanlineFormat SRCFMT, ScanlineFormat DSTFMT>
295 static void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst,
296  const TrueColorPixelPtr<SRCFMT>& rSrc, const TrueColorPixelPtr<MASKFMT>& rMsk,
297  int nPixelCount )
298 {
299  TrueColorPixelPtr<MASKFMT> aMsk( rMsk );
300  TrueColorPixelPtr<DSTFMT> aDst( rDst );
301  TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
302  while( --nPixelCount >= 0 )
303  {
304  ImplBlendPixels(aDst, aSrc, aMsk.GetAlpha());
305  ++aDst;
306  ++aSrc;
307  ++aMsk;
308  }
309 }
310 
311 static bool ImplCopyImage( BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
312 {
313  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
314  int nDstLinestep = rDstBuffer.mnScanlineSize;
315 
316  const PIXBYTE* pRawSrc = rSrcBuffer.mpBits;
317  PIXBYTE* pRawDst = rDstBuffer.mpBits;
318 
319  // source and destination don't match upside down
320  if( ScanlineFormat::TopDown & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
321  {
322  pRawDst += (rSrcBuffer.mnHeight - 1) * nDstLinestep;
323  nDstLinestep = -rDstBuffer.mnScanlineSize;
324  }
325  else if( nSrcLinestep == nDstLinestep )
326  {
327  memcpy( pRawDst, pRawSrc, rSrcBuffer.mnHeight * nDstLinestep );
328  return true;
329  }
330 
331  int nByteWidth = nSrcLinestep;
332  if( nByteWidth > rDstBuffer.mnScanlineSize )
333  nByteWidth = rDstBuffer.mnScanlineSize;
334 
335  for( int y = rSrcBuffer.mnHeight; --y >= 0; )
336  {
337  memcpy( pRawDst, pRawSrc, nByteWidth );
338  pRawSrc += nSrcLinestep;
339  pRawDst += nDstLinestep;
340  }
341 
342  return true;
343 }
344 
345 template <ScanlineFormat DSTFMT,ScanlineFormat SRCFMT>
347  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
348 {
349  // help the compiler to avoid instantiations of unneeded conversions
350  SAL_WARN_IF( SRCFMT == DSTFMT, "vcl.gdi", "ImplConvertToBitmap into same format");
351  if( SRCFMT == DSTFMT )
352  return false;
353 
354  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
355  int nDstLinestep = rDstBuffer.mnScanlineSize;
356 
357  TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
358 
359  // source and destination don't match upside down
360  if( ScanlineFormat::TopDown & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
361  {
362  aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep );
363  nDstLinestep = -nDstLinestep;
364  }
365 
366  for( int y = rSrcBuffer.mnHeight; --y >= 0; )
367  {
368  ImplConvertLine( aDstLine, rSrcLine, rSrcBuffer.mnWidth );
369  rSrcLine.AddByteOffset( nSrcLinestep );
370  aDstLine.AddByteOffset( nDstLinestep );
371  }
372 
373  return true;
374 }
375 
376 template <ScanlineFormat SRCFMT>
377 static bool ImplConvertFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc )
378 {
379  TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
380 
381  // select the matching instantiation for the destination's bitmap format
382  switch (RemoveScanline(rDst.mnFormat))
383  {
389  break;
390 
392 // return ImplConvertToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc );
394 // return ImplConvertToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc );
395  break;
396 
398  return ImplConvertToBitmap<ScanlineFormat::N16BitTcMsbMask>( aSrcType, rDst, rSrc );
400  return ImplConvertToBitmap<ScanlineFormat::N16BitTcLsbMask>( aSrcType, rDst, rSrc );
401 
403  return ImplConvertToBitmap<ScanlineFormat::N24BitTcBgr>( aSrcType, rDst, rSrc );
405  return ImplConvertToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDst, rSrc );
406 
408  return ImplConvertToBitmap<ScanlineFormat::N32BitTcAbgr>( aSrcType, rDst, rSrc );
410  return ImplConvertToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDst, rSrc );
412  return ImplConvertToBitmap<ScanlineFormat::N32BitTcBgra>( aSrcType, rDst, rSrc );
414  return ImplConvertToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDst, rSrc );
415  default: break;
416  }
417 
418  static int nNotAccelerated = 0;
419  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
420  "vcl.gdi",
421  "ImplConvertFromBitmap for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
422 
423  return false;
424 }
425 
426 // A universal stretching conversion is overkill in most common situations
427 // => performance benefits for speeding up the non-stretching cases
429  const SalTwoRect& rTR )
430 {
431  // TODO:horizontal mirroring not implemented yet
432  if( rTR.mnDestWidth < 0 )
433  return false;
434  // vertical mirroring
435  if( rTR.mnDestHeight < 0 )
436  // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
437  return false;
438 
439  // offsetted conversion is not implemented yet
440  if( rTR.mnSrcX || rTR.mnSrcY )
441  return false;
442  if( rTR.mnDestX || rTR.mnDestY )
443  return false;
444 
445  // stretched conversion is not implemented yet
446  if( rTR.mnDestWidth != rTR.mnSrcWidth )
447  return false;
448  if( rTR.mnDestHeight!= rTR.mnSrcHeight )
449  return false;
450 
451  // check source image size
452  if( rSrc.mnWidth < rTR.mnSrcX + rTR.mnSrcWidth )
453  return false;
454  if( rSrc.mnHeight < rTR.mnSrcY + rTR.mnSrcHeight )
455  return false;
456 
457  // check dest image size
458  if( rDst.mnWidth < rTR.mnDestX + rTR.mnDestWidth )
459  return false;
460  if( rDst.mnHeight < rTR.mnDestY + rTR.mnDestHeight )
461  return false;
462 
463  const ScanlineFormat nSrcFormat = RemoveScanline(rSrc.mnFormat);
464  const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
465 
466  // TODO: also implement conversions for 16bit colormasks with non-565 format
468  if( rSrc.maColorMask.GetRedMask() != 0xF800
469  || rSrc.maColorMask.GetGreenMask()!= 0x07E0
470  || rSrc.maColorMask.GetBlueMask() != 0x001F )
471  return false;
473  if( rDst.maColorMask.GetRedMask() != 0xF800
474  || rDst.maColorMask.GetGreenMask()!= 0x07E0
475  || rDst.maColorMask.GetBlueMask() != 0x001F )
476  return false;
477 
478  // special handling of trivial cases
479  if( nSrcFormat == nDstFormat )
480  {
481  // accelerated palette conversions not yet implemented
482  if( rSrc.maPalette != rDst.maPalette )
483  return false;
484  return ImplCopyImage( rDst, rSrc );
485  }
486 
487  // select the matching instantiation for the source's bitmap format
488  switch( nSrcFormat )
489  {
495  break;
496 
498 // return ImplConvertFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
500 // return ImplConvertFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
501  break;
502 
504  return ImplConvertFromBitmap<ScanlineFormat::N16BitTcMsbMask>( rDst, rSrc );
506  return ImplConvertFromBitmap<ScanlineFormat::N16BitTcLsbMask>( rDst, rSrc );
507 
509  return ImplConvertFromBitmap<ScanlineFormat::N24BitTcBgr>( rDst, rSrc );
511  return ImplConvertFromBitmap<ScanlineFormat::N24BitTcRgb>( rDst, rSrc );
512 
514  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcAbgr>( rDst, rSrc );
516  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcArgb>( rDst, rSrc );
518  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcBgra>( rDst, rSrc );
520  return ImplConvertFromBitmap<ScanlineFormat::N32BitTcRgba>( rDst, rSrc );
521  default: break;
522  }
523 
524  static int nNotAccelerated = 0;
525  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
526  "vcl.gdi",
527  "ImplFastBitmapConversion for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
528 
529  return false;
530 }
531 
532 template <ScanlineFormat DSTFMT, ScanlineFormat SRCFMT> //,sal_uLong MSKFMT>
534  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
535  const BitmapBuffer& rMskBuffer )
536 {
537  SAL_WARN_IF( rMskBuffer.mnFormat != ScanlineFormat::N8BitPal, "vcl.gdi", "FastBmp BlendImage: unusual MSKFMT" );
538 
539  const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
540  int nMskLinestep = rMskBuffer.mnScanlineSize;
541  int nDstLinestep = rDstBuffer.mnScanlineSize;
542 
543  TrueColorPixelPtr<ScanlineFormat::N8BitPal> aMskLine; aMskLine.SetRawPtr( rMskBuffer.mpBits );
544  TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
545 
546  // special case for single line masks
547  if( rMskBuffer.mnHeight == 1 )
548  nMskLinestep = 0;
549 
550  // source and mask don't match: upside down
551  if( (rSrcBuffer.mnFormat ^ rMskBuffer.mnFormat) & ScanlineFormat::TopDown )
552  {
553  aMskLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nMskLinestep );
554  nMskLinestep = -nMskLinestep;
555  }
556 
557  // source and destination don't match: upside down
558  if( (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) & ScanlineFormat::TopDown )
559  {
560  aDstLine.AddByteOffset( (rDstBuffer.mnHeight - 1) * nDstLinestep );
561  nDstLinestep = -nDstLinestep;
562  }
563 
564  assert(rDstBuffer.mnHeight <= rSrcBuffer.mnHeight && "not sure about that?");
565  for (int y = rDstBuffer.mnHeight; --y >= 0;)
566  {
567  ImplBlendLines(aDstLine, rSrcLine, aMskLine, rDstBuffer.mnWidth);
568  aDstLine.AddByteOffset( nDstLinestep );
569  rSrcLine.AddByteOffset( nSrcLinestep );
570  aMskLine.AddByteOffset( nMskLinestep );
571  }
572 
573  return true;
574 }
575 
576 // some specializations to reduce the code size
577 template <>
578 bool ImplBlendToBitmap<ScanlineFormat::N24BitTcBgr,ScanlineFormat::N24BitTcBgr>(
580  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
581  const BitmapBuffer& rMskBuffer )
582  {
583  TrueColorPixelPtr<ScanlineFormat::N24BitTcRgb> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
584  return ImplBlendToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
585  }
586 
587 template <>
588 bool ImplBlendToBitmap<ScanlineFormat::N32BitTcAbgr,ScanlineFormat::N32BitTcAbgr>(
590  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
591  const BitmapBuffer& rMskBuffer )
592  {
593  TrueColorPixelPtr<ScanlineFormat::N32BitTcArgb> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
594  return ImplBlendToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
595  }
596 
597 template <>
598 bool ImplBlendToBitmap<ScanlineFormat::N32BitTcBgra,ScanlineFormat::N32BitTcBgra>(
600  BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
601  const BitmapBuffer& rMskBuffer )
602  {
603  TrueColorPixelPtr<ScanlineFormat::N32BitTcRgba> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
604  return ImplBlendToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
605  }
606 
607 template <ScanlineFormat SRCFMT>
608 static bool ImplBlendFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc, const BitmapBuffer& rMsk )
609 {
610  TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
611 
612  // select the matching instantiation for the destination's bitmap format
613  switch (RemoveScanline(rDst.mnFormat))
614  {
620  break;
621 
623 // return ImplBlendToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc, rMsk );
625 // return ImplBlendToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc, rMsk );
626  break;
627 
629  return ImplBlendToBitmap<ScanlineFormat::N16BitTcMsbMask>( aSrcType, rDst, rSrc, rMsk );
631  return ImplBlendToBitmap<ScanlineFormat::N16BitTcLsbMask>( aSrcType, rDst, rSrc, rMsk );
632 
634  return ImplBlendToBitmap<ScanlineFormat::N24BitTcBgr>( aSrcType, rDst, rSrc, rMsk );
636  return ImplBlendToBitmap<ScanlineFormat::N24BitTcRgb>( aSrcType, rDst, rSrc, rMsk );
637 
639  return ImplBlendToBitmap<ScanlineFormat::N32BitTcAbgr>( aSrcType, rDst, rSrc, rMsk );
641  return ImplBlendToBitmap<ScanlineFormat::N32BitTcArgb>( aSrcType, rDst, rSrc, rMsk );
643  return ImplBlendToBitmap<ScanlineFormat::N32BitTcBgra>( aSrcType, rDst, rSrc, rMsk );
645  return ImplBlendToBitmap<ScanlineFormat::N32BitTcRgba>( aSrcType, rDst, rSrc, rMsk );
646  default: break;
647  }
648 
649  static int nNotAccelerated = 0;
650  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
651  "vcl.gdi",
652  "ImplBlendFromBitmap for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "*" << static_cast<int>(rMsk.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) );
653  return false;
654 }
655 
657  const BitmapReadAccess& rSrcRA, const BitmapReadAccess& rMskRA,
658  const SalTwoRect& rTR )
659 {
660  // accelerated blending of paletted bitmaps not implemented yet
661  if( rSrcRA.HasPalette() )
662  return false;
663  if( rDstWA.HasPalette() )
664  return false;
665  // TODO: either get rid of mask's use of 8BIT_PAL or check the palette
666 
667  // horizontal mirroring not implemented yet
668  if( rTR.mnDestWidth < 0 )
669  return false;
670  // vertical mirroring
671  if( rTR.mnDestHeight < 0 )
672  // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
673  return false;
674 
675  // offsetted blending is not implemented yet
676  if( rTR.mnSrcX || rTR.mnSrcY )
677  return false;
678  if( rTR.mnDestX || rTR.mnDestY )
679  return false;
680 
681  // stretched blending is not implemented yet
682  if( rTR.mnDestWidth != rTR.mnSrcWidth )
683  return false;
684  if( rTR.mnDestHeight!= rTR.mnSrcHeight )
685  return false;
686 
687  // check source image size
688  if( rSrcRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
689  return false;
690  if( rSrcRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
691  return false;
692 
693  // check mask image size
694  if( rMskRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
695  return false;
696  if( rMskRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
697  if( rMskRA.Height() != 1 )
698  return false;
699 
700  // check dest image size
701  if( rDstWA.Width() < rTR.mnDestX + rTR.mnDestWidth )
702  return false;
703  if( rDstWA.Height() < rTR.mnDestY + rTR.mnDestHeight )
704  return false;
705 
706  BitmapBuffer& rDst = *rDstWA.ImplGetBitmapBuffer();
707  const BitmapBuffer& rSrc = *rSrcRA.ImplGetBitmapBuffer();
708  const BitmapBuffer& rMsk = *rMskRA.ImplGetBitmapBuffer();
709 
710  const ScanlineFormat nSrcFormat = RemoveScanline(rSrc.mnFormat);
711  const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
712 
713  // accelerated conversions for 16bit colormasks with non-565 format are not yet implemented
715  if( rSrc.maColorMask.GetRedMask() != 0xF800
716  || rSrc.maColorMask.GetGreenMask()!= 0x07E0
717  || rSrc.maColorMask.GetBlueMask() != 0x001F)
718  return false;
720  if( rDst.maColorMask.GetRedMask() != 0xF800
721  || rDst.maColorMask.GetGreenMask()!= 0x07E0
722  || rDst.maColorMask.GetBlueMask() != 0x001F)
723  return false;
724 
725  // select the matching instantiation for the source's bitmap format
726  switch( nSrcFormat )
727  {
733  break;
734 
736 // return ImplBlendFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
738 // return ImplBlendFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
739  break;
740 
742  return ImplBlendFromBitmap<ScanlineFormat::N16BitTcMsbMask>( rDst, rSrc, rMsk );
744  return ImplBlendFromBitmap<ScanlineFormat::N16BitTcLsbMask>( rDst, rSrc, rMsk );
745 
747  return ImplBlendFromBitmap<ScanlineFormat::N24BitTcBgr>( rDst, rSrc, rMsk );
749  return ImplBlendFromBitmap<ScanlineFormat::N24BitTcRgb>( rDst, rSrc, rMsk );
750 
752  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcAbgr>( rDst, rSrc, rMsk );
754  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcArgb>( rDst, rSrc, rMsk );
756  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcBgra>( rDst, rSrc, rMsk );
758  return ImplBlendFromBitmap<ScanlineFormat::N32BitTcRgba>( rDst, rSrc, rMsk );
759  default: break;
760  }
761 
762  static int nNotAccelerated = 0;
763  SAL_WARN_IF( rSrc.mnWidth * rSrc.mnHeight >= 4000 && ++nNotAccelerated == 100,
764  "vcl.gdi",
765  "ImplFastBlend for not accelerated case (" << std::hex << static_cast<int>(rSrc.mnFormat) << "*" << static_cast<int>(rMsk.mnFormat) << "->" << static_cast<int>(rDst.mnFormat) << ")" );
766 
767  return false;
768 }
769 
770 bool ImplFastEraseBitmap( BitmapBuffer& rDst, const BitmapColor& rColor )
771 {
772  const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
773 
774  // erasing a bitmap is often just a byte-wise memory fill
775  bool bByteFill = true;
776  sal_uInt8 nFillByte;
777 
778  switch( nDstFormat )
779  {
782  nFillByte = rColor.GetIndex();
783  nFillByte = static_cast<sal_uInt8>( -(nFillByte & 1) ); // 0x00 or 0xFF
784  break;
787  nFillByte = rColor.GetIndex();
788  nFillByte &= 0x0F;
789  nFillByte |= (nFillByte << 4);
790  break;
793  nFillByte = rColor.GetIndex();
794  break;
795 
798  nFillByte = rColor.GetRed();
799  if( (nFillByte != rColor.GetGreen())
800  || (nFillByte != rColor.GetBlue()) )
801  bByteFill = false;
802  break;
803 
804  default:
805  bByteFill = false;
806  nFillByte = 0x00;
807  break;
808  }
809 
810  if( bByteFill )
811  {
812  long nByteCount = rDst.mnHeight * rDst.mnScanlineSize;
813  memset( rDst.mpBits, nFillByte, nByteCount );
814  return true;
815  }
816 
817  // TODO: handle other bitmap formats
818  switch( nDstFormat )
819  {
823 
826 
831  break;
832 
833  default:
834  break;
835  }
836 
837  return false;
838 }
839 
840 /* 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
ColorMask maColorMask
long mnSrcHeight
Definition: salgtype.hxx:53
PIXBYTE GetRed() const
static void ImplConvertPixel(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc)
Definition: bmpfast.cxx:233
PIXBYTE GetBlue() const
sal_uInt32 GetRedMask() const
Definition: ColorMask.hxx:123
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:67
void AddByteOffset(int nByteOffset)
Definition: bmpfast.cxx:35
static void ImplBlendPixels(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, unsigned nAlphaVal)
Definition: bmpfast.cxx:268
long mnDestWidth
Definition: salgtype.hxx:56
long mnSrcX
Definition: salgtype.hxx:50
long Width() const
PIXBYTE * GetRawPtr() const
Definition: bmpfast.cxx:34
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:311
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:87
static void ImplBlendLines(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, const TrueColorPixelPtr< MASKFMT > &rMsk, int nPixelCount)
Definition: bmpfast.cxx:295
SAL_DLLPRIVATE BitmapBuffer * ImplGetBitmapBuffer() const
sal_uInt8 GetBlue() const
ScanlineFormat mnFormat
float y
bool HasPalette() const
PIXBYTE GetGreen() const
PIXBYTE * mpPixel
Definition: bmpfast.cxx:38
static bool ImplBlendToBitmap(TrueColorPixelPtr< SRCFMT > &rSrcLine, BitmapBuffer &rDstBuffer, const BitmapBuffer &rSrcBuffer, const BitmapBuffer &rMskBuffer)
Definition: bmpfast.cxx:533
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:167
bool ImplFastBitmapBlending(BitmapWriteAccess const &rDstWA, const BitmapReadAccess &rSrcRA, const BitmapReadAccess &rMskRA, const SalTwoRect &rTR)
Definition: bmpfast.cxx:656
sal_uInt8 * mpBits
long mnSrcY
Definition: salgtype.hxx:51
sal_uInt8 GetGreen() const
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:208
unsigned char PIXBYTE
Definition: bmpfast.cxx:27
long Height() const
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:188
long mnDestX
Definition: salgtype.hxx:54
static bool ImplConvertToBitmap(TrueColorPixelPtr< SRCFMT > &rSrcLine, BitmapBuffer &rDstBuffer, const BitmapBuffer &rSrcBuffer)
Definition: bmpfast.cxx:346
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:127
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:147
sal_uInt32 GetBlueMask() const
Definition: ColorMask.hxx:133
static bool ImplConvertFromBitmap(BitmapBuffer &rDst, const BitmapBuffer &rSrc)
Definition: bmpfast.cxx:377
ScanlineFormat RemoveScanline(ScanlineFormat nFormat)
Definition: Scanline.hxx:60
BitmapPalette maPalette
long mnDestHeight
Definition: salgtype.hxx:57
static void ImplConvertLine(const TrueColorPixelPtr< DSTFMT > &rDst, const TrueColorPixelPtr< SRCFMT > &rSrc, int nPixelCount)
Definition: bmpfast.cxx:253
sal_uInt32 GetGreenMask() const
Definition: ColorMask.hxx:128
static bool ImplBlendFromBitmap(BitmapBuffer &rDst, const BitmapBuffer &rSrc, const BitmapBuffer &rMsk)
Definition: bmpfast.cxx:608
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
void SetColor(PIXBYTE r, PIXBYTE g, PIXBYTE b) const
Definition: bmpfast.cxx:107
bool ImplFastEraseBitmap(BitmapBuffer &rDst, const BitmapColor &rColor)
Definition: bmpfast.cxx:770
bool ImplFastBitmapConversion(BitmapBuffer &rDst, const BitmapBuffer &rSrc, const SalTwoRect &rTR)
Definition: bmpfast.cxx:428