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