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 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 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 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 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 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 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 ) 433 { 434 const double fFactorX = ( nDstDX > 1 ) ? (double) ( nSrcDX - 1 ) / ( nDstDX - 1 ) : 0.0; 435 436 for( i = 0L; i < nDstDX; i++ ) 437 pMapX[ i ] = nSrcX + FRound( 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 ) 447 { 448 const double fFactorY = ( nDstDY > 1 ) ? (double) ( nSrcDY - 1 ) / ( nDstDY - 1 ) : 0.0; 449 450 for( i = 0L; i < nDstDY; i++ ) 451 pMapY[ i ] = nSrcY + FRound( 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