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