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