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 #include <rtl/memory.h>
27 #include <vcl/bmpacc.hxx>
28 #include <vcl/salbtype.hxx>
29 #include <bmpfast.hxx>
30
31 // -----------
32 // - Defines -
33 // -----------
34
35 #define IMPL_CASE_GET_FORMAT( Format ) \
36 case( BMP_FORMAT##Format ): \
37 pFncGetPixel = BitmapReadAccess::GetPixelFor##Format; \
38 break
39
40 // -----------------------------------------------------------------------------
41
42 #define IMPL_CASE_SET_FORMAT( Format, BitCount ) \
43 case( BMP_FORMAT##Format ): \
44 { \
45 pFncSetPixel = BitmapReadAccess::SetPixelFor##Format; \
46 pDstBuffer->mnBitCount = BitCount; \
47 } \
48 break
49
50 // -----------------------------------------------------------------------------
51
52 #define DOUBLE_SCANLINES() \
53 while( ( nActY < nHeight1 ) && ( pMapY[ nActY + 1 ] == nMapY ) ) \
54 { \
55 memcpy( pDstScanMap[ nActY + 1L ], pDstScan, rDstBuffer.mnScanlineSize ); \
56 nActY++; \
57 }
58
59 // -----------
60 // - Inlines -
61 // -----------
62
63 #define TC_TO_PAL_COLORS 4096
64
ImplIndexFromColor(const BitmapColor & rCol)65 static long ImplIndexFromColor( const BitmapColor& rCol )
66 {
67 #if TC_TO_PAL_COLORS == 4096
68
69 return( ( ( (long) rCol.GetBlue() >> 4L) << 8L ) |
70 ( ( (long) rCol.GetGreen() >> 4L ) << 4L ) |
71 ( (long) rCol.GetRed() >> 4L ) );
72
73 #elif TC_TO_PAL_COLORS == 32768
74
75 return( ( ( (long) rCol.GetBlue() >> 3L) << 10L ) |
76 ( ( (long) rCol.GetGreen() >> 3L ) << 5L ) |
77 ( (long) rCol.GetRed() >> 3L ) );
78
79 #endif
80 }
81
82
83 #define COLOR_TO_INDEX( _def_rCol )
84
85 // ------------------------
86 // - conversion functions -
87 // ------------------------
88
ImplPALToPAL(const BitmapBuffer & rSrcBuffer,BitmapBuffer & rDstBuffer,FncGetPixel pFncGetPixel,FncSetPixel pFncSetPixel,Scanline * pSrcScanMap,Scanline * pDstScanMap,long * pMapX,long * pMapY)89 static void ImplPALToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
90 FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
91 Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
92 {
93 const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
94 const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
95 const ColorMask& rDstMask = rDstBuffer.maColorMask;
96 BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
97 BitmapColor* pColMapBuf = aColMap.ImplGetColorBuffer();
98 BitmapColor aIndex( 0 );
99
100 for( sal_uInt16 i = 0, nSrcCount = aColMap.GetEntryCount(), nDstCount = rDstBuffer.maPalette.GetEntryCount(); i < nSrcCount; i++ )
101 {
102 if( ( i < nDstCount ) && ( rSrcBuffer.maPalette[ i ] == rDstBuffer.maPalette[ i ] ) )
103 aIndex.SetIndex( sal::static_int_cast<sal_uInt8>(i) );
104 else
105 aIndex.SetIndex( sal::static_int_cast<sal_uInt8>(rDstBuffer.maPalette.GetBestIndex( rSrcBuffer.maPalette[ i ] )) );
106
107 pColMapBuf[ i ] = aIndex;
108 }
109
110 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
111 {
112 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
113
114 for( long nX = 0L; nX < nWidth; nX++ )
115 pFncSetPixel( pDstScan, nX, pColMapBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
116
117 DOUBLE_SCANLINES();
118 }
119 }
120
121 // -----------------------------------------------------------------------------
122
ImplPALToTC(const BitmapBuffer & rSrcBuffer,BitmapBuffer & rDstBuffer,FncGetPixel pFncGetPixel,FncSetPixel pFncSetPixel,Scanline * pSrcScanMap,Scanline * pDstScanMap,long * pMapX,long * pMapY)123 static void ImplPALToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
124 FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
125 Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
126 {
127 const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
128 const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
129 const ColorMask& rDstMask = rDstBuffer.maColorMask;
130 const BitmapColor* pColBuf = rSrcBuffer.maPalette.ImplGetColorBuffer();
131
132 if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_1BIT_MSB_PAL )
133 {
134 const BitmapColor aCol0( pColBuf[ 0 ] );
135 const BitmapColor aCol1( pColBuf[ 1 ] );
136 long nMapX;
137
138 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
139 {
140 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
141
142 for( long nX = 0L; nX < nWidth; )
143 {
144 nMapX = pMapX[ nX ];
145 pFncSetPixel( pDstScan, nX++,
146 pSrcScan[ nMapX >> 3 ] & ( 1 << ( 7 - ( nMapX & 7 ) ) ) ? aCol1 : aCol0,
147 rDstMask );
148 }
149
150 DOUBLE_SCANLINES();
151 }
152 }
153 else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_4BIT_MSN_PAL )
154 {
155 long nMapX;
156
157 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
158 {
159 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
160
161 for( long nX = 0L; nX < nWidth; )
162 {
163 nMapX = pMapX[ nX ];
164 pFncSetPixel( pDstScan, nX++,
165 pColBuf[ ( pSrcScan[ nMapX >> 1 ] >> ( nMapX & 1 ? 0 : 4 ) ) & 0x0f ],
166 rDstMask );
167 }
168
169 DOUBLE_SCANLINES();
170 }
171 }
172 else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_8BIT_PAL )
173 {
174 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
175 {
176 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
177
178 for( long nX = 0L; nX < nWidth; nX++ )
179 pFncSetPixel( pDstScan, nX, pColBuf[ pSrcScan[ pMapX[ nX ] ] ], rDstMask );
180
181 DOUBLE_SCANLINES();
182 }
183 }
184 else
185 {
186 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
187 {
188 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
189
190 for( long nX = 0L; nX < nWidth; nX++ )
191 pFncSetPixel( pDstScan, nX, pColBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
192
193 DOUBLE_SCANLINES();
194 }
195 }
196 }
197
198 // -----------------------------------------------------------------------------
199
ImplTCToTC(const BitmapBuffer & rSrcBuffer,BitmapBuffer & rDstBuffer,FncGetPixel pFncGetPixel,FncSetPixel pFncSetPixel,Scanline * pSrcScanMap,Scanline * pDstScanMap,long * pMapX,long * pMapY)200 static void ImplTCToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
201 FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
202 Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
203 {
204 const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
205 const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
206 const ColorMask& rDstMask = rDstBuffer.maColorMask;
207
208 if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_24BIT_TC_BGR )
209 {
210 BitmapColor aCol;
211 sal_uInt8* pPixel;
212
213 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
214 {
215 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
216
217 for( long nX = 0L; nX < nWidth; nX++ )
218 {
219 aCol.SetBlue( *( pPixel = ( pSrcScan + pMapX[ nX ] * 3 ) )++ );
220 aCol.SetGreen( *pPixel++ );
221 aCol.SetRed( *pPixel );
222 pFncSetPixel( pDstScan, nX, aCol, rDstMask );
223 }
224
225 DOUBLE_SCANLINES()
226 }
227 }
228 else
229 {
230 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
231 {
232 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
233
234 for( long nX = 0L; nX < nWidth; nX++ )
235 pFncSetPixel( pDstScan, nX, pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ), rDstMask );
236
237 DOUBLE_SCANLINES();
238 }
239 }
240 }
241
242 // -----------------------------------------------------------------------------
243
ImplTCToPAL(const BitmapBuffer & rSrcBuffer,BitmapBuffer & rDstBuffer,FncGetPixel pFncGetPixel,FncSetPixel pFncSetPixel,Scanline * pSrcScanMap,Scanline * pDstScanMap,long * pMapX,long * pMapY)244 static void ImplTCToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
245 FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
246 Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
247 {
248 const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
249 const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
250 const ColorMask& rDstMask = rDstBuffer.maColorMask;
251 BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
252 sal_uInt8* pColToPalMap = new sal_uInt8[ TC_TO_PAL_COLORS ];
253 BitmapColor aIndex( 0 );
254
255 for( long nR = 0; nR < 16; nR++ )
256 {
257 for( long nG = 0; nG < 16; nG++ )
258 {
259 for( long nB = 0; nB < 16; nB++ )
260 {
261 BitmapColor aCol( sal::static_int_cast<sal_uInt8>(nR << 4),
262 sal::static_int_cast<sal_uInt8>(nG << 4),
263 sal::static_int_cast<sal_uInt8>(nB << 4) );
264 pColToPalMap[ ImplIndexFromColor( aCol ) ] = (sal_uInt8) rDstBuffer.maPalette.GetBestIndex( aCol );
265 }
266 }
267 }
268
269 for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
270 {
271 Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
272
273 for( long nX = 0L; nX < nWidth; nX++ )
274 {
275 aIndex.SetIndex( pColToPalMap[ ImplIndexFromColor( pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ) ) ] );
276 pFncSetPixel( pDstScan, nX, aIndex, rDstMask );
277 }
278
279 DOUBLE_SCANLINES();
280 }
281
282 delete[] pColToPalMap;
283 }
284
285 // -----------------------------------------------------------------------------
286
287 // ---------------------
288 // - StretchAndConvert -
289 // ---------------------
290
StretchAndConvert(const BitmapBuffer & rSrcBuffer,const SalTwoRect & rTwoRect,sal_uLong nDstBitmapFormat,const BitmapPalette * pDstPal,const ColorMask * pDstMask)291 BitmapBuffer* StretchAndConvert(
292 const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect,
293 sal_uLong nDstBitmapFormat, const BitmapPalette* pDstPal, const ColorMask* pDstMask )
294 {
295 FncGetPixel pFncGetPixel;
296 FncSetPixel pFncSetPixel;
297 BitmapBuffer* pDstBuffer = new BitmapBuffer;
298 long i;
299
300 // set function for getting pixels
301 switch( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) )
302 {
303 IMPL_CASE_GET_FORMAT( _1BIT_MSB_PAL );
304 IMPL_CASE_GET_FORMAT( _1BIT_LSB_PAL );
305 IMPL_CASE_GET_FORMAT( _4BIT_MSN_PAL );
306 IMPL_CASE_GET_FORMAT( _4BIT_LSN_PAL );
307 IMPL_CASE_GET_FORMAT( _8BIT_PAL );
308 IMPL_CASE_GET_FORMAT( _8BIT_TC_MASK );
309 IMPL_CASE_GET_FORMAT( _16BIT_TC_MSB_MASK );
310 IMPL_CASE_GET_FORMAT( _16BIT_TC_LSB_MASK );
311 IMPL_CASE_GET_FORMAT( _24BIT_TC_BGR );
312 IMPL_CASE_GET_FORMAT( _24BIT_TC_RGB );
313 IMPL_CASE_GET_FORMAT( _24BIT_TC_MASK );
314 IMPL_CASE_GET_FORMAT( _32BIT_TC_ABGR );
315 IMPL_CASE_GET_FORMAT( _32BIT_TC_ARGB );
316 IMPL_CASE_GET_FORMAT( _32BIT_TC_BGRA );
317 IMPL_CASE_GET_FORMAT( _32BIT_TC_RGBA );
318 IMPL_CASE_GET_FORMAT( _32BIT_TC_MASK );
319
320 default:
321 // should never come here
322 // initialize pFncGetPixel to something valid that is
323 // least likely to crash
324 pFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL;
325 DBG_ERROR( "unknown read format" );
326 break;
327 }
328
329 // set function for setting pixels
330 const sal_uLong nDstScanlineFormat = BMP_SCANLINE_FORMAT( nDstBitmapFormat );
331 switch( nDstScanlineFormat )
332 {
333 IMPL_CASE_SET_FORMAT( _1BIT_MSB_PAL, 1 );
334 IMPL_CASE_SET_FORMAT( _1BIT_LSB_PAL, 1 );
335 IMPL_CASE_SET_FORMAT( _4BIT_MSN_PAL, 1 );
336 IMPL_CASE_SET_FORMAT( _4BIT_LSN_PAL, 4 );
337 IMPL_CASE_SET_FORMAT( _8BIT_PAL, 8 );
338 IMPL_CASE_SET_FORMAT( _8BIT_TC_MASK, 8 );
339 IMPL_CASE_SET_FORMAT( _16BIT_TC_MSB_MASK, 16 );
340 IMPL_CASE_SET_FORMAT( _16BIT_TC_LSB_MASK, 16 );
341 IMPL_CASE_SET_FORMAT( _24BIT_TC_BGR, 24 );
342 IMPL_CASE_SET_FORMAT( _24BIT_TC_RGB, 24 );
343 IMPL_CASE_SET_FORMAT( _24BIT_TC_MASK, 24 );
344 IMPL_CASE_SET_FORMAT( _32BIT_TC_ABGR, 32 );
345 IMPL_CASE_SET_FORMAT( _32BIT_TC_ARGB, 32 );
346 IMPL_CASE_SET_FORMAT( _32BIT_TC_BGRA, 32 );
347 IMPL_CASE_SET_FORMAT( _32BIT_TC_RGBA, 32 );
348 IMPL_CASE_SET_FORMAT( _32BIT_TC_MASK, 32 );
349
350 default:
351 // should never come here
352 // initialize pFncSetPixel to something valid that is
353 // least likely to crash
354 pFncSetPixel = BitmapReadAccess::SetPixelFor_1BIT_MSB_PAL;
355 pDstBuffer->mnBitCount = 1;
356 DBG_ERROR( "unknown write format" );
357 break;
358 }
359
360 // fill destination buffer
361 pDstBuffer->mnFormat = nDstBitmapFormat;
362 pDstBuffer->mnWidth = rTwoRect.mnDestWidth;
363 pDstBuffer->mnHeight = rTwoRect.mnDestHeight;
364 pDstBuffer->mnScanlineSize = AlignedWidth4Bytes( pDstBuffer->mnBitCount * pDstBuffer->mnWidth );
365 try
366 {
367 pDstBuffer->mpBits = new sal_uInt8[ pDstBuffer->mnScanlineSize * pDstBuffer->mnHeight ];
368 }
369 catch( const std::bad_alloc& )
370 {
371 // memory exception, clean up
372 pDstBuffer->mpBits = NULL;
373 delete pDstBuffer;
374 return NULL;
375 }
376
377 // do we need a destination palette or color mask?
378 if( ( nDstScanlineFormat == BMP_FORMAT_1BIT_MSB_PAL ) ||
379 ( nDstScanlineFormat == BMP_FORMAT_1BIT_LSB_PAL ) ||
380 ( nDstScanlineFormat == BMP_FORMAT_4BIT_MSN_PAL ) ||
381 ( nDstScanlineFormat == BMP_FORMAT_4BIT_LSN_PAL ) ||
382 ( nDstScanlineFormat == BMP_FORMAT_8BIT_PAL ) )
383 {
384 DBG_ASSERT( pDstPal, "destination buffer requires palette" );
385 pDstBuffer->maPalette = *pDstPal;
386 }
387 else if( ( nDstScanlineFormat == BMP_FORMAT_8BIT_TC_MASK ) ||
388 ( nDstScanlineFormat == BMP_FORMAT_16BIT_TC_MSB_MASK ) ||
389 ( nDstScanlineFormat == BMP_FORMAT_16BIT_TC_LSB_MASK ) ||
390 ( nDstScanlineFormat == BMP_FORMAT_24BIT_TC_MASK ) ||
391 ( nDstScanlineFormat == BMP_FORMAT_32BIT_TC_MASK ) )
392 {
393 DBG_ASSERT( pDstMask, "destination buffer requires color mask" );
394 pDstBuffer->maColorMask = *pDstMask;
395 }
396
397 // short circuit the most important conversions
398 bool bFastConvert = ImplFastBitmapConversion( *pDstBuffer, rSrcBuffer, rTwoRect );
399 if( bFastConvert )
400 return pDstBuffer;
401
402 const long nSrcX = rTwoRect.mnSrcX, nSrcY = rTwoRect.mnSrcY;
403 const long nSrcDX = rTwoRect.mnSrcWidth, nSrcDY = rTwoRect.mnSrcHeight;
404 const long nDstDX = rTwoRect.mnDestWidth, nDstDY = rTwoRect.mnDestHeight;
405 Scanline* pSrcScan = NULL;
406 Scanline* pDstScan = NULL;
407 long* pMapX = NULL;
408 long* pMapY = NULL;
409 long nTmp, nOffset;
410
411 try
412 {
413 pSrcScan = new Scanline[ rSrcBuffer.mnHeight ];
414 pDstScan = new Scanline[ nDstDY ];
415 pMapX = new long[ nDstDX ];
416 pMapY = new long[ nDstDY ];
417 }
418 catch( const std::bad_alloc& )
419 {
420 // memory exception, clean up
421 // remark: the buffer ptr causing the exception
422 // is still NULL here
423 delete[] pSrcScan;
424 delete[] pDstScan;
425 delete[] pMapX;
426 delete[] pMapY;
427 delete pDstBuffer;
428 return NULL;
429 }
430
431 // horizontal mapping table
432 if( (nDstDX != nSrcDX) && (nDstDX != 0) )
433 {
434 const double fFactorX = (double)nSrcDX / nDstDX;
435
436 for( i = 0L; i < nDstDX; i++ )
437 pMapX[ i ] = nSrcX + static_cast<int>( i * fFactorX );
438 }
439 else
440 {
441 for( i = 0L, nTmp = nSrcX; i < nDstDX; i++ )
442 pMapX[ i ] = nTmp++;
443 }
444
445 // vertical mapping table
446 if( (nDstDY != nSrcDY) && (nDstDY != 0) )
447 {
448 const double fFactorY = (double)nSrcDY / nDstDY;
449
450 for( i = 0L; i < nDstDY; i++ )
451 pMapY[ i ] = nSrcY + static_cast<int>( i * fFactorY );
452 }
453 else
454 {
455 for( i = 0L, nTmp = nSrcY; i < nDstDY; i++ )
456 pMapY[ i ] = nTmp++;
457 }
458
459 // source scanline buffer
460 Scanline pTmpScan;
461 if( BMP_SCANLINE_ADJUSTMENT( rSrcBuffer.mnFormat ) == BMP_FORMAT_TOP_DOWN )
462 pTmpScan = rSrcBuffer.mpBits, nOffset = rSrcBuffer.mnScanlineSize;
463 else
464 {
465 pTmpScan = rSrcBuffer.mpBits + ( rSrcBuffer.mnHeight - 1 ) * rSrcBuffer.mnScanlineSize;
466 nOffset = -rSrcBuffer.mnScanlineSize;
467 }
468
469 for( i = 0L; i < rSrcBuffer.mnHeight; i++, pTmpScan += nOffset )
470 pSrcScan[ i ] = pTmpScan;
471
472 // destination scanline buffer
473 if( BMP_SCANLINE_ADJUSTMENT( pDstBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
474 pTmpScan = pDstBuffer->mpBits, nOffset = pDstBuffer->mnScanlineSize;
475 else
476 {
477 pTmpScan = pDstBuffer->mpBits + ( nDstDY - 1 ) * pDstBuffer->mnScanlineSize;
478 nOffset = -pDstBuffer->mnScanlineSize;
479 }
480
481 for( i = 0L; i < nDstDY; i++, pTmpScan += nOffset )
482 pDstScan[ i ] = pTmpScan;
483
484 // do buffer scaling and conversion
485 if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount <= 8 )
486 {
487 ImplPALToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
488 pSrcScan, pDstScan, pMapX, pMapY );
489 }
490 else if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount > 8 )
491 {
492 ImplPALToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
493 pSrcScan, pDstScan, pMapX, pMapY );
494 }
495 else if( rSrcBuffer.mnBitCount > 8 && pDstBuffer->mnBitCount > 8 )
496 {
497 ImplTCToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
498 pSrcScan, pDstScan, pMapX, pMapY );
499 }
500 else
501 {
502 ImplTCToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
503 pSrcScan, pDstScan, pMapX, pMapY );
504 }
505
506 // cleanup
507 delete[] pSrcScan;
508 delete[] pDstScan;
509 delete[] pMapX;
510 delete[] pMapY;
511
512 return pDstBuffer;
513 }
514