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 : :
30 : : #include <bmpfast.hxx>
31 : :
32 : : #ifndef NO_OPTIMIZED_BITMAP_ACCESS
33 : :
34 : : #include <tools/debug.hxx>
35 : : #include <vcl/bmpacc.hxx>
36 : :
37 : : #define FAST_ARGB_BGRA
38 : :
39 : : #include <stdlib.h>
40 : :
41 : : typedef unsigned char PIXBYTE;
42 : :
43 : : class BasePixelPtr
44 : : {
45 : : public:
46 : 407200 : BasePixelPtr( PIXBYTE* p = NULL ) : mpPixel( p ) {}
47 : 407200 : void SetRawPtr( PIXBYTE* pRawPtr ) { mpPixel = pRawPtr; }
48 : 0 : PIXBYTE* GetRawPtr( void ) const { return mpPixel; }
49 : 7351770 : void AddByteOffset( int nByteOffset ) { mpPixel += nByteOffset; }
50 : : bool operator<( const BasePixelPtr& rCmp ) const { return (mpPixel < rCmp.mpPixel); }
51 : :
52 : : protected:
53 : : PIXBYTE* mpPixel;
54 : : };
55 : :
56 : : template <sal_uLong PIXFMT>
57 : : class TrueColorPixelPtr : public BasePixelPtr
58 : : {
59 : : public:
60 : : PIXBYTE GetRed() const;
61 : : PIXBYTE GetGreen() const;
62 : : PIXBYTE GetBlue() const;
63 : : PIXBYTE GetAlpha() const;
64 : :
65 : : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const;
66 : : void SetAlpha( PIXBYTE a ) const;
67 : : void operator++(int);
68 : : };
69 : :
70 : : // =======================================================================
71 : : // template specializations for truecolor pixel formats
72 : :
73 : : template <>
74 : 203600 : class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_RGB> : public BasePixelPtr
75 : : {
76 : : public:
77 : 136842872 : void operator++() { mpPixel += 3; }
78 : :
79 : 95280116 : PIXBYTE GetRed() const { return mpPixel[0]; }
80 : 95280116 : PIXBYTE GetGreen() const { return mpPixel[1]; }
81 : 95280116 : PIXBYTE GetBlue() const { return mpPixel[2]; }
82 : 18024756 : PIXBYTE GetAlpha() const { return 0; }
83 : 18024756 : void SetAlpha( PIXBYTE ) const {}
84 : :
85 : 56652436 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
86 : : {
87 : 56652436 : mpPixel[0] = r;
88 : 56652436 : mpPixel[1] = g;
89 : 56652436 : mpPixel[2] = b;
90 : 56652436 : }
91 : : };
92 : :
93 : : template <>
94 : 101800 : class TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_BGR> : public BasePixelPtr
95 : : {
96 : : public:
97 : 0 : void operator++() { mpPixel += 3; }
98 : :
99 : 0 : PIXBYTE GetRed() const { return mpPixel[2]; }
100 : 0 : PIXBYTE GetGreen() const { return mpPixel[1]; }
101 : 0 : PIXBYTE GetBlue() const { return mpPixel[0]; }
102 : 0 : PIXBYTE GetAlpha() const { return 0; }
103 : 0 : void SetAlpha( PIXBYTE ) const {}
104 : :
105 : 0 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
106 : : {
107 : 0 : mpPixel[0] = b;
108 : 0 : mpPixel[1] = g;
109 : 0 : mpPixel[2] = r;
110 : 0 : }
111 : : };
112 : :
113 : : template <>
114 : 0 : class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ARGB> : public BasePixelPtr
115 : : {
116 : : public:
117 : 0 : void operator++() { mpPixel += 4; }
118 : :
119 : 0 : PIXBYTE GetRed() const { return mpPixel[1]; }
120 : 0 : PIXBYTE GetGreen() const { return mpPixel[2]; }
121 : 0 : PIXBYTE GetBlue() const { return mpPixel[3]; }
122 : 0 : PIXBYTE GetAlpha() const { return mpPixel[0]; }
123 : 0 : void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
124 : :
125 : 0 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
126 : : {
127 : 0 : mpPixel[1] = r;
128 : 0 : mpPixel[2] = g;
129 : 0 : mpPixel[3] = b;
130 : 0 : }
131 : : };
132 : :
133 : : template <>
134 : 0 : class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ABGR> : public BasePixelPtr
135 : : {
136 : : public:
137 : 0 : void operator++() { mpPixel += 4; }
138 : :
139 : 0 : PIXBYTE GetRed() const { return mpPixel[3]; }
140 : 0 : PIXBYTE GetGreen() const { return mpPixel[2]; }
141 : 0 : PIXBYTE GetBlue() const { return mpPixel[1]; }
142 : 0 : PIXBYTE GetAlpha() const { return mpPixel[0]; }
143 : 0 : void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
144 : :
145 : 0 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
146 : : {
147 : 0 : mpPixel[1] = b;
148 : 0 : mpPixel[2] = g;
149 : 0 : mpPixel[3] = r;
150 : 0 : }
151 : : };
152 : :
153 : : template <>
154 : 0 : class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_RGBA> : public BasePixelPtr
155 : : {
156 : : public:
157 : 0 : void operator++() { mpPixel += 4; }
158 : :
159 : 0 : PIXBYTE GetRed() const { return mpPixel[0]; }
160 : 0 : PIXBYTE GetGreen() const { return mpPixel[1]; }
161 : 0 : PIXBYTE GetBlue() const { return mpPixel[2]; }
162 : 0 : PIXBYTE GetAlpha() const { return mpPixel[3]; }
163 : 0 : void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
164 : :
165 : 0 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
166 : : {
167 : 0 : mpPixel[0] = r;
168 : 0 : mpPixel[1] = g;
169 : 0 : mpPixel[2] = b;
170 : 0 : }
171 : : };
172 : :
173 : : template <>
174 : 0 : class TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_BGRA> : public BasePixelPtr
175 : : {
176 : : public:
177 : 0 : void operator++() { mpPixel += 4; }
178 : :
179 : 0 : PIXBYTE GetRed() const { return mpPixel[2]; }
180 : 0 : PIXBYTE GetGreen() const { return mpPixel[1]; }
181 : 0 : PIXBYTE GetBlue() const { return mpPixel[0]; }
182 : 0 : PIXBYTE GetAlpha() const { return mpPixel[3]; }
183 : 0 : void SetAlpha( PIXBYTE a ) const{ mpPixel[3] = a; }
184 : :
185 : 0 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
186 : : {
187 : 0 : mpPixel[0] = b;
188 : 0 : mpPixel[1] = g;
189 : 0 : mpPixel[2] = r;
190 : 0 : }
191 : : };
192 : :
193 : : template <>
194 : 0 : class TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_MSB_MASK> : public BasePixelPtr
195 : : {
196 : : public:
197 : 0 : void operator++() { mpPixel += 2; }
198 : :
199 : : // TODO: non565-RGB
200 : 0 : PIXBYTE GetRed() const { return (mpPixel[0] & 0xF8U); }
201 : 0 : PIXBYTE GetGreen() const { return (mpPixel[0]<<5U) | ((mpPixel[1]>>3U)&28U); }
202 : 0 : PIXBYTE GetBlue() const { return (mpPixel[1]<<3U); }
203 : 0 : PIXBYTE GetAlpha() const { return 0; }
204 : 0 : void SetAlpha( PIXBYTE ) const {}
205 : :
206 : 0 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
207 : : {
208 : 0 : mpPixel[0] = ((g >> 5U) & 7U) | (r & 0xF8U);
209 : 0 : mpPixel[1] = ((g & 28U)<< 3U) | (b >> 3U);
210 : 0 : }
211 : : };
212 : :
213 : : template <>
214 : 0 : class TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_LSB_MASK> : public BasePixelPtr
215 : : {
216 : : public:
217 : 0 : void operator++() { mpPixel += 2; }
218 : :
219 : : // TODO: non565-RGB
220 : 0 : PIXBYTE GetRed() const { return (mpPixel[1] & 0xF8U); }
221 : 0 : PIXBYTE GetGreen() const { return (mpPixel[1]<<5U) | ((mpPixel[0]>>3U)&28U); }
222 : 0 : PIXBYTE GetBlue() const { return (mpPixel[0]<<3U); }
223 : 0 : PIXBYTE GetAlpha() const { return 0; }
224 : 0 : void SetAlpha( PIXBYTE ) const {}
225 : :
226 : 0 : void SetColor( PIXBYTE r, PIXBYTE g, PIXBYTE b ) const
227 : : {
228 : 0 : mpPixel[0] = ((g & 28U)<< 3U) | (b >> 3U);
229 : 0 : mpPixel[1] = ((g >> 5U) & 7U) | (r & 0xF8U);
230 : 0 : }
231 : : };
232 : :
233 : : // -----------------------------------------------------------------------
234 : :
235 : : template <>
236 : 101800 : class TrueColorPixelPtr<BMP_FORMAT_8BIT_TC_MASK> : public BasePixelPtr
237 : : {
238 : : public:
239 : 68421436 : void operator++() { mpPixel += 1; }
240 : 68421436 : PIXBYTE GetAlpha() const { return mpPixel[0]; }
241 : : void SetAlpha( PIXBYTE a ) const { mpPixel[0] = a; }
242 : : void SetColor( PIXBYTE, PIXBYTE, PIXBYTE ) const {}
243 : : };
244 : :
245 : : // TODO: for some reason many Alpha maps are BMP_FORMAT_8BIT_PAL
246 : : // they should be BMP_FORMAT_8BIT_TC_MASK
247 : : template <>
248 : 101800 : class TrueColorPixelPtr<BMP_FORMAT_8BIT_PAL>
249 : : : public TrueColorPixelPtr<BMP_FORMAT_8BIT_TC_MASK>
250 : : {};
251 : :
252 : : // =======================================================================
253 : : // converting truecolor formats
254 : :
255 : : template <sal_uLong SRCFMT, sal_uLong DSTFMT>
256 : 18024756 : inline void ImplConvertPixel( const TrueColorPixelPtr<DSTFMT>& rDst,
257 : : const TrueColorPixelPtr<SRCFMT>& rSrc )
258 : : {
259 : 18024756 : rDst.SetColor( rSrc.GetRed(), rSrc.GetGreen(), rSrc.GetBlue() );
260 : 18024756 : rDst.SetAlpha( rSrc.GetAlpha() );
261 : 18024756 : }
262 : :
263 : : // -----------------------------------------------------------------------
264 : :
265 : : template <>
266 : 0 : inline void ImplConvertPixel<BMP_FORMAT_16BIT_TC_LSB_MASK, BMP_FORMAT_16BIT_TC_MSB_MASK> (
267 : : const TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_MSB_MASK>& rDst,
268 : : const TrueColorPixelPtr<BMP_FORMAT_16BIT_TC_LSB_MASK>& rSrc )
269 : : {
270 : : // byte swapping
271 : 0 : const PIXBYTE* pSrc = rSrc.GetRawPtr();
272 : 0 : PIXBYTE* pDst = rDst.GetRawPtr();
273 : 0 : pDst[1] = pSrc[0];
274 : 0 : pDst[0] = pSrc[1];
275 : 0 : }
276 : :
277 : : // -----------------------------------------------------------------------
278 : :
279 : : template <sal_uLong SRCFMT, sal_uLong DSTFMT>
280 : 0 : inline void ImplConvertLine( const TrueColorPixelPtr<DSTFMT>& rDst,
281 : : const TrueColorPixelPtr<SRCFMT>& rSrc, int nPixelCount )
282 : : {
283 : 0 : TrueColorPixelPtr<DSTFMT> aDst( rDst );
284 : 0 : TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
285 [ # # ][ # # ]: 0 : while( --nPixelCount >= 0 )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
286 : : {
287 : 0 : ImplConvertPixel( aDst, aSrc );
288 : 0 : ++aSrc;
289 : 0 : ++aDst;
290 : : }
291 : 0 : }
292 : :
293 : : // =======================================================================
294 : : // alpha blending truecolor pixels
295 : :
296 : : template <unsigned ALPHABITS, sal_uLong SRCFMT, sal_uLong DSTFMT>
297 : 68421436 : inline void ImplBlendPixels( const TrueColorPixelPtr<DSTFMT>& rDst,
298 : : const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal )
299 : : {
300 [ # # ][ # # ]: 68421436 : if( !nAlphaVal )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ]
301 : 18024756 : ImplConvertPixel( rDst, rSrc );
302 [ # # ][ # # ]: 50396680 : else if( nAlphaVal != ~(~0 << ALPHABITS) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ]
303 : : {
304 : : static const unsigned nAlphaShift = (ALPHABITS > 8) ? 8 : ALPHABITS;
305 : : if( ALPHABITS > nAlphaShift )
306 : : nAlphaVal >>= ALPHABITS - nAlphaShift;
307 : :
308 : 38627680 : int nR = rDst.GetRed();
309 : 38627680 : int nS = rSrc.GetRed();
310 : 38627680 : nR = nS + (((nR - nS) * nAlphaVal) >> nAlphaShift);
311 : :
312 : 38627680 : int nG = rDst.GetGreen();
313 : 38627680 : nS = rSrc.GetGreen();
314 : 38627680 : nG = nS + (((nG - nS) * nAlphaVal) >> nAlphaShift);
315 : :
316 : 38627680 : int nB = rDst.GetBlue();
317 : 38627680 : nS = rSrc.GetBlue();
318 : 38627680 : nB = nS + (((nB - nS) * nAlphaVal) >> nAlphaShift);
319 : :
320 : 38627680 : rDst.SetColor( sal::static_int_cast<PIXBYTE>(nR),
321 : : sal::static_int_cast<PIXBYTE>(nG),
322 : : sal::static_int_cast<PIXBYTE>(nB) );
323 : : }
324 : 68421436 : }
325 : :
326 : : // -----------------------------------------------------------------------
327 : :
328 : : template <unsigned ALPHABITS, sal_uLong MASKFMT, sal_uLong SRCFMT, sal_uLong DSTFMT>
329 : 2450590 : inline void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst,
330 : : const TrueColorPixelPtr<SRCFMT>& rSrc, const TrueColorPixelPtr<MASKFMT>& rMsk,
331 : : int nPixelCount )
332 : : {
333 : 2450590 : TrueColorPixelPtr<MASKFMT> aMsk( rMsk );
334 : 2450590 : TrueColorPixelPtr<DSTFMT> aDst( rDst );
335 : 2450590 : TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
336 [ # # ][ # # ]: 70872026 : while( --nPixelCount >= 0 )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ]
337 : : {
338 [ # # ][ # # ]: 68421436 : ImplBlendPixels<ALPHABITS>( aDst, aSrc, aMsk.GetAlpha() );
[ + - ]
339 : 68421436 : ++aDst;
340 : 68421436 : ++aSrc;
341 : 68421436 : ++aMsk;
342 : : }
343 : 2450590 : }
344 : :
345 : : // -----------------------------------------------------------------------
346 : :
347 : : template <unsigned ALPHABITS, sal_uLong SRCFMT, sal_uLong DSTFMT>
348 : : inline void ImplBlendLines( const TrueColorPixelPtr<DSTFMT>& rDst,
349 : : const TrueColorPixelPtr<SRCFMT>& rSrc, unsigned nAlphaVal,
350 : : int nPixelCount )
351 : : {
352 : : if( nAlphaVal == ~(~0 << ALPHABITS) )
353 : : ImplConvertLine( rDst, rSrc, nPixelCount );
354 : : else if( nAlphaVal )
355 : : {
356 : : TrueColorPixelPtr<SRCFMT> aSrc( rSrc );
357 : : TrueColorPixelPtr<DSTFMT> aDst( rDst );
358 : : while( --nPixelCount >= 0 )
359 : : {
360 : : ImplBlendPixels<ALPHABITS>( aDst, aSrc, nAlphaVal );
361 : : ++aDst;
362 : : ++aSrc;
363 : : }
364 : : }
365 : : }
366 : :
367 : : // =======================================================================
368 : :
369 : 0 : static bool ImplCopyImage( BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
370 : : {
371 : 0 : const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
372 : 0 : int nDstLinestep = rDstBuffer.mnScanlineSize;
373 : :
374 : 0 : const PIXBYTE* pRawSrc = rSrcBuffer.mpBits;
375 : 0 : PIXBYTE* pRawDst = rDstBuffer.mpBits;
376 : :
377 : : // source and destination don't match upside down
378 [ # # ]: 0 : if( BMP_FORMAT_TOP_DOWN & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
379 : : {
380 : 0 : pRawDst += (rSrcBuffer.mnHeight - 1) * nDstLinestep;
381 : 0 : nDstLinestep = -rDstBuffer.mnScanlineSize;
382 : : }
383 [ # # ]: 0 : else if( nSrcLinestep == nDstLinestep )
384 : : {
385 : 0 : memcpy( pRawDst, pRawSrc, rSrcBuffer.mnHeight * nDstLinestep );
386 : 0 : return true;
387 : : }
388 : :
389 : 0 : int nByteWidth = nSrcLinestep;
390 [ # # ]: 0 : if( nByteWidth > rDstBuffer.mnScanlineSize )
391 : 0 : nByteWidth = rDstBuffer.mnScanlineSize;
392 : :
393 [ # # ]: 0 : for( int y = rSrcBuffer.mnHeight; --y >= 0; )
394 : : {
395 : 0 : memcpy( pRawDst, pRawSrc, nByteWidth );
396 : 0 : pRawSrc += nSrcLinestep;
397 : 0 : pRawDst += nDstLinestep;
398 : : }
399 : :
400 : 0 : return true;
401 : : }
402 : :
403 : : // -----------------------------------------------------------------------
404 : :
405 : : template <sal_uLong DSTFMT,sal_uLong SRCFMT>
406 : 0 : bool ImplConvertToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine,
407 : : BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer )
408 : : {
409 : : // help the compiler to avoid instantiations of unneeded conversions
410 : : DBG_ASSERT( SRCFMT != DSTFMT, "ImplConvertToBitmap into same format");
411 : : if( SRCFMT == DSTFMT )
412 : 0 : return false;
413 : :
414 : 0 : const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
415 : 0 : int nDstLinestep = rDstBuffer.mnScanlineSize;
416 : :
417 : 0 : TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
418 : :
419 : : // source and destination don't match upside down
420 [ # # # # : 0 : if( BMP_FORMAT_TOP_DOWN & (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) )
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
421 : : {
422 : 0 : aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep );
423 : 0 : nDstLinestep = -nDstLinestep;
424 : : }
425 : :
426 [ # # ][ # # ]: 0 : for( int y = rSrcBuffer.mnHeight; --y >= 0; )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
427 : : {
428 [ # # ][ # # ]: 0 : ImplConvertLine( aDstLine, rSrcLine, rSrcBuffer.mnWidth );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
429 : 0 : rSrcLine.AddByteOffset( nSrcLinestep );
430 : 0 : aDstLine.AddByteOffset( nDstLinestep );
431 : : }
432 : :
433 : 0 : return true;
434 : : }
435 : :
436 : : // -----------------------------------------------------------------------
437 : :
438 : : template <sal_uLong SRCFMT>
439 : 0 : inline bool ImplConvertFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc )
440 : : {
441 : 0 : TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
442 : :
443 : : // select the matching instantiation for the destination's bitmap format
444 [ # # # # : 0 : switch( rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN )
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
445 : : {
446 : : case BMP_FORMAT_1BIT_MSB_PAL:
447 : : case BMP_FORMAT_1BIT_LSB_PAL:
448 : : case BMP_FORMAT_4BIT_MSN_PAL:
449 : : case BMP_FORMAT_4BIT_LSN_PAL:
450 : : case BMP_FORMAT_8BIT_PAL:
451 : 0 : break;
452 : :
453 : : case BMP_FORMAT_8BIT_TC_MASK:
454 : : // return ImplConvertToBitmap<BMP_FORMAT_8BIT_TC_MASK>( aSrcType, rDst, rSrc );
455 : : case BMP_FORMAT_24BIT_TC_MASK:
456 : : // return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_MASK>( aSrcType, rDst, rSrc );
457 : : case BMP_FORMAT_32BIT_TC_MASK:
458 : : // return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_MASK>( aSrcType, rDst, rSrc );
459 : 0 : break;
460 : :
461 : : case BMP_FORMAT_16BIT_TC_MSB_MASK:
462 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
463 : : case BMP_FORMAT_16BIT_TC_LSB_MASK:
464 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
465 : :
466 : : case BMP_FORMAT_24BIT_TC_BGR:
467 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_BGR>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
468 : : case BMP_FORMAT_24BIT_TC_RGB:
469 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
470 : :
471 : : case BMP_FORMAT_32BIT_TC_ABGR:
472 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_ABGR>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
473 : : #ifdef FAST_ARGB_BGRA
474 : : case BMP_FORMAT_32BIT_TC_ARGB:
475 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
476 : : case BMP_FORMAT_32BIT_TC_BGRA:
477 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_BGRA>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
478 : : #endif
479 : : case BMP_FORMAT_32BIT_TC_RGBA:
480 [ # # ][ # # ]: 0 : return ImplConvertToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDst, rSrc );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
481 : : }
482 : :
483 : : #ifdef DEBUG
484 : : static int nNotAccelerated = 0;
485 : : if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
486 : : if( ++nNotAccelerated == 100 )
487 : : {
488 : : int foo = 0; (void)foo; // so no warning is created when building on pro with debug
489 : : DBG_WARNING2( "ImplConvertFromBitmap for not accelerated case (0x%04X->0x%04X)",
490 : : rSrc.mnFormat, rDst.mnFormat );
491 : : }
492 : : #endif
493 : :
494 : 0 : return false;
495 : : }
496 : :
497 : : // =======================================================================
498 : :
499 : : // an universal stretching conversion is overkill in most common situations
500 : : // => performance benefits for speeding up the non-stretching cases
501 : 0 : bool ImplFastBitmapConversion( BitmapBuffer& rDst, const BitmapBuffer& rSrc,
502 : : const SalTwoRect& rTR )
503 : : {
504 : : // horizontal mirroring not implemented yet
505 [ # # ]: 0 : if( rTR.mnDestWidth < 0 )
506 : 0 : return false;
507 : : // vertical mirroring
508 [ # # ]: 0 : if( rTR.mnDestHeight < 0 )
509 : : // TODO: rDst.mnFormat ^= BMP_FORMAT_TOP_DOWN;
510 : 0 : return false;
511 : :
512 : : // offseted conversion is not implemented yet
513 [ # # ][ # # ]: 0 : if( rTR.mnSrcX || rTR.mnSrcY )
514 : 0 : return false;
515 [ # # ][ # # ]: 0 : if( rTR.mnDestX || rTR.mnDestY )
516 : 0 : return false;
517 : :
518 : : // stretched conversion is not implemented yet
519 [ # # ]: 0 : if( rTR.mnDestWidth != rTR.mnSrcWidth )
520 : 0 : return false;
521 [ # # ]: 0 : if( rTR.mnDestHeight!= rTR.mnSrcHeight )
522 : 0 : return false;
523 : :
524 : : // check source image size
525 [ # # ]: 0 : if( rSrc.mnWidth < rTR.mnSrcX + rTR.mnSrcWidth )
526 : 0 : return false;
527 [ # # ]: 0 : if( rSrc.mnHeight < rTR.mnSrcY + rTR.mnSrcHeight )
528 : 0 : return false;
529 : :
530 : : // check dest image size
531 [ # # ]: 0 : if( rDst.mnWidth < rTR.mnDestX + rTR.mnDestWidth )
532 : 0 : return false;
533 [ # # ]: 0 : if( rDst.mnHeight < rTR.mnDestY + rTR.mnDestHeight )
534 : 0 : return false;
535 : :
536 : 0 : const sal_uLong nSrcFormat = rSrc.mnFormat & ~BMP_FORMAT_TOP_DOWN;
537 : 0 : const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN;
538 : :
539 : : // TODO: also implement conversions for 16bit colormasks with non-565 format
540 [ # # ]: 0 : if( nSrcFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
541 [ # # # # : 0 : if( rSrc.maColorMask.GetRedMask() != 0xF800
# # ][ # # ]
542 : 0 : || rSrc.maColorMask.GetGreenMask()!= 0x07E0
543 : 0 : || rSrc.maColorMask.GetBlueMask() != 0x001F )
544 : 0 : return false;
545 [ # # ]: 0 : if( nDstFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
546 [ # # # # : 0 : if( rDst.maColorMask.GetRedMask() != 0xF800
# # ][ # # ]
547 : 0 : || rDst.maColorMask.GetGreenMask()!= 0x07E0
548 : 0 : || rDst.maColorMask.GetBlueMask() != 0x001F )
549 : 0 : return false;
550 : :
551 : : // special handling of trivial cases
552 [ # # ]: 0 : if( nSrcFormat == nDstFormat )
553 : : {
554 : : // accelerated palette conversions not yet implemented
555 [ # # ]: 0 : if( rSrc.maPalette != rDst.maPalette )
556 : 0 : return false;
557 : 0 : return ImplCopyImage( rDst, rSrc );
558 : : }
559 : :
560 : : // select the matching instantiation for the source's bitmap format
561 [ # # # # : 0 : switch( nSrcFormat )
# # # # #
# # ]
562 : : {
563 : : case BMP_FORMAT_1BIT_MSB_PAL:
564 : : case BMP_FORMAT_1BIT_LSB_PAL:
565 : : case BMP_FORMAT_4BIT_MSN_PAL:
566 : : case BMP_FORMAT_4BIT_LSN_PAL:
567 : : case BMP_FORMAT_8BIT_PAL:
568 : 0 : break;
569 : :
570 : : case BMP_FORMAT_8BIT_TC_MASK:
571 : : // return ImplConvertFromBitmap<BMP_FORMAT_8BIT_TC_MASK>( rDst, rSrc );
572 : : case BMP_FORMAT_24BIT_TC_MASK:
573 : : // return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_MASK>( rDst, rSrc );
574 : : case BMP_FORMAT_32BIT_TC_MASK:
575 : : // return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_MASK>( rDst, rSrc );
576 : 0 : break;
577 : :
578 : : case BMP_FORMAT_16BIT_TC_MSB_MASK:
579 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( rDst, rSrc );
580 : : case BMP_FORMAT_16BIT_TC_LSB_MASK:
581 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( rDst, rSrc );
582 : :
583 : : case BMP_FORMAT_24BIT_TC_BGR:
584 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_BGR>( rDst, rSrc );
585 : : case BMP_FORMAT_24BIT_TC_RGB:
586 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_24BIT_TC_RGB>( rDst, rSrc );
587 : :
588 : : case BMP_FORMAT_32BIT_TC_ABGR:
589 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_ABGR>( rDst, rSrc );
590 : : #ifdef FAST_ARGB_BGRA
591 : : case BMP_FORMAT_32BIT_TC_ARGB:
592 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_ARGB>( rDst, rSrc );
593 : : case BMP_FORMAT_32BIT_TC_BGRA:
594 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_BGRA>( rDst, rSrc );
595 : : #endif
596 : : case BMP_FORMAT_32BIT_TC_RGBA:
597 : 0 : return ImplConvertFromBitmap<BMP_FORMAT_32BIT_TC_RGBA>( rDst, rSrc );
598 : : }
599 : :
600 : : #ifdef DEBUG
601 : : static int nNotAccelerated = 0;
602 : : if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
603 : : {
604 : : if( ++nNotAccelerated == 100 )
605 : : {
606 : : int foo = 0; (void)foo; // so no warning is created when building on pro with debug
607 : : DBG_WARNING2( "ImplFastBitmapConversion for not accelerated case (0x%04X->0x%04X)", rSrc.mnFormat, rDst.mnFormat );
608 : : }
609 : : }
610 : : #endif
611 : :
612 : 0 : return false;
613 : : }
614 : :
615 : : // =======================================================================
616 : :
617 : : template <sal_uLong DSTFMT,sal_uLong SRCFMT> //,sal_uLong MSKFMT>
618 : 101800 : bool ImplBlendToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine,
619 : : BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
620 : : const BitmapBuffer& rMskBuffer )
621 : : {
622 : : //DBG_ASSERT( rMskBuffer.mnFormat == MSKFMT, "FastBmp BlendImage: wrong MSKFMT" );
623 : : DBG_ASSERT( rMskBuffer.mnFormat == BMP_FORMAT_8BIT_PAL, "FastBmp BlendImage: unusual MSKFMT" );
624 : :
625 : 101800 : const int nSrcLinestep = rSrcBuffer.mnScanlineSize;
626 : 101800 : int nMskLinestep = rMskBuffer.mnScanlineSize;
627 : 101800 : int nDstLinestep = rDstBuffer.mnScanlineSize;
628 : :
629 : 101800 : TrueColorPixelPtr<BMP_FORMAT_8BIT_PAL> aMskLine; aMskLine.SetRawPtr( rMskBuffer.mpBits );
630 : 101800 : TrueColorPixelPtr<DSTFMT> aDstLine; aDstLine.SetRawPtr( rDstBuffer.mpBits );
631 : :
632 : : // special case for single line masks
633 [ # # # # : 101800 : if( rMskBuffer.mnHeight == 1 )
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# - + ]
634 : 0 : nMskLinestep = 0;
635 : :
636 : : // source and mask don't match: upside down
637 [ # # ][ # # ]: 101800 : if( (rSrcBuffer.mnFormat ^ rMskBuffer.mnFormat) & BMP_FORMAT_TOP_DOWN )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ - + ]
638 : : {
639 : 0 : aMskLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nMskLinestep );
640 : 0 : nMskLinestep = -nMskLinestep;
641 : : }
642 : :
643 : : // source and destination don't match: upside down
644 [ # # ][ # # ]: 101800 : if( (rSrcBuffer.mnFormat ^ rDstBuffer.mnFormat) & BMP_FORMAT_TOP_DOWN )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ - + ]
645 : : {
646 : 0 : aDstLine.AddByteOffset( (rSrcBuffer.mnHeight - 1) * nDstLinestep );
647 : 0 : nDstLinestep = -nDstLinestep;
648 : : }
649 : :
650 [ # # ][ # # ]: 2552390 : for( int y = rSrcBuffer.mnHeight; --y >= 0; )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + + ]
651 : : {
652 [ # # ][ # # ]: 2450590 : ImplBlendLines<8>( aDstLine, rSrcLine, aMskLine, rDstBuffer.mnWidth );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ + - ]
653 : 2450590 : aDstLine.AddByteOffset( nDstLinestep );
654 : 2450590 : rSrcLine.AddByteOffset( nSrcLinestep );
655 : 2450590 : aMskLine.AddByteOffset( nMskLinestep );
656 : : }
657 : :
658 : 101800 : return true;
659 : : }
660 : :
661 : : // some specializations to reduce the code size
662 : : template <>
663 : 101800 : inline bool ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_BGR,BMP_FORMAT_24BIT_TC_BGR>(
664 : : TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_BGR>&,
665 : : BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
666 : : const BitmapBuffer& rMskBuffer )
667 : : {
668 : 101800 : TrueColorPixelPtr<BMP_FORMAT_24BIT_TC_RGB> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
669 [ + - ]: 101800 : return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
670 : : }
671 : :
672 : : template <>
673 : 0 : inline bool ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ABGR,BMP_FORMAT_32BIT_TC_ABGR>(
674 : : TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ABGR>&,
675 : : BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
676 : : const BitmapBuffer& rMskBuffer )
677 : : {
678 : 0 : TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_ARGB> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
679 [ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
680 : : }
681 : :
682 : : template <>
683 : 0 : inline bool ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_BGRA,BMP_FORMAT_32BIT_TC_BGRA>(
684 : : TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_BGRA>&,
685 : : BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,
686 : : const BitmapBuffer& rMskBuffer )
687 : : {
688 : 0 : TrueColorPixelPtr<BMP_FORMAT_32BIT_TC_RGBA> aSrcType; aSrcType.SetRawPtr( rSrcBuffer.mpBits );
689 [ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDstBuffer, rSrcBuffer, rMskBuffer );
690 : : }
691 : :
692 : : // -----------------------------------------------------------------------
693 : :
694 : : template <sal_uLong SRCFMT>
695 : 101800 : bool ImplBlendFromBitmap( BitmapBuffer& rDst, const BitmapBuffer& rSrc, const BitmapBuffer& rMsk )
696 : : {
697 : 101800 : TrueColorPixelPtr<SRCFMT> aSrcType; aSrcType.SetRawPtr( rSrc.mpBits );
698 : :
699 : : // select the matching instantiation for the destination's bitmap format
700 [ # # # # : 101800 : switch( rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN )
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# - - - -
+ - - - -
- - # # #
# # # # #
# # # # #
# # # # #
# # # # ]
701 : : {
702 : : case BMP_FORMAT_1BIT_MSB_PAL:
703 : : case BMP_FORMAT_1BIT_LSB_PAL:
704 : : case BMP_FORMAT_4BIT_MSN_PAL:
705 : : case BMP_FORMAT_4BIT_LSN_PAL:
706 : : case BMP_FORMAT_8BIT_PAL:
707 : 0 : break;
708 : :
709 : : case BMP_FORMAT_8BIT_TC_MASK:
710 : : // return ImplBlendToBitmap<BMP_FORMAT_8BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk );
711 : : case BMP_FORMAT_24BIT_TC_MASK:
712 : : // return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk );
713 : : case BMP_FORMAT_32BIT_TC_MASK:
714 : : // return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_MASK>( aSrcType, rDst, rSrc, rMsk );
715 : 0 : break;
716 : :
717 : : case BMP_FORMAT_16BIT_TC_MSB_MASK:
718 [ # # ][ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
719 : : case BMP_FORMAT_16BIT_TC_LSB_MASK:
720 [ # # ][ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
721 : :
722 : : case BMP_FORMAT_24BIT_TC_BGR:
723 [ # # ][ # # ]: 101800 : return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_BGR>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ + - ]
[ # # ][ # # ]
724 : : case BMP_FORMAT_24BIT_TC_RGB:
725 [ # # ][ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_24BIT_TC_RGB>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
726 : :
727 : : case BMP_FORMAT_32BIT_TC_ABGR:
728 [ # # ][ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ABGR>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
729 : : #ifdef FAST_ARGB_BGRA
730 : : case BMP_FORMAT_32BIT_TC_ARGB:
731 [ # # ][ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_ARGB>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
732 : : case BMP_FORMAT_32BIT_TC_BGRA:
733 [ # # ][ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_BGRA>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
734 : : #endif
735 : : case BMP_FORMAT_32BIT_TC_RGBA:
736 [ # # ][ # # ]: 0 : return ImplBlendToBitmap<BMP_FORMAT_32BIT_TC_RGBA>( aSrcType, rDst, rSrc, rMsk );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
737 : : }
738 : :
739 : : #ifdef DEBUG
740 : : static int nNotAccelerated = 0;
741 : : if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
742 : : if( ++nNotAccelerated == 100 )
743 : : {
744 : : int foo = 0; (void)foo; // so no warning is created when building on pro with debug
745 : : DBG_WARNING3( "ImplBlendFromBitmap for not accelerated case (0x%04X*0x%04X->0x%04X)",
746 : : rSrc.mnFormat, rMsk.mnFormat, rDst.mnFormat );
747 : : }
748 : : #endif
749 : :
750 : 101800 : return false;
751 : : }
752 : :
753 : : // -----------------------------------------------------------------------
754 : :
755 : 175246 : bool ImplFastBitmapBlending( BitmapWriteAccess& rDstWA,
756 : : const BitmapReadAccess& rSrcRA, const BitmapReadAccess& rMskRA,
757 : : const SalTwoRect& rTR )
758 : : {
759 : : // accelerated blending of paletted bitmaps not implemented yet
760 [ + + ]: 175246 : if( rSrcRA.HasPalette() )
761 : 35146 : return false;
762 [ - + ]: 140100 : if( rDstWA.HasPalette() )
763 : 0 : return false;
764 : : // TODO: either get rid of mask's use of 8BIT_PAL or check the palette
765 : :
766 : : // horizontal mirroring not implemented yet
767 [ - + ]: 140100 : if( rTR.mnDestWidth < 0 )
768 : 0 : return false;
769 : : // vertical mirroring
770 [ - + ]: 140100 : if( rTR.mnDestHeight < 0 )
771 : : // TODO: rDst.mnFormat ^= BMP_FORMAT_TOP_DOWN;
772 : 0 : return false;
773 : :
774 : : // offseted blending is not implemented yet
775 [ + - ][ - + ]: 140100 : if( rTR.mnSrcX || rTR.mnSrcY )
776 : 0 : return false;
777 [ + + ][ + + ]: 140100 : if( rTR.mnDestX || rTR.mnDestY )
778 : 7960 : return false;
779 : :
780 : : // stretched blending is not implemented yet
781 [ + + ]: 132140 : if( rTR.mnDestWidth != rTR.mnSrcWidth )
782 : 826 : return false;
783 [ + + ]: 131314 : if( rTR.mnDestHeight!= rTR.mnSrcHeight )
784 : 588 : return false;
785 : :
786 : : // check source image size
787 [ - + ]: 130726 : if( rSrcRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
788 : 0 : return false;
789 [ - + ]: 130726 : if( rSrcRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
790 : 0 : return false;
791 : :
792 : : // check mask image size
793 [ - + ]: 130726 : if( rMskRA.Width() < rTR.mnSrcX + rTR.mnSrcWidth )
794 : 0 : return false;
795 [ - + ]: 130726 : if( rMskRA.Height() < rTR.mnSrcY + rTR.mnSrcHeight )
796 [ # # ]: 0 : if( rMskRA.Height() != 1 )
797 : 0 : return false;
798 : :
799 : : // check dest image size
800 [ + + ]: 130726 : if( rDstWA.Width() < rTR.mnDestX + rTR.mnDestWidth )
801 : 20014 : return false;
802 [ + + ]: 110712 : if( rDstWA.Height() < rTR.mnDestY + rTR.mnDestHeight )
803 : 8912 : return false;
804 : :
805 : 101800 : BitmapBuffer& rDst = *rDstWA.ImplGetBitmapBuffer();
806 : 101800 : const BitmapBuffer& rSrc = *rSrcRA.ImplGetBitmapBuffer();
807 : 101800 : const BitmapBuffer& rMsk = *rMskRA.ImplGetBitmapBuffer();
808 : :
809 : 101800 : const sal_uLong nSrcFormat = rSrc.mnFormat & ~BMP_FORMAT_TOP_DOWN;
810 : 101800 : const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN;
811 : :
812 : : // accelerated conversions for 16bit colormasks with non-565 format are not yet implemented
813 [ - + ]: 101800 : if( nSrcFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
814 [ # # # # : 0 : if( rSrc.maColorMask.GetRedMask() != 0xF800
# # ][ # # ]
815 : 0 : || rSrc.maColorMask.GetGreenMask()!= 0x07E0
816 : 0 : || rSrc.maColorMask.GetBlueMask() != 0x001F)
817 : 0 : return false;
818 [ - + ]: 101800 : if( nDstFormat & (BMP_FORMAT_16BIT_TC_LSB_MASK | BMP_FORMAT_16BIT_TC_MSB_MASK) )
819 [ # # # # : 0 : if( rDst.maColorMask.GetRedMask() != 0xF800
# # ][ # # ]
820 : 0 : || rDst.maColorMask.GetGreenMask()!= 0x07E0
821 : 0 : || rDst.maColorMask.GetBlueMask() != 0x001F)
822 : 0 : return false;
823 : :
824 : : // select the matching instantiation for the source's bitmap format
825 [ - - - - : 101800 : switch( nSrcFormat )
+ - - - -
- - ]
826 : : {
827 : : case BMP_FORMAT_1BIT_MSB_PAL:
828 : : case BMP_FORMAT_1BIT_LSB_PAL:
829 : : case BMP_FORMAT_4BIT_MSN_PAL:
830 : : case BMP_FORMAT_4BIT_LSN_PAL:
831 : : case BMP_FORMAT_8BIT_PAL:
832 : 0 : break;
833 : :
834 : : case BMP_FORMAT_8BIT_TC_MASK:
835 : : // return ImplBlendFromBitmap<BMP_FORMAT_8BIT_TC_MASK>( rDst, rSrc );
836 : : case BMP_FORMAT_24BIT_TC_MASK:
837 : : // return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_MASK>( rDst, rSrc );
838 : : case BMP_FORMAT_32BIT_TC_MASK:
839 : : // return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_MASK>( rDst, rSrc );
840 : 0 : break;
841 : :
842 : : case BMP_FORMAT_16BIT_TC_MSB_MASK:
843 : 0 : return ImplBlendFromBitmap<BMP_FORMAT_16BIT_TC_MSB_MASK>( rDst, rSrc, rMsk );
844 : : case BMP_FORMAT_16BIT_TC_LSB_MASK:
845 : 0 : return ImplBlendFromBitmap<BMP_FORMAT_16BIT_TC_LSB_MASK>( rDst, rSrc, rMsk );
846 : :
847 : : case BMP_FORMAT_24BIT_TC_BGR:
848 : 101800 : return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_BGR>( rDst, rSrc, rMsk );
849 : : case BMP_FORMAT_24BIT_TC_RGB:
850 : 0 : return ImplBlendFromBitmap<BMP_FORMAT_24BIT_TC_RGB>( rDst, rSrc, rMsk );
851 : :
852 : : case BMP_FORMAT_32BIT_TC_ABGR:
853 : 0 : return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_ABGR>( rDst, rSrc, rMsk );
854 : : #ifdef FAST_ARGB_BGRA
855 : : case BMP_FORMAT_32BIT_TC_ARGB:
856 : 0 : return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_ARGB>( rDst, rSrc, rMsk );
857 : : case BMP_FORMAT_32BIT_TC_BGRA:
858 : 0 : return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_BGRA>( rDst, rSrc, rMsk );
859 : : #endif
860 : : case BMP_FORMAT_32BIT_TC_RGBA:
861 : 0 : return ImplBlendFromBitmap<BMP_FORMAT_32BIT_TC_RGBA>( rDst, rSrc, rMsk );
862 : : }
863 : :
864 : : #ifdef DEBUG
865 : : static int nNotAccelerated = 0;
866 : : if( rSrc.mnWidth * rSrc.mnHeight >= 4000 )
867 : : if( ++nNotAccelerated == 100 )
868 : : {
869 : : int foo = 0; (void)foo; // so no warning is created when building on pro with debug
870 : : DBG_WARNING3( "ImplFastBlend for not accelerated case (0x%04X*0x%04X->0x%04X)",
871 : : rSrc.mnFormat, rMsk.mnFormat, rDst.mnFormat );
872 : : }
873 : : #endif
874 : :
875 : 175246 : return false;
876 : : }
877 : :
878 : 1752 : bool ImplFastEraseBitmap( BitmapBuffer& rDst, const BitmapColor& rColor )
879 : : {
880 : 1752 : const sal_uLong nDstFormat = rDst.mnFormat & ~BMP_FORMAT_TOP_DOWN;
881 : :
882 : : // erasing a bitmap is often just a byte-wise memory fill
883 : 1752 : bool bByteFill = true;
884 : : sal_uInt8 nFillByte;
885 : :
886 [ + + + + : 1752 : switch( nDstFormat )
- ]
887 : : {
888 : : case BMP_FORMAT_1BIT_MSB_PAL:
889 : : case BMP_FORMAT_1BIT_LSB_PAL:
890 : 229 : nFillByte = rColor.GetIndex();
891 : 229 : nFillByte = static_cast<sal_uInt8>( -(nFillByte & 1) ); // 0x00 or 0xFF
892 : 229 : break;
893 : : case BMP_FORMAT_4BIT_MSN_PAL:
894 : : case BMP_FORMAT_4BIT_LSN_PAL:
895 : 60 : nFillByte = rColor.GetIndex();
896 : 60 : nFillByte &= 0x0F;
897 : 60 : nFillByte |= (nFillByte << 4);
898 : 60 : break;
899 : : case BMP_FORMAT_8BIT_PAL:
900 : : case BMP_FORMAT_8BIT_TC_MASK:
901 : 954 : nFillByte = rColor.GetIndex();
902 : 954 : break;
903 : :
904 : : case BMP_FORMAT_24BIT_TC_MASK:
905 : : case BMP_FORMAT_24BIT_TC_BGR:
906 : : case BMP_FORMAT_24BIT_TC_RGB:
907 : 509 : nFillByte = rColor.GetRed();
908 [ + + ]: 960 : if( (nFillByte != rColor.GetGreen())
[ + + - + ]
909 : 451 : || (nFillByte != rColor.GetBlue()) )
910 : 58 : bByteFill = false;
911 : 509 : break;
912 : :
913 : : default:
914 : 0 : bByteFill = false;
915 : 0 : nFillByte = 0x00;
916 : 0 : break;
917 : : }
918 : :
919 [ + + ]: 1752 : if( bByteFill )
920 : : {
921 : 1694 : long nByteCount = rDst.mnHeight * rDst.mnScanlineSize;
922 : 1694 : memset( rDst.mpBits, nFillByte, nByteCount );
923 : 1694 : return true;
924 : : }
925 : :
926 : : // TODO: handle other bitmap formats
927 [ + - ]: 58 : switch( nDstFormat )
928 : : {
929 : : case BMP_FORMAT_32BIT_TC_MASK:
930 : : case BMP_FORMAT_16BIT_TC_MSB_MASK:
931 : : case BMP_FORMAT_16BIT_TC_LSB_MASK:
932 : :
933 : : case BMP_FORMAT_24BIT_TC_BGR:
934 : : case BMP_FORMAT_24BIT_TC_RGB:
935 : :
936 : : case BMP_FORMAT_32BIT_TC_ABGR:
937 : : #ifdef FAST_ARGB_BGRA
938 : : case BMP_FORMAT_32BIT_TC_ARGB:
939 : : case BMP_FORMAT_32BIT_TC_BGRA:
940 : : #endif
941 : : case BMP_FORMAT_32BIT_TC_RGBA:
942 : 58 : break;
943 : :
944 : : default:
945 : 0 : break;
946 : : }
947 : :
948 : 1752 : return false;
949 : : }
950 : :
951 : : // =======================================================================
952 : :
953 : : #else // NO_OPTIMIZED_BITMAP_ACCESS
954 : :
955 : : bool ImplFastBitmapConversion( BitmapBuffer&, const BitmapBuffer& )
956 : : {
957 : : return false;
958 : : }
959 : :
960 : : bool ImplFastBitmapBlending( BitmapWriteAccess&,
961 : : const BitmapReadAccess&, const BitmapReadAccess&,
962 : : const Size&, const Point& )
963 : : {
964 : : return false;
965 : : }
966 : :
967 : : bool ImplFastEraseBitmap( BitmapBuffer&, const BitmapColor& )
968 : : {
969 : : return false;
970 : : }
971 : :
972 : : #endif
973 : :
974 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|