1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <bmpfast.hxx>
21 #include <vcl/bitmapaccess.hxx>
22 #include <vcl/salgtype.hxx>
23 #include <bitmapwriteaccess.hxx>
25 #include <sal/log.hxx>
27 typedef unsigned char PIXBYTE
;
32 explicit BasePixelPtr( PIXBYTE
* p
= nullptr ) : mpPixel( p
) {}
33 void SetRawPtr( PIXBYTE
* pRawPtr
) { mpPixel
= pRawPtr
; }
34 void AddByteOffset( int nByteOffset
) { mpPixel
+= nByteOffset
; }
40 template <ScanlineFormat PIXFMT
>
41 class TrueColorPixelPtr
: public BasePixelPtr
44 PIXBYTE
GetRed() const;
45 PIXBYTE
GetGreen() const;
46 PIXBYTE
GetBlue() const;
47 PIXBYTE
GetAlpha() const;
49 void SetColor( PIXBYTE r
, PIXBYTE g
, PIXBYTE b
) const;
50 void SetAlpha( PIXBYTE a
) const;
53 // template specializations for truecolor pixel formats
55 class TrueColorPixelPtr
<ScanlineFormat::N24BitTcRgb
> : public BasePixelPtr
58 void operator++() { mpPixel
+= 3; }
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
) {}
66 void SetColor( PIXBYTE r
, PIXBYTE g
, PIXBYTE b
) const
75 class TrueColorPixelPtr
<ScanlineFormat::N24BitTcBgr
> : public BasePixelPtr
78 void operator++() { mpPixel
+= 3; }
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
) {}
86 void SetColor( PIXBYTE r
, PIXBYTE g
, PIXBYTE b
) const
95 class TrueColorPixelPtr
<ScanlineFormat::N32BitTcArgb
> : public BasePixelPtr
98 void operator++() { mpPixel
+= 4; }
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
; }
106 void SetColor( PIXBYTE r
, PIXBYTE g
, PIXBYTE b
) const
115 class TrueColorPixelPtr
<ScanlineFormat::N32BitTcAbgr
> : public BasePixelPtr
118 void operator++() { mpPixel
+= 4; }
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
; }
126 void SetColor( PIXBYTE r
, PIXBYTE g
, PIXBYTE b
) const
135 class TrueColorPixelPtr
<ScanlineFormat::N32BitTcRgba
> : public BasePixelPtr
138 void operator++() { mpPixel
+= 4; }
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
; }
146 void SetColor( PIXBYTE r
, PIXBYTE g
, PIXBYTE b
) const
155 class TrueColorPixelPtr
<ScanlineFormat::N32BitTcBgra
> : public BasePixelPtr
158 void operator++() { mpPixel
+= 4; }
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
; }
166 void SetColor( PIXBYTE r
, PIXBYTE g
, PIXBYTE b
) const
175 class TrueColorPixelPtr
<ScanlineFormat::N8BitTcMask
> : public BasePixelPtr
178 void operator++() { mpPixel
+= 1; }
179 PIXBYTE
GetAlpha() const { return mpPixel
[0]; }
180 void SetAlpha( PIXBYTE a
) const { mpPixel
[0] = a
; }
183 // TODO: for some reason many Alpha maps are ScanlineFormat::N8BitPal
184 // they should be ScanlineFormat::N8BitTcMask
186 class TrueColorPixelPtr
<ScanlineFormat::N8BitPal
>
187 : public TrueColorPixelPtr
<ScanlineFormat::N8BitTcMask
>
190 // converting truecolor formats
191 template <ScanlineFormat SRCFMT
, ScanlineFormat DSTFMT
>
192 static void ImplConvertPixel( const TrueColorPixelPtr
<DSTFMT
>& rDst
,
193 const TrueColorPixelPtr
<SRCFMT
>& rSrc
)
195 rDst
.SetColor( rSrc
.GetRed(), rSrc
.GetGreen(), rSrc
.GetBlue() );
196 rDst
.SetAlpha( rSrc
.GetAlpha() );
199 template <ScanlineFormat SRCFMT
, ScanlineFormat DSTFMT
>
200 static void ImplConvertLine( const TrueColorPixelPtr
<DSTFMT
>& rDst
,
201 const TrueColorPixelPtr
<SRCFMT
>& rSrc
, int nPixelCount
)
203 TrueColorPixelPtr
<DSTFMT
> aDst( rDst
);
204 TrueColorPixelPtr
<SRCFMT
> aSrc( rSrc
);
205 while( --nPixelCount
>= 0 )
207 ImplConvertPixel( aDst
, aSrc
);
213 // alpha blending truecolor pixels
214 template <ScanlineFormat SRCFMT
, ScanlineFormat DSTFMT
>
215 static void ImplBlendPixels( const TrueColorPixelPtr
<DSTFMT
>& rDst
,
216 const TrueColorPixelPtr
<SRCFMT
>& rSrc
, unsigned nAlphaVal
)
218 static const unsigned nAlphaShift
= 8;
220 ImplConvertPixel( rDst
, rSrc
);
221 else if( nAlphaVal
!= ~(~0U << nAlphaShift
) )
223 int nR
= rDst
.GetRed();
224 int nS
= rSrc
.GetRed();
225 nR
= nS
+ (((nR
- nS
) * nAlphaVal
) >> nAlphaShift
);
227 int nG
= rDst
.GetGreen();
228 nS
= rSrc
.GetGreen();
229 nG
= nS
+ (((nG
- nS
) * nAlphaVal
) >> nAlphaShift
);
231 int nB
= rDst
.GetBlue();
233 nB
= nS
+ (((nB
- nS
) * nAlphaVal
) >> nAlphaShift
);
235 rDst
.SetColor( sal::static_int_cast
<PIXBYTE
>(nR
),
236 sal::static_int_cast
<PIXBYTE
>(nG
),
237 sal::static_int_cast
<PIXBYTE
>(nB
) );
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
,
246 TrueColorPixelPtr
<MASKFMT
> aMsk( rMsk
);
247 TrueColorPixelPtr
<DSTFMT
> aDst( rDst
);
248 TrueColorPixelPtr
<SRCFMT
> aSrc( rSrc
);
249 while( --nPixelCount
>= 0 )
251 ImplBlendPixels(aDst
, aSrc
, aMsk
.GetAlpha());
258 static bool ImplCopyImage( BitmapBuffer
& rDstBuffer
, const BitmapBuffer
& rSrcBuffer
)
260 const int nSrcLinestep
= rSrcBuffer
.mnScanlineSize
;
261 int nDstLinestep
= rDstBuffer
.mnScanlineSize
;
263 const PIXBYTE
* pRawSrc
= rSrcBuffer
.mpBits
;
264 PIXBYTE
* pRawDst
= rDstBuffer
.mpBits
;
266 // source and destination don't match upside down
267 if( ScanlineFormat::TopDown
& (rSrcBuffer
.mnFormat
^ rDstBuffer
.mnFormat
) )
269 pRawDst
+= (rSrcBuffer
.mnHeight
- 1) * nDstLinestep
;
270 nDstLinestep
= -rDstBuffer
.mnScanlineSize
;
272 else if( nSrcLinestep
== nDstLinestep
)
274 memcpy( pRawDst
, pRawSrc
, rSrcBuffer
.mnHeight
* nDstLinestep
);
278 int nByteWidth
= nSrcLinestep
;
279 if( nByteWidth
> rDstBuffer
.mnScanlineSize
)
280 nByteWidth
= rDstBuffer
.mnScanlineSize
;
282 for( int y
= rSrcBuffer
.mnHeight
; --y
>= 0; )
284 memcpy( pRawDst
, pRawSrc
, nByteWidth
);
285 pRawSrc
+= nSrcLinestep
;
286 pRawDst
+= nDstLinestep
;
292 template <ScanlineFormat DSTFMT
,ScanlineFormat SRCFMT
>
293 static bool ImplConvertToBitmap( TrueColorPixelPtr
<SRCFMT
>& rSrcLine
,
294 BitmapBuffer
& rDstBuffer
, const BitmapBuffer
& rSrcBuffer
)
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
)
301 const int nSrcLinestep
= rSrcBuffer
.mnScanlineSize
;
302 int nDstLinestep
= rDstBuffer
.mnScanlineSize
;
304 TrueColorPixelPtr
<DSTFMT
> aDstLine
; aDstLine
.SetRawPtr( rDstBuffer
.mpBits
);
306 // source and destination don't match upside down
307 if( ScanlineFormat::TopDown
& (rSrcBuffer
.mnFormat
^ rDstBuffer
.mnFormat
) )
309 aDstLine
.AddByteOffset( (rSrcBuffer
.mnHeight
- 1) * nDstLinestep
);
310 nDstLinestep
= -nDstLinestep
;
313 for( int y
= rSrcBuffer
.mnHeight
; --y
>= 0; )
315 ImplConvertLine( aDstLine
, rSrcLine
, rSrcBuffer
.mnWidth
);
316 rSrcLine
.AddByteOffset( nSrcLinestep
);
317 aDstLine
.AddByteOffset( nDstLinestep
);
323 template <ScanlineFormat SRCFMT
>
324 static bool ImplConvertFromBitmap( BitmapBuffer
& rDst
, const BitmapBuffer
& rSrc
)
326 TrueColorPixelPtr
<SRCFMT
> aSrcType
; aSrcType
.SetRawPtr( rSrc
.mpBits
);
328 // select the matching instantiation for the destination's bitmap format
329 switch (RemoveScanline(rDst
.mnFormat
))
331 case ScanlineFormat::N1BitMsbPal
:
332 case ScanlineFormat::N1BitLsbPal
:
333 case ScanlineFormat::N4BitMsnPal
:
334 case ScanlineFormat::N4BitLsnPal
:
335 case ScanlineFormat::N8BitPal
:
338 case ScanlineFormat::N8BitTcMask
:
339 // return ImplConvertToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc );
340 case ScanlineFormat::N32BitTcMask
:
341 // return ImplConvertToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc );
344 case ScanlineFormat::N24BitTcBgr
:
345 return ImplConvertToBitmap
<ScanlineFormat::N24BitTcBgr
>( aSrcType
, rDst
, rSrc
);
346 case ScanlineFormat::N24BitTcRgb
:
347 return ImplConvertToBitmap
<ScanlineFormat::N24BitTcRgb
>( aSrcType
, rDst
, rSrc
);
349 case ScanlineFormat::N32BitTcAbgr
:
350 return ImplConvertToBitmap
<ScanlineFormat::N32BitTcAbgr
>( aSrcType
, rDst
, rSrc
);
351 case ScanlineFormat::N32BitTcArgb
:
352 return ImplConvertToBitmap
<ScanlineFormat::N32BitTcArgb
>( aSrcType
, rDst
, rSrc
);
353 case ScanlineFormat::N32BitTcBgra
:
354 return ImplConvertToBitmap
<ScanlineFormat::N32BitTcBgra
>( aSrcType
, rDst
, rSrc
);
355 case ScanlineFormat::N32BitTcRgba
:
356 return ImplConvertToBitmap
<ScanlineFormat::N32BitTcRgba
>( aSrcType
, rDst
, rSrc
);
360 static int nNotAccelerated
= 0;
361 SAL_WARN_IF( rSrc
.mnWidth
* rSrc
.mnHeight
>= 4000 && ++nNotAccelerated
== 100,
363 "ImplConvertFromBitmap for not accelerated case (" << std::hex
<< static_cast<int>(rSrc
.mnFormat
) << "->" << static_cast<int>(rDst
.mnFormat
) << ")" );
368 // A universal stretching conversion is overkill in most common situations
369 // => performance benefits for speeding up the non-stretching cases
370 bool ImplFastBitmapConversion( BitmapBuffer
& rDst
, const BitmapBuffer
& rSrc
,
371 const SalTwoRect
& rTR
)
373 // TODO:horizontal mirroring not implemented yet
374 if( rTR
.mnDestWidth
< 0 )
376 // vertical mirroring
377 if( rTR
.mnDestHeight
< 0 )
378 // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
381 // offsetted conversion is not implemented yet
382 if( rTR
.mnSrcX
|| rTR
.mnSrcY
)
384 if( rTR
.mnDestX
|| rTR
.mnDestY
)
387 // stretched conversion is not implemented yet
388 if( rTR
.mnDestWidth
!= rTR
.mnSrcWidth
)
390 if( rTR
.mnDestHeight
!= rTR
.mnSrcHeight
)
393 // check source image size
394 if( rSrc
.mnWidth
< rTR
.mnSrcX
+ rTR
.mnSrcWidth
)
396 if( rSrc
.mnHeight
< rTR
.mnSrcY
+ rTR
.mnSrcHeight
)
399 // check dest image size
400 if( rDst
.mnWidth
< rTR
.mnDestX
+ rTR
.mnDestWidth
)
402 if( rDst
.mnHeight
< rTR
.mnDestY
+ rTR
.mnDestHeight
)
405 const ScanlineFormat nSrcFormat
= RemoveScanline(rSrc
.mnFormat
);
406 const ScanlineFormat nDstFormat
= RemoveScanline(rDst
.mnFormat
);
408 // special handling of trivial cases
409 if( nSrcFormat
== nDstFormat
)
411 // accelerated palette conversions not yet implemented
412 if( rSrc
.maPalette
!= rDst
.maPalette
)
414 return ImplCopyImage( rDst
, rSrc
);
417 // select the matching instantiation for the source's bitmap format
420 case ScanlineFormat::N1BitMsbPal
:
421 case ScanlineFormat::N1BitLsbPal
:
422 case ScanlineFormat::N4BitMsnPal
:
423 case ScanlineFormat::N4BitLsnPal
:
424 case ScanlineFormat::N8BitPal
:
427 case ScanlineFormat::N8BitTcMask
:
428 // return ImplConvertFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
429 case ScanlineFormat::N32BitTcMask
:
430 // return ImplConvertFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
433 case ScanlineFormat::N24BitTcBgr
:
434 return ImplConvertFromBitmap
<ScanlineFormat::N24BitTcBgr
>( rDst
, rSrc
);
435 case ScanlineFormat::N24BitTcRgb
:
436 return ImplConvertFromBitmap
<ScanlineFormat::N24BitTcRgb
>( rDst
, rSrc
);
438 case ScanlineFormat::N32BitTcAbgr
:
439 return ImplConvertFromBitmap
<ScanlineFormat::N32BitTcAbgr
>( rDst
, rSrc
);
440 case ScanlineFormat::N32BitTcArgb
:
441 return ImplConvertFromBitmap
<ScanlineFormat::N32BitTcArgb
>( rDst
, rSrc
);
442 case ScanlineFormat::N32BitTcBgra
:
443 return ImplConvertFromBitmap
<ScanlineFormat::N32BitTcBgra
>( rDst
, rSrc
);
444 case ScanlineFormat::N32BitTcRgba
:
445 return ImplConvertFromBitmap
<ScanlineFormat::N32BitTcRgba
>( rDst
, rSrc
);
449 static int nNotAccelerated
= 0;
450 SAL_WARN_IF( rSrc
.mnWidth
* rSrc
.mnHeight
>= 4000 && ++nNotAccelerated
== 100,
452 "ImplFastBitmapConversion for not accelerated case (" << std::hex
<< static_cast<int>(rSrc
.mnFormat
) << "->" << static_cast<int>(rDst
.mnFormat
) << ")" );
457 template <ScanlineFormat DSTFMT
, ScanlineFormat SRCFMT
> //,sal_uLong MSKFMT>
458 static bool ImplBlendToBitmap( TrueColorPixelPtr
<SRCFMT
>& rSrcLine
,
459 BitmapBuffer
& rDstBuffer
, const BitmapBuffer
& rSrcBuffer
,
460 const BitmapBuffer
& rMskBuffer
)
462 SAL_WARN_IF( rMskBuffer
.mnFormat
!= ScanlineFormat::N8BitPal
, "vcl.gdi", "FastBmp BlendImage: unusual MSKFMT" );
464 const int nSrcLinestep
= rSrcBuffer
.mnScanlineSize
;
465 int nMskLinestep
= rMskBuffer
.mnScanlineSize
;
466 int nDstLinestep
= rDstBuffer
.mnScanlineSize
;
468 TrueColorPixelPtr
<ScanlineFormat::N8BitPal
> aMskLine
; aMskLine
.SetRawPtr( rMskBuffer
.mpBits
);
469 TrueColorPixelPtr
<DSTFMT
> aDstLine
; aDstLine
.SetRawPtr( rDstBuffer
.mpBits
);
471 // special case for single line masks
472 if( rMskBuffer
.mnHeight
== 1 )
475 // source and mask don't match: upside down
476 if( (rSrcBuffer
.mnFormat
^ rMskBuffer
.mnFormat
) & ScanlineFormat::TopDown
)
478 aMskLine
.AddByteOffset( (rSrcBuffer
.mnHeight
- 1) * nMskLinestep
);
479 nMskLinestep
= -nMskLinestep
;
482 // source and destination don't match: upside down
483 if( (rSrcBuffer
.mnFormat
^ rDstBuffer
.mnFormat
) & ScanlineFormat::TopDown
)
485 aDstLine
.AddByteOffset( (rDstBuffer
.mnHeight
- 1) * nDstLinestep
);
486 nDstLinestep
= -nDstLinestep
;
489 assert(rDstBuffer
.mnHeight
<= rSrcBuffer
.mnHeight
&& "not sure about that?");
490 for (int y
= rDstBuffer
.mnHeight
; --y
>= 0;)
492 ImplBlendLines(aDstLine
, rSrcLine
, aMskLine
, rDstBuffer
.mnWidth
);
493 aDstLine
.AddByteOffset( nDstLinestep
);
494 rSrcLine
.AddByteOffset( nSrcLinestep
);
495 aMskLine
.AddByteOffset( nMskLinestep
);
501 // some specializations to reduce the code size
503 bool ImplBlendToBitmap
<ScanlineFormat::N24BitTcBgr
,ScanlineFormat::N24BitTcBgr
>(
504 TrueColorPixelPtr
<ScanlineFormat::N24BitTcBgr
>&,
505 BitmapBuffer
& rDstBuffer
, const BitmapBuffer
& rSrcBuffer
,
506 const BitmapBuffer
& rMskBuffer
)
508 TrueColorPixelPtr
<ScanlineFormat::N24BitTcRgb
> aSrcType
; aSrcType
.SetRawPtr( rSrcBuffer
.mpBits
);
509 return ImplBlendToBitmap
<ScanlineFormat::N24BitTcRgb
>( aSrcType
, rDstBuffer
, rSrcBuffer
, rMskBuffer
);
513 bool ImplBlendToBitmap
<ScanlineFormat::N32BitTcAbgr
,ScanlineFormat::N32BitTcAbgr
>(
514 TrueColorPixelPtr
<ScanlineFormat::N32BitTcAbgr
>&,
515 BitmapBuffer
& rDstBuffer
, const BitmapBuffer
& rSrcBuffer
,
516 const BitmapBuffer
& rMskBuffer
)
518 TrueColorPixelPtr
<ScanlineFormat::N32BitTcArgb
> aSrcType
; aSrcType
.SetRawPtr( rSrcBuffer
.mpBits
);
519 return ImplBlendToBitmap
<ScanlineFormat::N32BitTcArgb
>( aSrcType
, rDstBuffer
, rSrcBuffer
, rMskBuffer
);
523 bool ImplBlendToBitmap
<ScanlineFormat::N32BitTcBgra
,ScanlineFormat::N32BitTcBgra
>(
524 TrueColorPixelPtr
<ScanlineFormat::N32BitTcBgra
>&,
525 BitmapBuffer
& rDstBuffer
, const BitmapBuffer
& rSrcBuffer
,
526 const BitmapBuffer
& rMskBuffer
)
528 TrueColorPixelPtr
<ScanlineFormat::N32BitTcRgba
> aSrcType
; aSrcType
.SetRawPtr( rSrcBuffer
.mpBits
);
529 return ImplBlendToBitmap
<ScanlineFormat::N32BitTcRgba
>( aSrcType
, rDstBuffer
, rSrcBuffer
, rMskBuffer
);
532 template <ScanlineFormat SRCFMT
>
533 static bool ImplBlendFromBitmap( BitmapBuffer
& rDst
, const BitmapBuffer
& rSrc
, const BitmapBuffer
& rMsk
)
535 TrueColorPixelPtr
<SRCFMT
> aSrcType
; aSrcType
.SetRawPtr( rSrc
.mpBits
);
537 // select the matching instantiation for the destination's bitmap format
538 switch (RemoveScanline(rDst
.mnFormat
))
540 case ScanlineFormat::N1BitMsbPal
:
541 case ScanlineFormat::N1BitLsbPal
:
542 case ScanlineFormat::N4BitMsnPal
:
543 case ScanlineFormat::N4BitLsnPal
:
544 case ScanlineFormat::N8BitPal
:
547 case ScanlineFormat::N8BitTcMask
:
548 // return ImplBlendToBitmap<ScanlineFormat::N8BitTcMask>( aSrcType, rDst, rSrc, rMsk );
549 case ScanlineFormat::N32BitTcMask
:
550 // return ImplBlendToBitmap<ScanlineFormat::N32BitTcMask>( aSrcType, rDst, rSrc, rMsk );
553 case ScanlineFormat::N24BitTcBgr
:
554 return ImplBlendToBitmap
<ScanlineFormat::N24BitTcBgr
>( aSrcType
, rDst
, rSrc
, rMsk
);
555 case ScanlineFormat::N24BitTcRgb
:
556 return ImplBlendToBitmap
<ScanlineFormat::N24BitTcRgb
>( aSrcType
, rDst
, rSrc
, rMsk
);
558 case ScanlineFormat::N32BitTcAbgr
:
559 return ImplBlendToBitmap
<ScanlineFormat::N32BitTcAbgr
>( aSrcType
, rDst
, rSrc
, rMsk
);
560 case ScanlineFormat::N32BitTcArgb
:
561 return ImplBlendToBitmap
<ScanlineFormat::N32BitTcArgb
>( aSrcType
, rDst
, rSrc
, rMsk
);
562 case ScanlineFormat::N32BitTcBgra
:
563 return ImplBlendToBitmap
<ScanlineFormat::N32BitTcBgra
>( aSrcType
, rDst
, rSrc
, rMsk
);
564 case ScanlineFormat::N32BitTcRgba
:
565 return ImplBlendToBitmap
<ScanlineFormat::N32BitTcRgba
>( aSrcType
, rDst
, rSrc
, rMsk
);
569 static int nNotAccelerated
= 0;
570 SAL_WARN_IF( rSrc
.mnWidth
* rSrc
.mnHeight
>= 4000 && ++nNotAccelerated
== 100,
572 "ImplBlendFromBitmap for not accelerated case (" << std::hex
<< static_cast<int>(rSrc
.mnFormat
) << "*" << static_cast<int>(rMsk
.mnFormat
) << "->" << static_cast<int>(rDst
.mnFormat
) );
576 bool ImplFastBitmapBlending( BitmapWriteAccess
const & rDstWA
,
577 const BitmapReadAccess
& rSrcRA
, const BitmapReadAccess
& rMskRA
,
578 const SalTwoRect
& rTR
)
580 // accelerated blending of paletted bitmaps not implemented yet
581 if( rSrcRA
.HasPalette() )
583 if( rDstWA
.HasPalette() )
585 // TODO: either get rid of mask's use of 8BIT_PAL or check the palette
587 // horizontal mirroring not implemented yet
588 if( rTR
.mnDestWidth
< 0 )
590 // vertical mirroring
591 if( rTR
.mnDestHeight
< 0 )
592 // TODO: rDst.mnFormat ^= ScanlineFormat::TopDown;
595 // offsetted blending is not implemented yet
596 if( rTR
.mnSrcX
|| rTR
.mnSrcY
)
598 if( rTR
.mnDestX
|| rTR
.mnDestY
)
601 // stretched blending is not implemented yet
602 if( rTR
.mnDestWidth
!= rTR
.mnSrcWidth
)
604 if( rTR
.mnDestHeight
!= rTR
.mnSrcHeight
)
607 // check source image size
608 if( rSrcRA
.Width() < rTR
.mnSrcX
+ rTR
.mnSrcWidth
)
610 if( rSrcRA
.Height() < rTR
.mnSrcY
+ rTR
.mnSrcHeight
)
613 // check mask image size
614 if( rMskRA
.Width() < rTR
.mnSrcX
+ rTR
.mnSrcWidth
)
616 if( rMskRA
.Height() < rTR
.mnSrcY
+ rTR
.mnSrcHeight
)
617 if( rMskRA
.Height() != 1 )
620 // check dest image size
621 if( rDstWA
.Width() < rTR
.mnDestX
+ rTR
.mnDestWidth
)
623 if( rDstWA
.Height() < rTR
.mnDestY
+ rTR
.mnDestHeight
)
626 BitmapBuffer
& rDst
= *rDstWA
.ImplGetBitmapBuffer();
627 const BitmapBuffer
& rSrc
= *rSrcRA
.ImplGetBitmapBuffer();
628 const BitmapBuffer
& rMsk
= *rMskRA
.ImplGetBitmapBuffer();
630 const ScanlineFormat nSrcFormat
= RemoveScanline(rSrc
.mnFormat
);
632 // select the matching instantiation for the source's bitmap format
635 case ScanlineFormat::N1BitMsbPal
:
636 case ScanlineFormat::N1BitLsbPal
:
637 case ScanlineFormat::N4BitMsnPal
:
638 case ScanlineFormat::N4BitLsnPal
:
639 case ScanlineFormat::N8BitPal
:
642 case ScanlineFormat::N8BitTcMask
:
643 // return ImplBlendFromBitmap<ScanlineFormat::N8BitTcMask>( rDst, rSrc );
644 case ScanlineFormat::N32BitTcMask
:
645 // return ImplBlendFromBitmap<ScanlineFormat::N32BitTcMask>( rDst, rSrc );
648 case ScanlineFormat::N24BitTcBgr
:
649 return ImplBlendFromBitmap
<ScanlineFormat::N24BitTcBgr
>( rDst
, rSrc
, rMsk
);
650 case ScanlineFormat::N24BitTcRgb
:
651 return ImplBlendFromBitmap
<ScanlineFormat::N24BitTcRgb
>( rDst
, rSrc
, rMsk
);
653 case ScanlineFormat::N32BitTcAbgr
:
654 return ImplBlendFromBitmap
<ScanlineFormat::N32BitTcAbgr
>( rDst
, rSrc
, rMsk
);
655 case ScanlineFormat::N32BitTcArgb
:
656 return ImplBlendFromBitmap
<ScanlineFormat::N32BitTcArgb
>( rDst
, rSrc
, rMsk
);
657 case ScanlineFormat::N32BitTcBgra
:
658 return ImplBlendFromBitmap
<ScanlineFormat::N32BitTcBgra
>( rDst
, rSrc
, rMsk
);
659 case ScanlineFormat::N32BitTcRgba
:
660 return ImplBlendFromBitmap
<ScanlineFormat::N32BitTcRgba
>( rDst
, rSrc
, rMsk
);
664 static int nNotAccelerated
= 0;
665 SAL_WARN_IF( rSrc
.mnWidth
* rSrc
.mnHeight
>= 4000 && ++nNotAccelerated
== 100,
667 "ImplFastBlend for not accelerated case (" << std::hex
<< static_cast<int>(rSrc
.mnFormat
) << "*" << static_cast<int>(rMsk
.mnFormat
) << "->" << static_cast<int>(rDst
.mnFormat
) << ")" );
672 bool ImplFastEraseBitmap( BitmapBuffer
& rDst
, const BitmapColor
& rColor
)
674 const ScanlineFormat nDstFormat
= RemoveScanline(rDst
.mnFormat
);
676 // erasing a bitmap is often just a byte-wise memory fill
677 bool bByteFill
= true;
682 case ScanlineFormat::N1BitMsbPal
:
683 case ScanlineFormat::N1BitLsbPal
:
684 nFillByte
= rColor
.GetIndex();
685 nFillByte
= static_cast<sal_uInt8
>( -(nFillByte
& 1) ); // 0x00 or 0xFF
687 case ScanlineFormat::N4BitMsnPal
:
688 case ScanlineFormat::N4BitLsnPal
:
689 nFillByte
= rColor
.GetIndex();
691 nFillByte
|= (nFillByte
<< 4);
693 case ScanlineFormat::N8BitPal
:
694 case ScanlineFormat::N8BitTcMask
:
695 nFillByte
= rColor
.GetIndex();
698 case ScanlineFormat::N24BitTcBgr
:
699 case ScanlineFormat::N24BitTcRgb
:
700 nFillByte
= rColor
.GetRed();
701 if( (nFillByte
!= rColor
.GetGreen())
702 || (nFillByte
!= rColor
.GetBlue()) )
714 long nByteCount
= rDst
.mnHeight
* rDst
.mnScanlineSize
;
715 memset( rDst
.mpBits
, nFillByte
, nByteCount
);
719 // TODO: handle other bitmap formats
722 case ScanlineFormat::N32BitTcMask
:
724 case ScanlineFormat::N24BitTcBgr
:
725 case ScanlineFormat::N24BitTcRgb
:
727 case ScanlineFormat::N32BitTcAbgr
:
728 case ScanlineFormat::N32BitTcArgb
:
729 case ScanlineFormat::N32BitTcBgra
:
730 case ScanlineFormat::N32BitTcRgba
:
740 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */