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