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