xref: /AOO41X/main/vcl/source/gdi/bmpacc.cxx (revision 4b612aeb00e989a4e5c20dd116ea87dfa6f1a696)
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 <vcl/salbtype.hxx>
28 #include <vcl/bitmap.hxx>
29 #include <vcl/bmpacc.hxx>
30 
31 #include <impbmp.hxx>
32 
33 #include <string.h>
34 
35 // --------------------
36 // - BitmapReadAccess -
37 // --------------------
38 
BitmapReadAccess(Bitmap & rBitmap,sal_Bool bModify)39 BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap, sal_Bool bModify ) :
40             mpBuffer        ( NULL ),
41             mpScanBuf       ( NULL ),
42             mFncGetPixel    ( NULL ),
43             mFncSetPixel    ( NULL ),
44             mbModify        ( bModify )
45 {
46     ImplCreate( rBitmap );
47 }
48 
49 // ------------------------------------------------------------------
50 
BitmapReadAccess(Bitmap & rBitmap)51 BitmapReadAccess::BitmapReadAccess( Bitmap& rBitmap ) :
52             mpBuffer        ( NULL ),
53             mpScanBuf       ( NULL ),
54             mFncGetPixel    ( NULL ),
55             mFncSetPixel    ( NULL ),
56             mbModify        ( sal_False )
57 {
58     ImplCreate( rBitmap );
59 }
60 
61 // ------------------------------------------------------------------
62 
~BitmapReadAccess()63 BitmapReadAccess::~BitmapReadAccess()
64 {
65     ImplDestroy();
66 }
67 
68 // ------------------------------------------------------------------
69 
ImplCreate(Bitmap & rBitmap)70 void BitmapReadAccess::ImplCreate( Bitmap& rBitmap )
71 {
72     ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap();
73 
74     DBG_ASSERT( pImpBmp, "Forbidden Access to empty bitmap!" );
75 
76     if( pImpBmp )
77     {
78         if( mbModify && !maBitmap.ImplGetImpBitmap() )
79         {
80             rBitmap.ImplMakeUnique();
81             pImpBmp = rBitmap.ImplGetImpBitmap();
82         }
83         else
84         {
85             DBG_ASSERT( !mbModify || pImpBmp->ImplGetRefCount() == 2,
86                         "Unpredictable results: bitmap is referenced more than once!" );
87         }
88 
89         mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify );
90 
91         if( !mpBuffer )
92         {
93             ImpBitmap* pNewImpBmp = new ImpBitmap;
94 
95             if( pNewImpBmp->ImplCreate( *pImpBmp, rBitmap.GetBitCount()  ) )
96             {
97                 pImpBmp = pNewImpBmp;
98                 rBitmap.ImplSetImpBitmap( pImpBmp );
99                 mpBuffer = pImpBmp->ImplAcquireBuffer( !mbModify );
100             }
101             else
102                 delete pNewImpBmp;
103         }
104 
105         if( mpBuffer )
106         {
107             const long  nHeight = mpBuffer->mnHeight;
108             Scanline    pTmpLine = mpBuffer->mpBits;
109 
110             try {
111                 mpScanBuf = new Scanline[ nHeight ];
112             } catch (std::bad_alloc &) {
113                 mpScanBuf = NULL;
114             }
115             if (mpScanBuf) {
116                 maColorMask = mpBuffer->maColorMask;
117 
118                 if( BMP_SCANLINE_ADJUSTMENT( mpBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
119                 {
120                     for( long nY = 0L; nY < nHeight; nY++, pTmpLine += mpBuffer->mnScanlineSize )
121                         mpScanBuf[ nY ] = pTmpLine;
122                 }
123                 else
124                 {
125                     for( long nY = nHeight - 1; nY >= 0; nY--, pTmpLine += mpBuffer->mnScanlineSize )
126                         mpScanBuf[ nY ] = pTmpLine;
127                 }
128 
129                 if( !ImplSetAccessPointers( BMP_SCANLINE_FORMAT( mpBuffer->mnFormat ) ) )
130                 {
131                     delete[] mpScanBuf;
132                     mpScanBuf = NULL;
133 
134                     pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify );
135                     mpBuffer = NULL;
136                 }
137                 else
138                     maBitmap = rBitmap;
139             } else {
140                 pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify );
141                 mpBuffer = NULL;
142             }
143         }
144     }
145 }
146 
147 // ------------------------------------------------------------------
148 
ImplDestroy()149 void BitmapReadAccess::ImplDestroy()
150 {
151     ImpBitmap* pImpBmp = maBitmap.ImplGetImpBitmap();
152 
153     delete[] mpScanBuf;
154     mpScanBuf = NULL;
155 
156     if( mpBuffer && pImpBmp )
157     {
158         pImpBmp->ImplReleaseBuffer( mpBuffer, !mbModify );
159         mpBuffer = NULL;
160     }
161 }
162 
163 // ------------------------------------------------------------------
164 
ImplSetAccessPointers(sal_uLong nFormat)165 sal_Bool BitmapReadAccess::ImplSetAccessPointers( sal_uLong nFormat )
166 {
167     sal_Bool bRet = sal_True;
168 
169     switch( nFormat )
170     {
171         CASE_FORMAT( _1BIT_MSB_PAL )
172         CASE_FORMAT( _1BIT_LSB_PAL )
173         CASE_FORMAT( _4BIT_MSN_PAL )
174         CASE_FORMAT( _4BIT_LSN_PAL )
175         CASE_FORMAT( _8BIT_PAL )
176         CASE_FORMAT( _8BIT_TC_MASK )
177         CASE_FORMAT( _16BIT_TC_MSB_MASK )
178         CASE_FORMAT( _16BIT_TC_LSB_MASK )
179         CASE_FORMAT( _24BIT_TC_BGR )
180         CASE_FORMAT( _24BIT_TC_RGB )
181         CASE_FORMAT( _24BIT_TC_MASK )
182         CASE_FORMAT( _32BIT_TC_ABGR )
183         CASE_FORMAT( _32BIT_TC_ARGB )
184         CASE_FORMAT( _32BIT_TC_BGRA )
185         CASE_FORMAT( _32BIT_TC_RGBA )
186         CASE_FORMAT( _32BIT_TC_MASK )
187 
188         default:
189             bRet = sal_False;
190         break;
191     }
192 
193     return bRet;
194 }
195 
196 // ------------------------------------------------------------------
197 
ImplZeroInitUnusedBits()198 void BitmapReadAccess::ImplZeroInitUnusedBits()
199 {
200     const sal_uInt32 nWidth = Width(), nHeight = Height(), nScanSize = GetScanlineSize();
201 
202     if( nWidth && nHeight && nScanSize && GetBuffer() )
203     {
204         sal_uInt32 nBits;
205         bool       bMsb;
206 
207         const sal_uLong nScanlineFormat = GetScanlineFormat();
208         switch( nScanlineFormat )
209         {
210             case( BMP_FORMAT_1BIT_MSB_PAL ):
211                 nBits = 1;
212                 bMsb = true;
213                 break;
214 
215             case( BMP_FORMAT_1BIT_LSB_PAL ):
216                 nBits = 1;
217                 bMsb = false;
218                 break;
219 
220             case( BMP_FORMAT_4BIT_MSN_PAL ):
221                 nBits = 4;
222                 bMsb = true;
223                 break;
224 
225             case( BMP_FORMAT_4BIT_LSN_PAL ):
226                 nBits = 4;
227                 bMsb = false;
228                 break;
229 
230             case( BMP_FORMAT_8BIT_PAL ):
231             case( BMP_FORMAT_8BIT_TC_MASK ):
232                 bMsb = true;
233                 nBits = 8;
234             break;
235 
236             case( BMP_FORMAT_16BIT_TC_MSB_MASK ):
237             case( BMP_FORMAT_16BIT_TC_LSB_MASK ):
238                 bMsb = true;
239                 nBits = 16;
240             break;
241 
242             case( BMP_FORMAT_24BIT_TC_BGR ):
243             case( BMP_FORMAT_24BIT_TC_RGB ):
244             case( BMP_FORMAT_24BIT_TC_MASK ):
245                 bMsb = true;
246                 nBits = 24;
247             break;
248 
249             case( BMP_FORMAT_32BIT_TC_ABGR ):
250             case( BMP_FORMAT_32BIT_TC_ARGB ):
251             case( BMP_FORMAT_32BIT_TC_BGRA ):
252             case( BMP_FORMAT_32BIT_TC_RGBA ):
253             case( BMP_FORMAT_32BIT_TC_MASK ):
254                 bMsb = true;
255                 nBits = 32;
256             break;
257 
258             default:
259             {
260                 DBG_ERROR( "BitmapWriteAccess::ZeroInitUnusedBits: Unsupported pixel format");
261                 nBits = 0;
262                 bMsb = true;
263             }
264             break;
265         }
266 
267         nBits *= nWidth;
268         if( nScanSize % 4 || !bMsb )
269         {
270             DBG_ASSERT( 8*nScanSize >= nBits,
271                         "BitmapWriteAccess::ZeroInitUnusedBits: span size smaller than width?!");
272             const sal_uInt32 nLeftOverBits = 8*sizeof(sal_uInt8)*nScanSize - nBits;
273             if( nLeftOverBits != 0 ) // else there is really nothing to do
274             {
275                 const sal_uInt32 nBytes = (nLeftOverBits + 7U) >> 3U;
276                 sal_uInt8        nMask;
277 
278                 if( bMsb )
279                     nMask = static_cast<sal_uInt8>(0xffU << (nLeftOverBits & 3UL));
280                 else
281                     nMask = static_cast<sal_uInt8>(0xffU >> (nLeftOverBits & 3UL));
282 
283                 sal_uInt8* pLastBytes = (sal_uInt8*)GetBuffer() + ( nScanSize - nBytes );
284                 for( sal_uInt32 i = 0; i < nHeight; i++, pLastBytes += nScanSize )
285                 {
286                     *pLastBytes &= nMask;
287                     for( sal_uInt32 j = 1; j < nBytes; j++ )
288                         pLastBytes[j] = 0;
289                 }
290             }
291         }
292         else if( nBits & 0x1f )
293         {
294             sal_uInt32  nMask = 0xffffffff << ( ( nScanSize << 3 ) - nBits );
295             sal_uInt8*      pLast4Bytes = (sal_uInt8*) GetBuffer() + ( nScanSize - 4 );
296 
297 #ifdef OSL_LITENDIAN
298             nMask = SWAPLONG( nMask );
299 #endif
300             for( sal_uInt32 i = 0; i < nHeight; i++, pLast4Bytes += nScanSize )
301                 ( *(sal_uInt32*) pLast4Bytes ) &= nMask;
302         }
303     }
304 }
305 
306 // ------------------------------------------------------------------
307 
Flush()308 void BitmapReadAccess::Flush()
309 {
310     ImplDestroy();
311 }
312 
313 // ------------------------------------------------------------------
314 
ReAccess(sal_Bool bModify)315 void BitmapReadAccess::ReAccess( sal_Bool bModify )
316 {
317     const ImpBitmap* pImpBmp = maBitmap.ImplGetImpBitmap();
318 
319     DBG_ASSERT( !mpBuffer, "No ReAccess possible while bitmap is being accessed!" );
320     DBG_ASSERT( pImpBmp && ( pImpBmp->ImplGetRefCount() > 1UL ), "Accessed bitmap does not exist anymore!" );
321 
322     if( !mpBuffer && pImpBmp && ( pImpBmp->ImplGetRefCount() > 1UL ) )
323     {
324         mbModify = bModify;
325         ImplCreate( maBitmap );
326     }
327 }
328 
329 // ------------------------------------------------------------------
330 
GetBestPaletteIndex(const BitmapColor & rBitmapColor) const331 sal_uInt16 BitmapReadAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const
332 {
333     return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 );
334 }
335 
GetInterpolatedColorWithFallback(double fY,double fX,const BitmapColor & rFallback) const336 BitmapColor BitmapReadAccess::GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
337 {
338     // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
339     // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
340     if(mpBuffer && fX >= 0.0 && fY >= 0.0)
341     {
342         const sal_Int32 nX(static_cast< sal_Int32 >(fX));
343         const sal_Int32 nY(static_cast< sal_Int32 >(fY));
344 
345         if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
346         {
347             // get base-return value from inside pixel
348             BitmapColor aRetval(GetColor(nY, nX));
349 
350             // calculate deltas and indices for neighbour accesses
351             sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
352             sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
353             sal_Int16 nIndX(0);
354             sal_Int16 nIndY(0);
355 
356             if(nDeltaX > 0)
357             {
358                 nIndX = nX + 1;
359             }
360             else
361             {
362                 nIndX = nX - 1;
363                 nDeltaX = -nDeltaX;
364             }
365 
366             if(nDeltaY > 0)
367             {
368                 nIndY = nY + 1;
369             }
370             else
371             {
372                 nIndY = nY - 1;
373                 nDeltaY = -nDeltaY;
374             }
375 
376             // get right/left neighbour
377             BitmapColor aXCol(rFallback);
378 
379             if(nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
380             {
381                 aXCol = GetColor(nY, nIndX);
382             }
383 
384             // get top/bottom neighbour
385             BitmapColor aYCol(rFallback);
386 
387             if(nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
388             {
389                 aYCol = GetColor(nIndY, nX);
390             }
391 
392             // get one of four edge neighbours
393             BitmapColor aXYCol(rFallback);
394 
395             if(nDeltaX && nDeltaY && nIndX >=0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth && nIndY < mpBuffer->mnHeight)
396             {
397                 aXYCol = GetColor(nIndY, nIndX);
398             }
399 
400             // merge return value with right/left neighbour
401             if(aXCol != aRetval)
402             {
403                 aRetval.Merge(aXCol, 255 - nDeltaX);
404             }
405 
406             // merge top/bottom neighbour with edge
407             if(aYCol != aXYCol)
408             {
409                 aYCol.Merge(aXYCol, 255 - nDeltaX);
410             }
411 
412             // merge return value with already merged top/bottom neighbour
413             if(aRetval != aYCol)
414             {
415                 aRetval.Merge(aYCol, 255 - nDeltaY);
416             }
417 
418             return aRetval;
419         }
420     }
421 
422     return rFallback;
423 }
424 
GetColorWithFallback(double fY,double fX,const BitmapColor & rFallback) const425 BitmapColor BitmapReadAccess::GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
426 {
427     // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
428     // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
429     if(mpBuffer && fX >= 0.0 && fY >= 0.0)
430     {
431         const sal_Int32 nX(static_cast< sal_Int32 >(fX));
432         const sal_Int32 nY(static_cast< sal_Int32 >(fY));
433 
434         if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
435         {
436             return GetColor(nY, nX);
437         }
438     }
439 
440     return rFallback;
441 }
442 
GetColorWithFallback(long nY,long nX,const BitmapColor & rFallback) const443 BitmapColor BitmapReadAccess::GetColorWithFallback( long nY, long nX, const BitmapColor& rFallback ) const
444 {
445     if(mpBuffer)
446     {
447         if(nX >= 0 && nY >= 0 && nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
448         {
449             return GetColor(nY, nX);
450         }
451     }
452 
453     return rFallback;
454 }
455 
456 // ---------------------
457 // - BitmapWriteAccess -
458 // ---------------------
459 
BitmapWriteAccess(Bitmap & rBitmap)460 BitmapWriteAccess::BitmapWriteAccess( Bitmap& rBitmap ) :
461             BitmapReadAccess( rBitmap, sal_True ),
462             mpLineColor     ( NULL ),
463             mpFillColor     ( NULL )
464 {
465 }
466 
467 // ------------------------------------------------------------------
468 
~BitmapWriteAccess()469 BitmapWriteAccess::~BitmapWriteAccess()
470 {
471     delete mpLineColor;
472     delete mpFillColor;
473 }
474 
475 // ------------------------------------------------------------------
476 
CopyScanline(long nY,const BitmapReadAccess & rReadAcc)477 void BitmapWriteAccess::CopyScanline( long nY, const BitmapReadAccess& rReadAcc )
478 {
479     DBG_ASSERT( ( nY >= 0 ) && ( nY < mpBuffer->mnHeight ), "y-coordinate in destination out of range!" );
480     DBG_ASSERT( nY < rReadAcc.Height(), "y-coordinate in source out of range!" );
481     DBG_ASSERT( ( HasPalette() && rReadAcc.HasPalette() ) || ( !HasPalette() && !rReadAcc.HasPalette() ), "No copying possible between palette bitmap and TC bitmap!" );
482 
483     if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
484         ( GetScanlineSize() >= rReadAcc.GetScanlineSize() ) )
485     {
486         memcpy( mpScanBuf[ nY ], rReadAcc.GetScanline( nY ), rReadAcc.GetScanlineSize() );
487     }
488     else
489         // TODO: use fastbmp infrastructure
490         for( long nX = 0L, nWidth = Min( mpBuffer->mnWidth, rReadAcc.Width() ); nX < nWidth; nX++ )
491             SetPixel( nY, nX, rReadAcc.GetPixel( nY, nX ) );
492 }
493 
494 // ------------------------------------------------------------------
495 
CopyScanline(long nY,ConstScanline aSrcScanline,sal_uLong nSrcScanlineFormat,sal_uLong nSrcScanlineSize)496 void BitmapWriteAccess::CopyScanline( long nY, ConstScanline aSrcScanline,
497                                       sal_uLong nSrcScanlineFormat, sal_uLong nSrcScanlineSize )
498 {
499     const sal_uLong nFormat = BMP_SCANLINE_FORMAT( nSrcScanlineFormat );
500 
501     DBG_ASSERT( ( nY >= 0 ) && ( nY < mpBuffer->mnHeight ), "y-coordinate in destination out of range!" );
502     DBG_ASSERT( ( HasPalette() && nFormat <= BMP_FORMAT_8BIT_PAL ) ||
503                 ( !HasPalette() && nFormat > BMP_FORMAT_8BIT_PAL ),
504                 "No copying possible between palette and non palette scanlines!" );
505 
506     const sal_uLong nCount = Min( GetScanlineSize(), nSrcScanlineSize );
507 
508     if( nCount )
509     {
510         if( GetScanlineFormat() == BMP_SCANLINE_FORMAT( nSrcScanlineFormat ) )
511             memcpy( mpScanBuf[ nY ], aSrcScanline, nCount );
512         else
513         {
514             DBG_ASSERT( nFormat != BMP_FORMAT_8BIT_TC_MASK &&
515                         nFormat != BMP_FORMAT_16BIT_TC_MSB_MASK && nFormat != BMP_FORMAT_16BIT_TC_LSB_MASK &&
516                         nFormat != BMP_FORMAT_24BIT_TC_MASK && nFormat != BMP_FORMAT_32BIT_TC_MASK,
517                         "No support for pixel formats with color masks yet!" );
518 
519             // TODO: use fastbmp infrastructure
520             FncGetPixel pFncGetPixel;
521 
522             switch( nFormat )
523             {
524                 case( BMP_FORMAT_1BIT_MSB_PAL ):    pFncGetPixel = GetPixelFor_1BIT_MSB_PAL; break;
525                 case( BMP_FORMAT_1BIT_LSB_PAL ):    pFncGetPixel = GetPixelFor_1BIT_LSB_PAL; break;
526                 case( BMP_FORMAT_4BIT_MSN_PAL ):    pFncGetPixel = GetPixelFor_4BIT_MSN_PAL; break;
527                 case( BMP_FORMAT_4BIT_LSN_PAL ):    pFncGetPixel = GetPixelFor_4BIT_LSN_PAL; break;
528                 case( BMP_FORMAT_8BIT_PAL ):        pFncGetPixel = GetPixelFor_8BIT_PAL; break;
529                 case( BMP_FORMAT_8BIT_TC_MASK ):    pFncGetPixel = GetPixelFor_8BIT_TC_MASK; break;
530                 case( BMP_FORMAT_16BIT_TC_MSB_MASK ):   pFncGetPixel = GetPixelFor_16BIT_TC_MSB_MASK; break;
531                 case( BMP_FORMAT_16BIT_TC_LSB_MASK ):   pFncGetPixel = GetPixelFor_16BIT_TC_LSB_MASK; break;
532                 case( BMP_FORMAT_24BIT_TC_BGR ):    pFncGetPixel = GetPixelFor_24BIT_TC_BGR; break;
533                 case( BMP_FORMAT_24BIT_TC_RGB ):    pFncGetPixel = GetPixelFor_24BIT_TC_RGB; break;
534                 case( BMP_FORMAT_24BIT_TC_MASK ):   pFncGetPixel = GetPixelFor_24BIT_TC_MASK; break;
535                 case( BMP_FORMAT_32BIT_TC_ABGR ):   pFncGetPixel = GetPixelFor_32BIT_TC_ABGR; break;
536                 case( BMP_FORMAT_32BIT_TC_ARGB ):   pFncGetPixel = GetPixelFor_32BIT_TC_ARGB; break;
537                 case( BMP_FORMAT_32BIT_TC_BGRA ):   pFncGetPixel = GetPixelFor_32BIT_TC_BGRA; break;
538                 case( BMP_FORMAT_32BIT_TC_RGBA ):   pFncGetPixel = GetPixelFor_32BIT_TC_RGBA; break;
539                 case( BMP_FORMAT_32BIT_TC_MASK ):   pFncGetPixel = GetPixelFor_32BIT_TC_MASK; break;
540 
541                 default:
542                     pFncGetPixel = NULL;
543                 break;
544             }
545 
546             if( pFncGetPixel )
547             {
548                 const ColorMask aDummyMask;
549 
550                 for( long nX = 0L, nWidth = mpBuffer->mnWidth; nX < nWidth; nX++ )
551                     SetPixel( nY, nX, pFncGetPixel( aSrcScanline, nX, aDummyMask ) );
552             }
553         }
554     }
555 }
556 
557 
558 // ------------------------------------------------------------------
559 
CopyBuffer(const BitmapReadAccess & rReadAcc)560 void BitmapWriteAccess::CopyBuffer( const BitmapReadAccess& rReadAcc )
561 {
562     DBG_ASSERT( ( HasPalette() && rReadAcc.HasPalette() ) || ( !HasPalette() && !rReadAcc.HasPalette() ), "No copying possible between palette bitmap and TC bitmap!" );
563 
564     if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
565         ( GetScanlineSize() == rReadAcc.GetScanlineSize() ) )
566     {
567         const long  nHeight = Min( mpBuffer->mnHeight, rReadAcc.Height() );
568         const sal_uLong nCount = nHeight * mpBuffer->mnScanlineSize;
569 
570         memcpy( mpBuffer->mpBits, rReadAcc.GetBuffer(), nCount );
571     }
572     else
573         for( long nY = 0L, nHeight = Min( mpBuffer->mnHeight, rReadAcc.Height() ); nY < nHeight; nY++ )
574             CopyScanline( nY, rReadAcc );
575 }
576