xref: /aoo41x/main/vcl/source/gdi/bmpfast.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <bmpfast.hxx>
32 
33 #ifndef NO_OPTIMIZED_BITMAP_ACCESS
34 
35 #include <tools/debug.hxx>
36 #include <vcl/bmpacc.hxx>
37 
38 #define FAST_ARGB_BGRA
39 
40 #include <stdlib.h>
41 static bool bDisableFastBitops = (getenv( "SAL_DISABLE_BITMAPS_OPTS" ) != NULL);
42 
43 typedef unsigned char PIXBYTE;
44 
45 class BasePixelPtr
46 {
47 public:
48             BasePixelPtr( PIXBYTE* p = NULL ) : mpPixel( p ) {}
49     void    SetRawPtr( PIXBYTE* pRawPtr )               { mpPixel = pRawPtr; }
50     PIXBYTE* GetRawPtr( void ) const                    { return mpPixel; }
51     void    AddByteOffset( int nByteOffset )            { mpPixel += nByteOffset; }
52     bool    operator<( const BasePixelPtr& rCmp ) const { return (mpPixel < rCmp.mpPixel); }
53 
54 protected:
55    PIXBYTE* mpPixel;
56 };
57 
58 template <sal_uLong PIXFMT>
59 class TrueColorPixelPtr : public BasePixelPtr
60 {
61 public:
62     PIXBYTE GetRed() const;
63     PIXBYTE GetGreen() const;
64     PIXBYTE GetBlue() const;
65     PIXBYTE GetAlpha() const;
66 
67     void    SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const;
68     void    SetAlpha( PIXBYTE a ) const;
69     void    operator++(int);
70 };
71 
72 // =======================================================================
73 // template specializations for truecolor pixel formats
74 
75 template <>
76 class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_RGB> : public BasePixelPtr
77 {
78 public:
79     void    operator++()       { mpPixel += 3; }
80 
81     PIXBYTE GetRed() const     { return mpPixel[0]; }
82     PIXBYTE GetGreen() const   { return mpPixel[1]; }
83     PIXBYTE GetBlue() const    { return mpPixel[2]; }
84     PIXBYTE GetAlpha() const   { return 0; }
85     void SetAlpha( PIXBYTE ) const {}
86 
87     void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
88     {
89         mpPixel[0] = r;
90         mpPixel[1] = g;
91         mpPixel[2] = b;
92     }
93 };
94 
95 template <>
96 class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_BGR> : public BasePixelPtr
97 {
98 public:
99     void    operator++()        { mpPixel += 3; }
100 
101     PIXBYTE GetRed() const      { return mpPixel[2]; }
102     PIXBYTE GetGreen() const    { return mpPixel[1]; }
103     PIXBYTE GetBlue() const     { return mpPixel[0]; }
104     PIXBYTE GetAlpha() const    { return 0; }
105     void SetAlpha( PIXBYTE ) const  {}
106 
107     void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
108     {
109         mpPixel[0] = b;
110         mpPixel[1] = g;
111         mpPixel[2] = r;
112     }
113 };
114 
115 template <>
116 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ARGB> : public BasePixelPtr
117 {
118 public:
119     void    operator++()        { mpPixel += 4; }
120 
121     PIXBYTE GetRed() const      { return mpPixel[1]; }
122     PIXBYTE GetGreen() const    { return mpPixel[2]; }
123     PIXBYTE GetBlue() const     { return mpPixel[3]; }
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] = r;
130         mpPixel[2] = g;
131         mpPixel[3] = b;
132     }
133 };
134 
135 template <>
136 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ABGR> : public BasePixelPtr
137 {
138 public:
139     void    operator++()        { mpPixel += 4; }
140 
141     PIXBYTE GetRed() const      { return mpPixel[3]; }
142     PIXBYTE GetGreen() const    { return mpPixel[2]; }
143     PIXBYTE GetBlue() const     { return mpPixel[1]; }
144     PIXBYTE GetAlpha() const    { return mpPixel[0]; }
145     void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
146 
147     void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
148     {
149         mpPixel[1] = b;
150         mpPixel[2] = g;
151         mpPixel[3] = r;
152     }
153 };
154 
155 template <>
156 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_RGBA> : public BasePixelPtr
157 {
158 public:
159     void    operator++()            { mpPixel += 4; }
160 
161     PIXBYTE GetRed() const          { return mpPixel[0]; }
162     PIXBYTE GetGreen() const        { return mpPixel[1]; }
163     PIXBYTE GetBlue() const         { return mpPixel[2]; }
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] = r;
170         mpPixel[1] = g;
171         mpPixel[2] = b;
172     }
173 };
174 
175 template <>
176 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_BGRA> : public BasePixelPtr
177 {
178 public:
179     void    operator++()            { mpPixel += 4; }
180 
181     PIXBYTE GetRed() const          { return mpPixel[2]; }
182     PIXBYTE GetGreen() const        { return mpPixel[1]; }
183     PIXBYTE GetBlue() const         { return mpPixel[0]; }
184     PIXBYTE GetAlpha() const        { return mpPixel[3]; }
185     void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
186 
187     void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
188     {
189         mpPixel[0] = b;
190         mpPixel[1] = g;
191         mpPixel[2] = r;
192     }
193 };
194 
195 template <>
196 class TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_MSB_MASK> : public BasePixelPtr
197 {
198 public:
199     void    operator++()            { mpPixel += 2; }
200 
201     // TODO: non565-RGB
202     PIXBYTE GetRed() const          { return (mpPixel[0] & 0xF8U); }
203     PIXBYTE GetGreen() const        { return (mpPixel[0]<<5U) | ((mpPixel[1]>>3U)&28U); }
204     PIXBYTE GetBlue() const         { return (mpPixel[1]<<3U); }
205     PIXBYTE GetAlpha() const        { return 0; }
206     void SetAlpha( PIXBYTE ) const  {}
207 
208     void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
209     {
210         mpPixel[0] = ((g >> 5U) & 7U) | (r & 0xF8U);
211         mpPixel[1] = ((g & 28U)<< 3U) | (b >> 3U);
212     }
213 };
214 
215 template <>
216 class TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_LSB_MASK> : public BasePixelPtr
217 {
218 public:
219     void    operator++()            { mpPixel += 2; }
220 
221     // TODO: non565-RGB
222     PIXBYTE GetRed() const          { return (mpPixel[1] & 0xF8U); }
223     PIXBYTE GetGreen() const        { return (mpPixel[1]<<5U) | ((mpPixel[0]>>3U)&28U); }
224     PIXBYTE GetBlue() const         { return (mpPixel[0]<<3U); }
225     PIXBYTE GetAlpha() const        { return 0; }
226     void SetAlpha( PIXBYTE ) const  {}
227 
228     void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
229     {
230         mpPixel[0] = ((g & 28U)<< 3U) | (b >> 3U);
231         mpPixel[1] = ((g >> 5U) & 7U) | (r & 0xF8U);
232     }
233 };
234 
235 // -----------------------------------------------------------------------
236 
237 template <>
238 class TrueColorPixelPtr<BMP_FORMAT_8BIT_TC_MASK> : public BasePixelPtr
239 {
240 public:
241     void    operator++()                    { mpPixel += 1; }
242     PIXBYTE GetAlpha() const                { return mpPixel[0]; }
243     void    SetAlpha( PIXBYTE a ) const     { mpPixel[0] = a; }
244     void    SetColor( PIXBYTE, PIXBYTE, PIXBYTE ) const {}
245 };
246 
247 // TODO: for some reason many Alpha maps are BMP_FORMAT_8BIT_PAL
248 // they should be BMP_FORMAT_8BIT_TC_MASK
249 template <>
250 class TrueColorPixelPtr<BMP_FORMAT_8BIT_PAL>
251 : public TrueColorPixelPtr<BMP_FORMAT_8BIT_TC_MASK>
252 {};
253 
254 #if 0
255 template <>
256 class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_MASK> : public BasePixelPtr
257 {
258 public:
259     void operator++()   { mpPixel += 3; }
260 
261     unsigned GetAlpha() const
262     {
263         unsigned nAlpha = mpPixel[0];
264         nAlpha |= mpPixel[1] << 8U;
265         nAlpha |= mpPixel[2] << 16U;
266         return nAlpha;
267     }
268 
269     void SetAlpha( unsigned nAlpha ) const
270     {
271         mpPixel[0] = nAlpha;
272         mpPixel[1] = nAlpha >> 8U;
273         mpPixel[2] = nAlpha >> 16U;
274     }
275 };
276 
277 template <>
278 class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_MASK> : public BasePixelPtr
279 {
280 public:
281     void operator++()   { mpPixel += 4; }
282 
283     unsigned GetAlpha() const
284     {
285 #ifdef OSL_BIGENDIAN
286         unsigned nAlpha = *reinterpret_cast<unsigned*>( mpPixel );
287 #else
288         unsigned nAlpha = mpPixel[0];
289         nAlpha |= mpPixel[1] << 8U;
290         nAlpha |= mpPixel[2] << 16U;
291         nAlpha |= mpPixel[3] << 24U;
292 #endif
293         return nAlpha;
294     }
295 
296     void SetAlpha( unsigned nAlpha ) const
297     {
298 #ifdef OSL_BIGENDIAN
299         *reinterpret_cast<unsigned*>( mpPixel ) = nAlpha;
300 #else
301         mpPixel[0] = nAlpha;
302         mpPixel[1] = nAlpha >> 8U;
303         mpPixel[2] = nAlpha >> 16U;
304         mpPixel[3] = nAlpha >> 24U;
305 #endif
306     }
307 };
308 
309 #endif
310 
311 // =======================================================================
312 // converting truecolor formats
313 
314 template <sal_uLong SRCFMT, sal_uLong DSTFMT>
315 inline void ImplConvertPixel( const TrueColorPixelPtr<DSTFMT>& rDst,
316     const TrueColorPixelPtr<SRCFMT>& rSrc )
317 {
318     rDst.SetColor( rSrc.GetRed(), rSrc.GetGreen(), rSrc.GetBlue() );
319     rDst.SetAlpha( rSrc.GetAlpha() );
320 }
321 
322 // -----------------------------------------------------------------------
323 
324 template <>
325 inline void ImplConvertPixel<BMP_FORMAT_16BIT_TC_LSB_MASK, BMP_FORMAT_16BIT_TC_MSB_MASK> (
326     const TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_MSB_MASK>& rDst,
327     const TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_LSB_MASK>& rSrc )
328 {
329     // byte swapping
330     const PIXBYTE* pSrc = rSrc.GetRawPtr();
331     PIXBYTE* pDst = rDst.GetRawPtr();
332     pDst[1] = pSrc[0];
333     pDst[0] = pSrc[1];
334 }
335 
336 // -----------------------------------------------------------------------
337 
338 template <sal_uLong SRCFMT, sal_uLong DSTFMT>
339 inline void ImplConvertLine( const TrueColorPixelPtr<DSTFMT>& rDst,
340     const TrueColorPixelPtr<SRCFMT>& rSrc, int nPixelCount )
341 {
342     TrueColorPixelPtr<DSTFMT> aDst( rDst );
343     TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
344     while( --nPixelCount >= 0 )
345     {
346         ImplConvertPixel( aDst, aSrc );
347         ++aSrc;
348         ++aDst;
349     }
350 }
351 
352 // =======================================================================
353 // alpha blending truecolor pixels
354 
355 template <unsigned ALPHABITS, sal_uLong SRCFMT, sal_uLong DSTFMT>
356 inline void ImplBlendPixels( const TrueColorPixelPtr<DSTFMT>& rDst,
357     const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal )
358 {
359     if( !nAlphaVal )
360         ImplConvertPixel( rDst, rSrc );
361     else if( nAlphaVal != ~(~0 << ALPHABITS) )
362     {
363         static const unsigned nAlphaShift = (ALPHABITS > 8) ? 8 : ALPHABITS;
364         if( ALPHABITS > nAlphaShift )
365             nAlphaVal >>= ALPHABITS - nAlphaShift;
366 
367         int nR = rDst.GetRed();
368         int nS = rSrc.GetRed();
369         nR = nS + (((nR - nS) * nAlphaVal) >> nAlphaShift);
370 
371         int nG = rDst.GetGreen();
372         nS = rSrc.GetGreen();
373         nG = nS + (((nG - nS) * nAlphaVal) >> nAlphaShift);
374 
375         int nB = rDst.GetBlue();
376         nS = rSrc.GetBlue();
377         nB = nS + (((nB - nS) * nAlphaVal) >> nAlphaShift);
378 
379         rDst.SetColor( sal::static_int_cast<PIXBYTE>(nR),
380                        sal::static_int_cast<PIXBYTE>(nG),
381                        sal::static_int_cast<PIXBYTE>(nB) );
382     }
383 }
384 
385 // -----------------------------------------------------------------------
386 
387 template <unsigned ALPHABITS, sal_uLong MASKFMT, sal_uLong SRCFMT, sal_uLong DSTFMT>
388 inline void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst,
389     const TrueColorPixelPtr<SRCFMT>& rSrc, const TrueColorPixelPtr<MASKFMT>& rMsk,
390     int nPixelCount )
391 {
392     TrueColorPixelPtr<MASKFMT> aMsk( rMsk );
393     TrueColorPixelPtr<DSTFMT> aDst( rDst );
394     TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
395     while( --nPixelCount >= 0 )
396     {
397         ImplBlendPixels<ALPHABITS>( aDst, aSrc, aMsk.GetAlpha() );
398         ++aDst;
399         ++aSrc;
400         ++aMsk;
401     }
402 }
403 
404 // -----------------------------------------------------------------------
405 
406 template <unsigned ALPHABITS, sal_uLong SRCFMT, sal_uLong DSTFMT>
407 inline void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst,
408     const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal,
409     int nPixelCount )
410 {
411     if( nAlphaVal == ~(~0 << ALPHABITS) )
412         ImplConvertLine( rDst, rSrc, nPixelCount );
413     else if( nAlphaVal )
414     {
415         TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
416         TrueColorPixelPtr<DSTFMT> aDst( rDst );
417         while( --nPixelCount >= 0 )
418         {
419             ImplBlendPixels<ALPHABITS>( aDst, aSrc, nAlphaVal );
420             ++aDst;
421             ++aSrc;
422         }
423     }
424 }
425 
426 // =======================================================================
427 
428 static bool ImplCopyImage( BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
429 {
430     const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
431     int nDstLinestep = rDstBuffer.mnScanlineSize;
432 
433     const PIXBYTE* pRawSrc = rSrcBuffer.mpBits;
434     PIXBYTE* pRawDst = rDstBuffer.mpBits;
435 
436     // source and destination don't match upside down
437     if( BMP_FORMAT_TOP_DOWN & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat)  )
438     {
439         pRawDst += (rSrcBuffer.mnHeight - 1) * nDstLinestep;
440         nDstLinestep = -rDstBuffer.mnScanlineSize;
441     }
442     else if( nSrcLinestep == nDstLinestep )
443     {
444         memcpy( pRawDst, pRawSrc, rSrcBuffer.mnHeight * nDstLinestep );
445         return true;
446     }
447 
448     int nByteWidth = nSrcLinestep;
449     if( nByteWidth > rDstBuffer.mnScanlineSize )
450         nByteWidth = rDstBuffer.mnScanlineSize;
451 
452     for( int y = rSrcBuffer.mnHeight; --y >= 0; )
453     {
454         memcpy( pRawDst, pRawSrc, nByteWidth );
455         pRawSrc += nSrcLinestep;
456         pRawDst += nDstLinestep;
457     }
458 
459     return true;
460 }
461 
462 // -----------------------------------------------------------------------
463 
464 template <sal_uLong DSTFMT,sal_uLong SRCFMT>
465 bool ImplConvertToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine,
466     BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
467 {
468     // help the compiler to avoid instantiations of unneeded conversions
469     DBG_ASSERT( SRCFMT != DSTFMT, "ImplConvertToBitmap into same format");
470     if( SRCFMT == DSTFMT )
471         return false;
472 
473     const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
474     int nDstLinestep = rDstBuffer.mnScanlineSize;
475 
476     TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
477 
478     // source and destination don't match upside down
479     if( BMP_FORMAT_TOP_DOWN & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
480     {
481         aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep );
482         nDstLinestep = -nDstLinestep;
483     }
484 
485     for( int y = rSrcBuffer.mnHeight; --y >= 0; )
486     {
487         ImplConvertLine( aDstLine, rSrcLine, rSrcBuffer.mnWidth );
488         rSrcLine.AddByteOffset( nSrcLinestep );
489         aDstLine.AddByteOffset( nDstLinestep );
490     }
491 
492     return true;
493 }
494 
495 // -----------------------------------------------------------------------
496 
497 template <sal_uLong SRCFMT>
498 inline bool ImplConvertFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc )
499 {
500     TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
501 
502     // select the matching instantiation for the destination's bitmap format
503     switch( rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN )
504     {
505         case BMP_FORMAT_1BIT_MSB_PAL:
506         case BMP_FORMAT_1BIT_LSB_PAL:
507         case BMP_FORMAT_4BIT_MSN_PAL:
508         case BMP_FORMAT_4BIT_LSN_PAL:
509         case BMP_FORMAT_8BIT_PAL:
510             break;
511 
512         case BMP_FORMAT_8BIT_TC_MASK:
513 //            return ImplConvertToBitmap<BMP_FORMAT_8BIT_TC_MASK>( aSrcType, rDst, rSrc );
514         case BMP_FORMAT_24BIT_TC_MASK:
515 //            return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_MASK>( aSrcType, rDst, rSrc );
516         case BMP_FORMAT_32BIT_TC_MASK:
517 //            return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_MASK>( aSrcType, rDst, rSrc );
518             break;
519 
520         case BMP_FORMAT_16BIT_TC_MSB_MASK:
521             return ImplConvertToBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( aSrcType, rDst, rSrc );
522         case BMP_FORMAT_16BIT_TC_LSB_MASK:
523             return ImplConvertToBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( aSrcType, rDst, rSrc );
524 
525         case BMP_FORMAT_24BIT_TC_BGR:
526             return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_BGR>( aSrcType, rDst, rSrc );
527         case BMP_FORMAT_24BIT_TC_RGB:
528             return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDst, rSrc );
529 
530         case BMP_FORMAT_32BIT_TC_ABGR:
531             return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_ABGR>( aSrcType, rDst, rSrc );
532 #ifdef FAST_ARGB_BGRA
533         case BMP_FORMAT_32BIT_TC_ARGB:
534             return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDst, rSrc );
535         case BMP_FORMAT_32BIT_TC_BGRA:
536             return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_BGRA>( aSrcType, rDst, rSrc );
537 #endif
538         case BMP_FORMAT_32BIT_TC_RGBA:
539             return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDst, rSrc );
540     }
541 
542 #ifdef DEBUG
543     static int nNotAccelerated = 0;
544     if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
545         if( ++nNotAccelerated == 100 )
546 		{
547 			int foo = 0; (void)foo; // so no warning is created when building on pro with debug
548             DBG_WARNING2( "ImplConvertFromBitmap for not accelerated case (0x%04X->0x%04X)",
549                 rSrc.mnFormat, rDst.mnFormat );
550 		}
551 #endif
552 
553     return false;
554 }
555 
556 // =======================================================================
557 
558 // an universal stretching conversion is overkill in most common situations
559 // => performance benefits for speeding up the non-stretching cases
560 bool ImplFastBitmapConversion( BitmapBuffer& rDst, const BitmapBuffer& rSrc,
561     const SalTwoRect& rTR )
562 {
563     if( bDisableFastBitops )
564         return false;
565 
566     // horizontal mirroring not implemented yet
567     if( rTR.mnDestWidth < 0 )
568         return false;
569     // vertical mirroring
570     if( rTR.mnDestHeight < 0 )
571         // TODO: rDst.mnFormat ^= BMP_FORMAT_TOP_DOWN;
572         return false;
573 
574     // offseted conversion is not implemented yet
575     if( rTR.mnSrcX || rTR.mnSrcY )
576         return false;
577     if( rTR.mnDestX || rTR.mnDestY )
578         return false;
579 
580     // stretched conversion is not implemented yet
581     if( rTR.mnDestWidth != rTR.mnSrcWidth )
582         return false;
583     if( rTR.mnDestHeight!= rTR.mnSrcHeight )
584         return false;
585 
586     // check source image size
587     if( rSrc.mnWidth < rTR.mnSrcX + rTR.mnSrcWidth )
588         return false;
589     if( rSrc.mnHeight < rTR.mnSrcY + rTR.mnSrcHeight )
590         return false;
591 
592     // check dest image size
593     if( rDst.mnWidth < rTR.mnDestX + rTR.mnDestWidth )
594         return false;
595     if( rDst.mnHeight < rTR.mnDestY + rTR.mnDestHeight )
596         return false;
597 
598     const sal_uLong nSrcFormat = rSrc.mnFormat & ~BMP_FORMAT_TOP_DOWN;
599     const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN;
600 
601     // TODO: also implement conversions for 16bit colormasks with non-565 format
602     if( nSrcFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
603         if( rSrc.maColorMask.GetRedMask()  != 0xF800
604         ||  rSrc.maColorMask.GetGreenMask()!= 0x07E0
605         ||  rSrc.maColorMask.GetBlueMask() != 0x001F )
606             return false;
607     if( nDstFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
608         if( rDst.maColorMask.GetRedMask()  != 0xF800
609         ||  rDst.maColorMask.GetGreenMask()!= 0x07E0
610         ||  rDst.maColorMask.GetBlueMask() != 0x001F )
611             return false;
612 
613     // special handling of trivial cases
614     if( nSrcFormat == nDstFormat )
615     {
616         // accelerated palette conversions not yet implemented
617         if( rSrc.maPalette != rDst.maPalette )
618             return false;
619         return ImplCopyImage( rDst, rSrc );
620     }
621 
622     // select the matching instantiation for the source's bitmap format
623     switch( nSrcFormat )
624     {
625         case BMP_FORMAT_1BIT_MSB_PAL:
626         case BMP_FORMAT_1BIT_LSB_PAL:
627         case BMP_FORMAT_4BIT_MSN_PAL:
628         case BMP_FORMAT_4BIT_LSN_PAL:
629         case BMP_FORMAT_8BIT_PAL:
630             break;
631 
632         case BMP_FORMAT_8BIT_TC_MASK:
633 //            return ImplConvertFromBitmap<BMP_FORMAT_8BIT_TC_MASK>( rDst, rSrc );
634         case BMP_FORMAT_24BIT_TC_MASK:
635 //            return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_MASK>( rDst, rSrc );
636         case BMP_FORMAT_32BIT_TC_MASK:
637 //            return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_MASK>( rDst, rSrc );
638             break;
639 
640         case BMP_FORMAT_16BIT_TC_MSB_MASK:
641             return ImplConvertFromBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( rDst, rSrc );
642         case BMP_FORMAT_16BIT_TC_LSB_MASK:
643             return ImplConvertFromBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( rDst, rSrc );
644 
645         case BMP_FORMAT_24BIT_TC_BGR:
646             return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_BGR>( rDst, rSrc );
647         case BMP_FORMAT_24BIT_TC_RGB:
648             return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_RGB>( rDst, rSrc );
649 
650         case BMP_FORMAT_32BIT_TC_ABGR:
651             return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_ABGR>( rDst, rSrc );
652 #ifdef FAST_ARGB_BGRA
653         case BMP_FORMAT_32BIT_TC_ARGB:
654             return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_ARGB>( rDst, rSrc );
655         case BMP_FORMAT_32BIT_TC_BGRA:
656             return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_BGRA>( rDst, rSrc );
657 #endif
658         case BMP_FORMAT_32BIT_TC_RGBA:
659             return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_RGBA>( rDst, rSrc );
660     }
661 
662 #ifdef DEBUG
663     static int nNotAccelerated = 0;
664     if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
665 	{
666         if( ++nNotAccelerated == 100 )
667 		{
668 			int foo = 0; (void)foo; // so no warning is created when building on pro with debug
669             DBG_WARNING2( "ImplFastBitmapConversion for not accelerated case (0x%04X->0x%04X)", rSrc.mnFormat, rDst.mnFormat );
670 		}
671 	}
672 #endif
673 
674     return false;
675 }
676 
677 // =======================================================================
678 
679 template <sal_uLong DSTFMT,sal_uLong SRCFMT> //,sal_uLong MSKFMT>
680 bool ImplBlendToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine,
681     BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
682     const BitmapBuffer& rMskBuffer )
683 {
684     //DBG_ASSERT( rMskBuffer.mnFormat == MSKFMT, "FastBmp BlendImage: wrong MSKFMT" );
685     DBG_ASSERT( rMskBuffer.mnFormat == BMP_FORMAT_8BIT_PAL, "FastBmp BlendImage: unusual MSKFMT" );
686 
687     const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
688     int nMskLinestep = rMskBuffer.mnScanlineSize;
689     int nDstLinestep = rDstBuffer.mnScanlineSize;
690 
691     TrueColorPixelPtr<BMP_FORMAT_8BIT_PAL> aMskLine; aMskLine.SetRawPtr( rMskBuffer.mpBits );
692     TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
693 
694     // special case for single line masks
695     if( rMskBuffer.mnHeight == 1 )
696         nMskLinestep = 0;
697 
698     // source and mask don't match: upside down
699     if( (rSrcBuffer.mnFormat ^ rMskBuffer.mnFormat) & BMP_FORMAT_TOP_DOWN )
700     {
701         aMskLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nMskLinestep );
702         nMskLinestep = -nMskLinestep;
703     }
704 
705     // source and destination don't match: upside down
706     if( (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) & BMP_FORMAT_TOP_DOWN )
707     {
708         aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep );
709         nDstLinestep = -nDstLinestep;
710     }
711 
712     for( int y = rSrcBuffer.mnHeight; --y >= 0; )
713     {
714         ImplBlendLines<8>( aDstLine, rSrcLine, aMskLine, rDstBuffer.mnWidth );
715         aDstLine.AddByteOffset( nDstLinestep );
716         rSrcLine.AddByteOffset( nSrcLinestep );
717         aMskLine.AddByteOffset( nMskLinestep );
718     }
719 
720     return true;
721 }
722 
723 // some specializations to reduce the code size
724 template <>
725 inline bool ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_BGR,BMP_FORMAT_24BIT_TC_BGR>(
726     TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_BGR>&,
727     BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
728     const BitmapBuffer& rMskBuffer )
729  {
730     TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_RGB> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
731     return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
732  }
733 
734 template <>
735 inline bool ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ABGR,BMP_FORMAT_32BIT_TC_ABGR>(
736     TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ABGR>&,
737     BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
738     const BitmapBuffer& rMskBuffer )
739  {
740     TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ARGB> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
741     return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
742  }
743 
744 template <>
745 inline bool ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_BGRA,BMP_FORMAT_32BIT_TC_BGRA>(
746     TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_BGRA>&,
747     BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
748     const BitmapBuffer& rMskBuffer )
749  {
750     TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_RGBA> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
751     return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
752  }
753 
754 // -----------------------------------------------------------------------
755 
756 template <sal_uLong SRCFMT>
757 bool ImplBlendFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc, const BitmapBuffer& rMsk )
758 {
759     TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
760 
761     // select the matching instantiation for the destination's bitmap format
762     switch( rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN )
763     {
764         case BMP_FORMAT_1BIT_MSB_PAL:
765         case BMP_FORMAT_1BIT_LSB_PAL:
766         case BMP_FORMAT_4BIT_MSN_PAL:
767         case BMP_FORMAT_4BIT_LSN_PAL:
768         case BMP_FORMAT_8BIT_PAL:
769             break;
770 
771         case BMP_FORMAT_8BIT_TC_MASK:
772 //            return ImplBlendToBitmap<BMP_FORMAT_8BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk );
773         case BMP_FORMAT_24BIT_TC_MASK:
774 //            return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk );
775         case BMP_FORMAT_32BIT_TC_MASK:
776 //            return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk );
777             break;
778 
779         case BMP_FORMAT_16BIT_TC_MSB_MASK:
780             return ImplBlendToBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( aSrcType, rDst, rSrc, rMsk );
781         case BMP_FORMAT_16BIT_TC_LSB_MASK:
782             return ImplBlendToBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( aSrcType, rDst, rSrc, rMsk );
783 
784         case BMP_FORMAT_24BIT_TC_BGR:
785             return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_BGR>( aSrcType, rDst, rSrc, rMsk );
786         case BMP_FORMAT_24BIT_TC_RGB:
787             return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDst, rSrc, rMsk );
788 
789         case BMP_FORMAT_32BIT_TC_ABGR:
790             return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ABGR>( aSrcType, rDst, rSrc, rMsk );
791 #ifdef FAST_ARGB_BGRA
792         case BMP_FORMAT_32BIT_TC_ARGB:
793             return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDst, rSrc, rMsk );
794         case BMP_FORMAT_32BIT_TC_BGRA:
795             return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_BGRA>( aSrcType, rDst, rSrc, rMsk );
796 #endif
797         case BMP_FORMAT_32BIT_TC_RGBA:
798             return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDst, rSrc, rMsk );
799     }
800 
801 #ifdef DEBUG
802     static int nNotAccelerated = 0;
803     if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
804         if( ++nNotAccelerated == 100 )
805 		{
806 			int foo = 0; (void)foo; // so no warning is created when building on pro with debug
807             DBG_WARNING3( "ImplBlendFromBitmap for not accelerated case (0x%04X*0x%04X->0x%04X)",
808                 rSrc.mnFormat, rMsk.mnFormat, rDst.mnFormat );
809 		}
810 #endif
811 
812     return false;
813 }
814 
815 // -----------------------------------------------------------------------
816 
817 bool ImplFastBitmapBlending( BitmapWriteAccess& rDstWA,
818     const BitmapReadAccess& rSrcRA, const BitmapReadAccess& rMskRA,
819     const SalTwoRect& rTR )
820 {
821     if( bDisableFastBitops )
822         return false;
823 
824     // accelerated blending of paletted bitmaps not implemented yet
825     if( rSrcRA.HasPalette() )
826         return false;
827     if( rDstWA.HasPalette() )
828         return false;
829     // TODO: either get rid of mask's use of 8BIT_PAL or check the palette
830 
831     // horizontal mirroring not implemented yet
832     if( rTR.mnDestWidth < 0 )
833         return false;
834     // vertical mirroring
835     if( rTR.mnDestHeight < 0 )
836         // TODO: rDst.mnFormat ^= BMP_FORMAT_TOP_DOWN;
837         return false;
838 
839     // offseted blending is not implemented yet
840     if( rTR.mnSrcX || rTR.mnSrcY )
841         return false;
842     if( rTR.mnDestX || rTR.mnDestY )
843         return false;
844 
845     // stretched blending is not implemented yet
846     if( rTR.mnDestWidth != rTR.mnSrcWidth )
847         return false;
848     if( rTR.mnDestHeight!= rTR.mnSrcHeight )
849         return false;
850 
851     // check source image size
852     if( rSrcRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
853         return false;
854     if( rSrcRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
855         return false;
856 
857     // check mask image size
858     if( rMskRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
859         return false;
860     if( rMskRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
861         if( rMskRA.Height() != 1 )
862             return false;
863 
864     // check dest image size
865     if( rDstWA.Width() < rTR.mnDestX + rTR.mnDestWidth )
866         return false;
867     if( rDstWA.Height() < rTR.mnDestY + rTR.mnDestHeight )
868         return false;
869 
870     BitmapBuffer& rDst = *rDstWA.ImplGetBitmapBuffer();
871     const BitmapBuffer& rSrc = *rSrcRA.ImplGetBitmapBuffer();
872     const BitmapBuffer& rMsk = *rMskRA.ImplGetBitmapBuffer();
873 
874     const sal_uLong nSrcFormat = rSrc.mnFormat & ~BMP_FORMAT_TOP_DOWN;
875     const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN;
876 
877     // accelerated conversions for 16bit colormasks with non-565 format are not yet implemented
878     if( nSrcFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
879         if( rSrc.maColorMask.GetRedMask()  != 0xF800
880         ||  rSrc.maColorMask.GetGreenMask()!= 0x07E0
881         ||  rSrc.maColorMask.GetBlueMask() != 0x001F)
882             return false;
883     if( nDstFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
884         if( rDst.maColorMask.GetRedMask()  != 0xF800
885         ||  rDst.maColorMask.GetGreenMask()!= 0x07E0
886         ||  rDst.maColorMask.GetBlueMask() != 0x001F)
887             return false;
888 
889     // select the matching instantiation for the source's bitmap format
890     switch( nSrcFormat )
891     {
892         case BMP_FORMAT_1BIT_MSB_PAL:
893         case BMP_FORMAT_1BIT_LSB_PAL:
894         case BMP_FORMAT_4BIT_MSN_PAL:
895         case BMP_FORMAT_4BIT_LSN_PAL:
896         case BMP_FORMAT_8BIT_PAL:
897             break;
898 
899         case BMP_FORMAT_8BIT_TC_MASK:
900 //            return ImplBlendFromBitmap<BMP_FORMAT_8BIT_TC_MASK>( rDst, rSrc );
901         case BMP_FORMAT_24BIT_TC_MASK:
902 //            return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_MASK>( rDst, rSrc );
903         case BMP_FORMAT_32BIT_TC_MASK:
904 //            return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_MASK>( rDst, rSrc );
905             break;
906 
907         case BMP_FORMAT_16BIT_TC_MSB_MASK:
908             return ImplBlendFromBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( rDst, rSrc, rMsk );
909         case BMP_FORMAT_16BIT_TC_LSB_MASK:
910             return ImplBlendFromBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( rDst, rSrc, rMsk );
911 
912         case BMP_FORMAT_24BIT_TC_BGR:
913             return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_BGR>( rDst, rSrc, rMsk );
914         case BMP_FORMAT_24BIT_TC_RGB:
915             return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_RGB>( rDst, rSrc, rMsk );
916 
917         case BMP_FORMAT_32BIT_TC_ABGR:
918             return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_ABGR>( rDst, rSrc, rMsk );
919 #ifdef FAST_ARGB_BGRA
920         case BMP_FORMAT_32BIT_TC_ARGB:
921             return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_ARGB>( rDst, rSrc, rMsk );
922         case BMP_FORMAT_32BIT_TC_BGRA:
923             return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_BGRA>( rDst, rSrc, rMsk );
924 #endif
925         case BMP_FORMAT_32BIT_TC_RGBA:
926             return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_RGBA>( rDst, rSrc, rMsk );
927     }
928 
929 #ifdef DEBUG
930     static int nNotAccelerated = 0;
931     if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
932         if( ++nNotAccelerated == 100 )
933 		{
934 			int foo = 0; (void)foo; // so no warning is created when building on pro with debug
935             DBG_WARNING3( "ImplFastBlend for not accelerated case (0x%04X*0x%04X->0x%04X)",
936                 rSrc.mnFormat, rMsk.mnFormat, rDst.mnFormat );
937 		}
938 #endif
939 
940     return false;
941 }
942 
943 bool ImplFastEraseBitmap( BitmapBuffer& rDst, const BitmapColor& rColor )
944 {
945     if( bDisableFastBitops )
946         return false;
947 
948     const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN;
949 
950     // erasing a bitmap is often just a byte-wise memory fill
951     bool bByteFill = true;
952     sal_uInt8 nFillByte;
953 
954     switch( nDstFormat )
955     {
956         case BMP_FORMAT_1BIT_MSB_PAL:
957         case BMP_FORMAT_1BIT_LSB_PAL:
958             nFillByte = rColor.GetIndex();
959             nFillByte = static_cast<sal_uInt8>( -(nFillByte & 1) ); // 0x00 or 0xFF
960             break;
961         case BMP_FORMAT_4BIT_MSN_PAL:
962         case BMP_FORMAT_4BIT_LSN_PAL:
963             nFillByte = rColor.GetIndex();
964             nFillByte &= 0x0F;
965             nFillByte |= (nFillByte << 4);
966             break;
967         case BMP_FORMAT_8BIT_PAL:
968         case BMP_FORMAT_8BIT_TC_MASK:
969             nFillByte = rColor.GetIndex();
970             break;
971 
972         case BMP_FORMAT_24BIT_TC_MASK:
973         case BMP_FORMAT_24BIT_TC_BGR:
974         case BMP_FORMAT_24BIT_TC_RGB:
975             nFillByte = rColor.GetRed();
976             if( (nFillByte != rColor.GetGreen())
977             ||  (nFillByte != rColor.GetBlue()) )
978                 bByteFill = false;
979             break;
980 
981         default:
982             bByteFill = false;
983             nFillByte = 0x00;
984             break;
985     }
986 
987     if( bByteFill )
988     {
989         long nByteCount = rDst.mnHeight * rDst.mnScanlineSize;
990         rtl_fillMemory( rDst.mpBits, nByteCount, nFillByte );
991         return true;
992     }
993 
994     // TODO: handle other bitmap formats
995     switch( nDstFormat )
996     {
997         case BMP_FORMAT_32BIT_TC_MASK:
998         case BMP_FORMAT_16BIT_TC_MSB_MASK:
999         case BMP_FORMAT_16BIT_TC_LSB_MASK:
1000 
1001         case BMP_FORMAT_24BIT_TC_BGR:
1002         case BMP_FORMAT_24BIT_TC_RGB:
1003 
1004         case BMP_FORMAT_32BIT_TC_ABGR:
1005 #ifdef FAST_ARGB_BGRA
1006         case BMP_FORMAT_32BIT_TC_ARGB:
1007         case BMP_FORMAT_32BIT_TC_BGRA:
1008 #endif
1009         case BMP_FORMAT_32BIT_TC_RGBA:
1010             break;
1011 
1012         default:
1013             break;
1014     }
1015 
1016     return false;
1017 }
1018 
1019 // =======================================================================
1020 
1021 #else // NO_OPTIMIZED_BITMAP_ACCESS
1022 
1023 bool ImplFastBitmapConversion( BitmapBuffer&, const BitmapBuffer& )
1024 {
1025     return false;
1026 }
1027 
1028 bool ImplFastBitmapBlending( BitmapWriteAccess&,
1029     const BitmapReadAccess&, const BitmapReadAccess&,
1030     const Size&, const Point& )
1031 {
1032     return false;
1033 }
1034 
1035 bool ImplFastEraseBitmap( BitmapBuffer&, const BitmapColor& )
1036 {
1037     return false;
1038 }
1039 
1040 #endif
1041