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 <com/sun/star/util/Endianness.hpp>
31 : : #include <com/sun/star/rendering/ColorComponentTag.hpp>
32 : : #include <com/sun/star/rendering/ColorSpaceType.hpp>
33 : : #include <com/sun/star/rendering/RenderingIntent.hpp>
34 : :
35 : : #include <rtl/instance.hxx>
36 : : #include <osl/mutex.hxx>
37 : :
38 : : #include <tools/diagnose_ex.h>
39 : : #include <canvasbitmap.hxx>
40 : : #include <vcl/canvastools.hxx>
41 : : #include <vcl/bmpacc.hxx>
42 : : #include <vcl/svapp.hxx>
43 : :
44 : : #include <algorithm>
45 : :
46 : :
47 : : using namespace ::vcl::unotools;
48 : : using namespace ::com::sun::star;
49 : :
50 : : namespace
51 : : {
52 : : // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
53 : :
54 : : // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
55 : : // unrolled loop. See e.g. Hackers Delight, p. 66
56 : 0 : inline sal_Int32 bitcount( sal_uInt32 val )
57 : : {
58 : 0 : val = val - ((val >> 1) & 0x55555555);
59 : 0 : val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
60 : 0 : val = (val + (val >> 4)) & 0x0F0F0F0F;
61 : 0 : val = val + (val >> 8);
62 : 0 : val = val + (val >> 16);
63 : 0 : return sal_Int32(val & 0x0000003F);
64 : : }
65 : : }
66 : :
67 : 0 : void VclCanvasBitmap::setComponentInfo( sal_uLong redShift, sal_uLong greenShift, sal_uLong blueShift )
68 : : {
69 : : // sort channels in increasing order of appearance in the pixel
70 : : // (starting with the least significant bits)
71 : 0 : sal_Int8 redPos(0);
72 : 0 : sal_Int8 greenPos(1);
73 : 0 : sal_Int8 bluePos(2);
74 : :
75 [ # # ]: 0 : if( redShift > greenShift )
76 : : {
77 : 0 : std::swap(redPos,greenPos);
78 [ # # ]: 0 : if( redShift > blueShift )
79 : : {
80 : 0 : std::swap(redPos,bluePos);
81 [ # # ]: 0 : if( greenShift > blueShift )
82 : 0 : std::swap(greenPos,bluePos);
83 : : }
84 : : }
85 : : else
86 : : {
87 [ # # ]: 0 : if( greenShift > blueShift )
88 : : {
89 : 0 : std::swap(greenPos,bluePos);
90 [ # # ]: 0 : if( redShift > blueShift )
91 : 0 : std::swap(redPos,bluePos);
92 : : }
93 : : }
94 : :
95 [ # # ]: 0 : m_aComponentTags.realloc(3);
96 [ # # ]: 0 : sal_Int8* pTags = m_aComponentTags.getArray();
97 : 0 : pTags[redPos] = rendering::ColorComponentTag::RGB_RED;
98 : 0 : pTags[greenPos] = rendering::ColorComponentTag::RGB_GREEN;
99 : 0 : pTags[bluePos] = rendering::ColorComponentTag::RGB_BLUE;
100 : :
101 [ # # ]: 0 : m_aComponentBitCounts.realloc(3);
102 [ # # ]: 0 : sal_Int32* pCounts = m_aComponentBitCounts.getArray();
103 : 0 : pCounts[redPos] = bitcount(sal::static_int_cast<sal_uInt32>(redShift));
104 : 0 : pCounts[greenPos] = bitcount(sal::static_int_cast<sal_uInt32>(greenShift));
105 : 0 : pCounts[bluePos] = bitcount(sal::static_int_cast<sal_uInt32>(blueShift));
106 : 0 : }
107 : :
108 : 0 : VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) :
109 : : m_aBmpEx( rBitmap ),
110 : : m_aBitmap( rBitmap.GetBitmap() ),
111 : : m_aAlpha(),
112 [ # # ]: 0 : m_pBmpAcc( m_aBitmap.AcquireReadAccess() ),
113 : : m_pAlphaAcc( NULL ),
114 : : m_aComponentTags(),
115 : : m_aComponentBitCounts(),
116 : : m_aLayout(),
117 : : m_nBitsPerInputPixel(0),
118 : : m_nBitsPerOutputPixel(0),
119 : : m_nRedIndex(-1),
120 : : m_nGreenIndex(-1),
121 : : m_nBlueIndex(-1),
122 : : m_nAlphaIndex(-1),
123 : : m_nIndexIndex(-1),
124 : : m_nEndianness(0),
125 [ # # ][ # # ]: 0 : m_bPalette(false)
[ # # ][ # # ]
[ # # ][ # # ]
126 : : {
127 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
128 : : {
129 [ # # ][ # # ]: 0 : m_aAlpha = m_aBmpEx.IsAlpha() ? m_aBmpEx.GetAlpha().GetBitmap() : m_aBmpEx.GetMask();
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
130 [ # # ]: 0 : m_pAlphaAcc = m_aAlpha.AcquireReadAccess();
131 : : }
132 : :
133 : 0 : m_aLayout.ScanLines = 0;
134 : 0 : m_aLayout.ScanLineBytes = 0;
135 : 0 : m_aLayout.ScanLineStride = 0;
136 : 0 : m_aLayout.PlaneStride = 0;
137 : 0 : m_aLayout.ColorSpace.clear();
138 : 0 : m_aLayout.Palette.clear();
139 : 0 : m_aLayout.IsMsbFirst = sal_False;
140 : :
141 [ # # ]: 0 : if( m_pBmpAcc )
142 : : {
143 : 0 : m_aLayout.ScanLines = m_pBmpAcc->Height();
144 : 0 : m_aLayout.ScanLineBytes = (m_pBmpAcc->GetBitCount()*m_pBmpAcc->Width() + 7) / 8;
145 : 0 : m_aLayout.ScanLineStride = m_pBmpAcc->GetScanlineSize();
146 : 0 : m_aLayout.PlaneStride = 0;
147 : :
148 [ # # # # : 0 : switch( m_pBmpAcc->GetScanlineFormat() )
# # # # #
# # # # #
# # # ]
149 : : {
150 : : case BMP_FORMAT_1BIT_MSB_PAL:
151 : 0 : m_bPalette = true;
152 : 0 : m_nBitsPerInputPixel = 1;
153 : 0 : m_nEndianness = util::Endianness::LITTLE; // doesn't matter
154 : 0 : m_aLayout.IsMsbFirst = sal_True;
155 : 0 : break;
156 : :
157 : : case BMP_FORMAT_1BIT_LSB_PAL:
158 : 0 : m_bPalette = true;
159 : 0 : m_nBitsPerInputPixel = 1;
160 : 0 : m_nEndianness = util::Endianness::LITTLE; // doesn't matter
161 : 0 : m_aLayout.IsMsbFirst = sal_False;
162 : 0 : break;
163 : :
164 : : case BMP_FORMAT_4BIT_MSN_PAL:
165 : 0 : m_bPalette = true;
166 : 0 : m_nBitsPerInputPixel = 4;
167 : 0 : m_nEndianness = util::Endianness::LITTLE; // doesn't matter
168 : 0 : m_aLayout.IsMsbFirst = sal_True;
169 : 0 : break;
170 : :
171 : : case BMP_FORMAT_4BIT_LSN_PAL:
172 : 0 : m_bPalette = true;
173 : 0 : m_nBitsPerInputPixel = 4;
174 : 0 : m_nEndianness = util::Endianness::LITTLE; // doesn't matter
175 : 0 : m_aLayout.IsMsbFirst = sal_False;
176 : 0 : break;
177 : :
178 : : case BMP_FORMAT_8BIT_PAL:
179 : 0 : m_bPalette = true;
180 : 0 : m_nBitsPerInputPixel = 8;
181 : 0 : m_nEndianness = util::Endianness::LITTLE; // doesn't matter
182 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
183 : 0 : break;
184 : :
185 : : case BMP_FORMAT_8BIT_TC_MASK:
186 : 0 : m_bPalette = false;
187 : 0 : m_nBitsPerInputPixel = 8;
188 : 0 : m_nEndianness = util::Endianness::LITTLE; // doesn't matter
189 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
190 : 0 : setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
191 : 0 : m_pBmpAcc->GetColorMask().GetGreenMask(),
192 [ # # ]: 0 : m_pBmpAcc->GetColorMask().GetBlueMask() );
193 : 0 : break;
194 : :
195 : : case BMP_FORMAT_16BIT_TC_MSB_MASK:
196 : 0 : m_bPalette = false;
197 : 0 : m_nBitsPerInputPixel = 16;
198 : 0 : m_nEndianness = util::Endianness::BIG;
199 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
200 : 0 : setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
201 : 0 : m_pBmpAcc->GetColorMask().GetGreenMask(),
202 [ # # ]: 0 : m_pBmpAcc->GetColorMask().GetBlueMask() );
203 : 0 : break;
204 : :
205 : : case BMP_FORMAT_16BIT_TC_LSB_MASK:
206 : 0 : m_bPalette = false;
207 : 0 : m_nBitsPerInputPixel = 16;
208 : 0 : m_nEndianness = util::Endianness::LITTLE;
209 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
210 : 0 : setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
211 : 0 : m_pBmpAcc->GetColorMask().GetGreenMask(),
212 [ # # ]: 0 : m_pBmpAcc->GetColorMask().GetBlueMask() );
213 : 0 : break;
214 : :
215 : : case BMP_FORMAT_24BIT_TC_BGR:
216 : 0 : m_bPalette = false;
217 : 0 : m_nBitsPerInputPixel = 24;
218 : 0 : m_nEndianness = util::Endianness::LITTLE;
219 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
220 : : setComponentInfo( 0xff0000LL,
221 : : 0x00ff00LL,
222 [ # # ]: 0 : 0x0000ffLL );
223 : 0 : break;
224 : :
225 : : case BMP_FORMAT_24BIT_TC_RGB:
226 : 0 : m_bPalette = false;
227 : 0 : m_nBitsPerInputPixel = 24;
228 : 0 : m_nEndianness = util::Endianness::LITTLE;
229 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
230 : : setComponentInfo( 0x0000ffLL,
231 : : 0x00ff00LL,
232 [ # # ]: 0 : 0xff0000LL );
233 : 0 : break;
234 : :
235 : : case BMP_FORMAT_24BIT_TC_MASK:
236 : 0 : m_bPalette = false;
237 : 0 : m_nBitsPerInputPixel = 24;
238 : 0 : m_nEndianness = util::Endianness::LITTLE;
239 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
240 : 0 : setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
241 : 0 : m_pBmpAcc->GetColorMask().GetGreenMask(),
242 [ # # ]: 0 : m_pBmpAcc->GetColorMask().GetBlueMask() );
243 : 0 : break;
244 : :
245 : : case BMP_FORMAT_32BIT_TC_ABGR:
246 : : {
247 : 0 : m_bPalette = false;
248 : 0 : m_nBitsPerInputPixel = 32;
249 : 0 : m_nEndianness = util::Endianness::LITTLE;
250 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
251 : :
252 [ # # ]: 0 : m_aComponentTags.realloc(4);
253 [ # # ]: 0 : sal_Int8* pTags = m_aComponentTags.getArray();
254 : 0 : pTags[0] = rendering::ColorComponentTag::ALPHA;
255 : 0 : pTags[1] = rendering::ColorComponentTag::RGB_BLUE;
256 : 0 : pTags[2] = rendering::ColorComponentTag::RGB_GREEN;
257 : 0 : pTags[3] = rendering::ColorComponentTag::RGB_RED;
258 : :
259 [ # # ]: 0 : m_aComponentBitCounts.realloc(4);
260 [ # # ]: 0 : sal_Int32* pCounts = m_aComponentBitCounts.getArray();
261 : 0 : pCounts[0] = 8;
262 : 0 : pCounts[1] = 8;
263 : 0 : pCounts[2] = 8;
264 : 0 : pCounts[3] = 8;
265 : :
266 : 0 : m_nRedIndex = 3;
267 : 0 : m_nGreenIndex = 2;
268 : 0 : m_nBlueIndex = 1;
269 : 0 : m_nAlphaIndex = 0;
270 : : }
271 : 0 : break;
272 : :
273 : : case BMP_FORMAT_32BIT_TC_ARGB:
274 : : {
275 : 0 : m_bPalette = false;
276 : 0 : m_nBitsPerInputPixel = 32;
277 : 0 : m_nEndianness = util::Endianness::LITTLE;
278 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
279 : :
280 [ # # ]: 0 : m_aComponentTags.realloc(4);
281 [ # # ]: 0 : sal_Int8* pTags = m_aComponentTags.getArray();
282 : 0 : pTags[0] = rendering::ColorComponentTag::ALPHA;
283 : 0 : pTags[1] = rendering::ColorComponentTag::RGB_RED;
284 : 0 : pTags[2] = rendering::ColorComponentTag::RGB_GREEN;
285 : 0 : pTags[3] = rendering::ColorComponentTag::RGB_BLUE;
286 : :
287 [ # # ]: 0 : m_aComponentBitCounts.realloc(4);
288 [ # # ]: 0 : sal_Int32* pCounts = m_aComponentBitCounts.getArray();
289 : 0 : pCounts[0] = 8;
290 : 0 : pCounts[1] = 8;
291 : 0 : pCounts[2] = 8;
292 : 0 : pCounts[3] = 8;
293 : :
294 : 0 : m_nRedIndex = 1;
295 : 0 : m_nGreenIndex = 2;
296 : 0 : m_nBlueIndex = 3;
297 : 0 : m_nAlphaIndex = 0;
298 : : }
299 : 0 : break;
300 : :
301 : : case BMP_FORMAT_32BIT_TC_BGRA:
302 : : {
303 : 0 : m_bPalette = false;
304 : 0 : m_nBitsPerInputPixel = 32;
305 : 0 : m_nEndianness = util::Endianness::LITTLE;
306 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
307 : :
308 [ # # ]: 0 : m_aComponentTags.realloc(4);
309 [ # # ]: 0 : sal_Int8* pTags = m_aComponentTags.getArray();
310 : 0 : pTags[0] = rendering::ColorComponentTag::RGB_BLUE;
311 : 0 : pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
312 : 0 : pTags[2] = rendering::ColorComponentTag::RGB_RED;
313 : 0 : pTags[3] = rendering::ColorComponentTag::ALPHA;
314 : :
315 [ # # ]: 0 : m_aComponentBitCounts.realloc(4);
316 [ # # ]: 0 : sal_Int32* pCounts = m_aComponentBitCounts.getArray();
317 : 0 : pCounts[0] = 8;
318 : 0 : pCounts[1] = 8;
319 : 0 : pCounts[2] = 8;
320 : 0 : pCounts[3] = 8;
321 : :
322 : 0 : m_nRedIndex = 2;
323 : 0 : m_nGreenIndex = 1;
324 : 0 : m_nBlueIndex = 0;
325 : 0 : m_nAlphaIndex = 3;
326 : : }
327 : 0 : break;
328 : :
329 : : case BMP_FORMAT_32BIT_TC_RGBA:
330 : : {
331 : 0 : m_bPalette = false;
332 : 0 : m_nBitsPerInputPixel = 32;
333 : 0 : m_nEndianness = util::Endianness::LITTLE;
334 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
335 : :
336 [ # # ]: 0 : m_aComponentTags.realloc(4);
337 [ # # ]: 0 : sal_Int8* pTags = m_aComponentTags.getArray();
338 : 0 : pTags[0] = rendering::ColorComponentTag::RGB_RED;
339 : 0 : pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
340 : 0 : pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
341 : 0 : pTags[3] = rendering::ColorComponentTag::ALPHA;
342 : :
343 [ # # ]: 0 : m_aComponentBitCounts.realloc(4);
344 [ # # ]: 0 : sal_Int32* pCounts = m_aComponentBitCounts.getArray();
345 : 0 : pCounts[0] = 8;
346 : 0 : pCounts[1] = 8;
347 : 0 : pCounts[2] = 8;
348 : 0 : pCounts[3] = 8;
349 : :
350 : 0 : m_nRedIndex = 0;
351 : 0 : m_nGreenIndex = 1;
352 : 0 : m_nBlueIndex = 2;
353 : 0 : m_nAlphaIndex = 3;
354 : : }
355 : 0 : break;
356 : :
357 : : case BMP_FORMAT_32BIT_TC_MASK:
358 : 0 : m_bPalette = false;
359 : 0 : m_nBitsPerInputPixel = 32;
360 : 0 : m_nEndianness = util::Endianness::LITTLE;
361 : 0 : m_aLayout.IsMsbFirst = sal_False; // doesn't matter
362 : 0 : setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
363 : 0 : m_pBmpAcc->GetColorMask().GetGreenMask(),
364 [ # # ]: 0 : m_pBmpAcc->GetColorMask().GetBlueMask() );
365 : 0 : break;
366 : :
367 : : default:
368 : : OSL_FAIL( "unsupported bitmap format" );
369 : 0 : break;
370 : : }
371 : :
372 [ # # ]: 0 : if( m_bPalette )
373 : : {
374 [ # # ]: 0 : m_aComponentTags.realloc(1);
375 [ # # ]: 0 : m_aComponentTags[0] = rendering::ColorComponentTag::INDEX;
376 : :
377 [ # # ]: 0 : m_aComponentBitCounts.realloc(1);
378 [ # # ]: 0 : m_aComponentBitCounts[0] = m_nBitsPerInputPixel;
379 : :
380 : 0 : m_nIndexIndex = 0;
381 : : }
382 : :
383 : 0 : m_nBitsPerOutputPixel = m_nBitsPerInputPixel;
384 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
385 : : {
386 : : // TODO(P1): need to interleave alpha with bitmap data -
387 : : // won't fuss with less-than-8 bit for now
388 [ # # ]: 0 : m_nBitsPerOutputPixel = std::max(sal_Int32(8),m_nBitsPerInputPixel);
389 : :
390 : : // check whether alpha goes in front or behind the
391 : : // bitcount sequence. If pixel format is little endian,
392 : : // put it behind all the other channels. If it's big
393 : : // endian, put it in front (because later, the actual data
394 : : // always gets written after the pixel data)
395 : :
396 : : // TODO(Q1): slight catch - in the case of the
397 : : // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
398 : : // channels might happen!
399 [ # # ]: 0 : m_aComponentTags.realloc(m_aComponentTags.getLength()+1);
400 [ # # ]: 0 : m_aComponentTags[m_aComponentTags.getLength()-1] = rendering::ColorComponentTag::ALPHA;
401 : :
402 [ # # ]: 0 : m_aComponentBitCounts.realloc(m_aComponentBitCounts.getLength()+1);
403 [ # # ][ # # ]: 0 : m_aComponentBitCounts[m_aComponentBitCounts.getLength()-1] = m_aBmpEx.IsAlpha() ? 8 : 1;
[ # # ]
404 : :
405 [ # # ]: 0 : if( m_nEndianness == util::Endianness::BIG )
406 : : {
407 : : // put alpha in front of all the color channels
408 [ # # ]: 0 : sal_Int8* pTags =m_aComponentTags.getArray();
409 [ # # ]: 0 : sal_Int32* pCounts=m_aComponentBitCounts.getArray();
410 : : std::rotate(pTags,
411 : 0 : pTags+m_aComponentTags.getLength()-1,
412 [ # # ]: 0 : pTags+m_aComponentTags.getLength());
413 : : std::rotate(pCounts,
414 : 0 : pCounts+m_aComponentBitCounts.getLength()-1,
415 [ # # ]: 0 : pCounts+m_aComponentBitCounts.getLength());
416 : 0 : ++m_nRedIndex;
417 : 0 : ++m_nGreenIndex;
418 : 0 : ++m_nBlueIndex;
419 : 0 : ++m_nIndexIndex;
420 : 0 : m_nAlphaIndex=0;
421 : : }
422 : :
423 : : // always add a full byte to the pixel size, otherwise
424 : : // pixel packing hell breaks loose.
425 : 0 : m_nBitsPerOutputPixel += 8;
426 : :
427 : : // adapt scanline parameters
428 [ # # ]: 0 : const Size aSize = m_aBitmap.GetSizePixel();
429 : : m_aLayout.ScanLineBytes =
430 : 0 : m_aLayout.ScanLineStride = (aSize.Width()*m_nBitsPerOutputPixel + 7)/8;
431 : : }
432 : : }
433 : 0 : }
434 : :
435 [ # # ][ # # ]: 0 : VclCanvasBitmap::~VclCanvasBitmap()
[ # # ][ # # ]
[ # # ][ # # ]
436 : : {
437 [ # # ]: 0 : if( m_pAlphaAcc )
438 [ # # ]: 0 : m_aAlpha.ReleaseAccess(m_pAlphaAcc);
439 [ # # ]: 0 : if( m_pBmpAcc )
440 [ # # ]: 0 : m_aBitmap.ReleaseAccess(m_pBmpAcc);
441 [ # # ]: 0 : }
442 : :
443 : : // XBitmap
444 : 0 : geometry::IntegerSize2D SAL_CALL VclCanvasBitmap::getSize() throw (uno::RuntimeException)
445 : : {
446 [ # # ]: 0 : SolarMutexGuard aGuard;
447 [ # # ][ # # ]: 0 : return integerSize2DFromSize( m_aBitmap.GetSizePixel() );
[ # # ]
448 : : }
449 : :
450 : 0 : ::sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException)
451 : : {
452 [ # # ]: 0 : SolarMutexGuard aGuard;
453 [ # # ][ # # ]: 0 : return m_aBmpEx.IsTransparent();
454 : : }
455 : :
456 : 0 : uno::Reference< rendering::XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D& newSize,
457 : : sal_Bool beFast ) throw (uno::RuntimeException)
458 : : {
459 [ # # ]: 0 : SolarMutexGuard aGuard;
460 : :
461 [ # # ]: 0 : BitmapEx aNewBmp( m_aBitmap );
462 [ # # ][ # # ]: 0 : aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BMP_SCALE_FAST : BMP_SCALE_DEFAULT );
[ # # ]
463 [ # # ][ # # ]: 0 : return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) );
[ # # ][ # # ]
[ # # ]
464 : : }
465 : :
466 : : // XIntegerReadOnlyBitmap
467 : 0 : uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerBitmapLayout& bitmapLayout,
468 : : const geometry::IntegerRectangle2D& rect ) throw( lang::IndexOutOfBoundsException,
469 : : rendering::VolatileContentDestroyedException,
470 : : uno::RuntimeException)
471 : : {
472 [ # # ]: 0 : SolarMutexGuard aGuard;
473 : :
474 [ # # ][ # # ]: 0 : bitmapLayout = getMemoryLayout();
[ # # ]
475 : :
476 [ # # ]: 0 : const ::Rectangle aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect) );
477 [ # # ][ # # ]: 0 : if( aRequestedArea.IsEmpty() )
478 [ # # ]: 0 : return uno::Sequence< sal_Int8 >();
479 : :
480 : : // Invalid/empty bitmap: no data available
481 [ # # ]: 0 : if( !m_pBmpAcc )
482 [ # # ]: 0 : throw lang::IndexOutOfBoundsException();
483 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
[ # # ][ # # ]
484 [ # # ]: 0 : throw lang::IndexOutOfBoundsException();
485 : :
486 [ # # ][ # # : 0 : if( aRequestedArea.Left() < 0 || aRequestedArea.Top() < 0 ||
# # # # ]
[ # # ]
487 : 0 : aRequestedArea.Right() > m_pBmpAcc->Width() ||
488 : 0 : aRequestedArea.Bottom() > m_pBmpAcc->Height() )
489 : : {
490 [ # # ]: 0 : throw lang::IndexOutOfBoundsException();
491 : : }
492 : :
493 [ # # ]: 0 : uno::Sequence< sal_Int8 > aRet;
494 : 0 : Rectangle aRequestedBytes( aRequestedArea );
495 : :
496 : : // adapt to byte boundaries
497 : 0 : aRequestedBytes.Left() = aRequestedArea.Left()*m_nBitsPerOutputPixel/8;
498 : 0 : aRequestedBytes.Right() = (aRequestedArea.Right()*m_nBitsPerOutputPixel + 7)/8;
499 : :
500 : : // copy stuff to output sequence
501 [ # # ]: 0 : aRet.realloc(aRequestedBytes.getWidth()*aRequestedBytes.getHeight());
502 [ # # ]: 0 : sal_Int8* pOutBuf = aRet.getArray();
503 : :
504 : 0 : bitmapLayout.ScanLines = aRequestedBytes.getHeight();
505 : : bitmapLayout.ScanLineBytes =
506 : 0 : bitmapLayout.ScanLineStride= aRequestedBytes.getWidth();
507 : :
508 : 0 : sal_Int32 nScanlineStride=bitmapLayout.ScanLineStride;
509 [ # # ]: 0 : if( !(m_pBmpAcc->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN) )
510 : : {
511 : 0 : pOutBuf += bitmapLayout.ScanLineStride*(aRequestedBytes.getHeight()-1);
512 : 0 : nScanlineStride *= -1;
513 : : }
514 : :
515 [ # # ][ # # ]: 0 : if( !m_aBmpEx.IsTransparent() )
516 : : {
517 : : OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
518 : :
519 : : // can return bitmap data as-is
520 [ # # ]: 0 : for( long y=aRequestedBytes.Top(); y<aRequestedBytes.Bottom(); ++y )
521 : : {
522 : 0 : Scanline pScan = m_pBmpAcc->GetScanline(y);
523 : 0 : memcpy(pOutBuf, pScan+aRequestedBytes.Left(), aRequestedBytes.getWidth());
524 : 0 : pOutBuf += nScanlineStride;
525 : : }
526 : : }
527 : : else
528 : : {
529 : : OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
530 : : OSL_ENSURE(m_pAlphaAcc,"Invalid alpha read access");
531 : :
532 : : // interleave alpha with bitmap data - note, bitcount is
533 : : // always integer multiple of 8
534 : : OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0,
535 : : "Transparent bitmap bitcount not integer multiple of 8" );
536 : :
537 [ # # ]: 0 : for( long y=aRequestedArea.Top(); y<aRequestedArea.Bottom(); ++y )
538 : : {
539 : 0 : sal_Int8* pOutScan = pOutBuf;
540 : :
541 [ # # ]: 0 : if( m_nBitsPerInputPixel < 8 )
542 : : {
543 : : // input less than a byte - copy via GetPixel()
544 [ # # ]: 0 : for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
545 : : {
546 [ # # ]: 0 : *pOutScan++ = m_pBmpAcc->GetPixel(y,x);
547 [ # # ]: 0 : *pOutScan++ = m_pAlphaAcc->GetPixel(y,x);
548 : : }
549 : : }
550 : : else
551 : : {
552 : 0 : const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
553 : 0 : const long nScanlineOffsetLeft(aRequestedArea.Left()*nNonAlphaBytes);
554 : 0 : Scanline pScan = m_pBmpAcc->GetScanline(y) + nScanlineOffsetLeft;
555 : :
556 : : // input integer multiple of byte - copy directly
557 [ # # ]: 0 : for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
558 : : {
559 [ # # ]: 0 : for( long i=0; i<nNonAlphaBytes; ++i )
560 : 0 : *pOutScan++ = *pScan++;
561 [ # # ]: 0 : *pOutScan++ = m_pAlphaAcc->GetPixel(y,x);
562 : : }
563 : : }
564 : :
565 : 0 : pOutBuf += nScanlineStride;
566 : : }
567 : : }
568 : :
569 [ # # ][ # # ]: 0 : return aRet;
[ # # ]
570 : : }
571 : :
572 : 0 : uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout& bitmapLayout,
573 : : const geometry::IntegerPoint2D& pos ) throw (lang::IndexOutOfBoundsException,
574 : : rendering::VolatileContentDestroyedException,
575 : : uno::RuntimeException)
576 : : {
577 [ # # ]: 0 : SolarMutexGuard aGuard;
578 : :
579 [ # # ][ # # ]: 0 : bitmapLayout = getMemoryLayout();
[ # # ]
580 : :
581 : : // Invalid/empty bitmap: no data available
582 [ # # ]: 0 : if( !m_pBmpAcc )
583 [ # # ]: 0 : throw lang::IndexOutOfBoundsException();
584 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
[ # # ][ # # ]
585 [ # # ]: 0 : throw lang::IndexOutOfBoundsException();
586 : :
587 [ # # ][ # # : 0 : if( pos.X < 0 || pos.Y < 0 ||
# # # # ]
[ # # ]
588 : 0 : pos.X > m_pBmpAcc->Width() || pos.Y > m_pBmpAcc->Height() )
589 : : {
590 [ # # ]: 0 : throw lang::IndexOutOfBoundsException();
591 : : }
592 : :
593 [ # # ]: 0 : uno::Sequence< sal_Int8 > aRet((m_nBitsPerOutputPixel + 7)/8);
594 [ # # ]: 0 : sal_Int8* pOutBuf = aRet.getArray();
595 : :
596 : : // copy stuff to output sequence
597 : 0 : bitmapLayout.ScanLines = 1;
598 : : bitmapLayout.ScanLineBytes =
599 : 0 : bitmapLayout.ScanLineStride= aRet.getLength();
600 : :
601 : 0 : const long nScanlineLeftOffset( pos.X*m_nBitsPerInputPixel/8 );
602 [ # # ][ # # ]: 0 : if( !m_aBmpEx.IsTransparent() )
603 : : {
604 : : OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
605 : :
606 : : // can return bitmap data as-is
607 : 0 : Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
608 : 0 : memcpy(pOutBuf, pScan+nScanlineLeftOffset, aRet.getLength() );
609 : : }
610 : : else
611 : : {
612 : : OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
613 : : OSL_ENSURE(m_pAlphaAcc,"Invalid alpha read access");
614 : :
615 : : // interleave alpha with bitmap data - note, bitcount is
616 : : // always integer multiple of 8
617 : : OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0,
618 : : "Transparent bitmap bitcount not integer multiple of 8" );
619 : :
620 [ # # ]: 0 : if( m_nBitsPerInputPixel < 8 )
621 : : {
622 : : // input less than a byte - copy via GetPixel()
623 [ # # ]: 0 : *pOutBuf++ = m_pBmpAcc->GetPixel(pos.Y,pos.X);
624 [ # # ]: 0 : *pOutBuf = m_pAlphaAcc->GetPixel(pos.Y,pos.X);
625 : : }
626 : : else
627 : : {
628 : 0 : const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
629 : 0 : Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
630 : :
631 : : // input integer multiple of byte - copy directly
632 : 0 : memcpy(pOutBuf, pScan+nScanlineLeftOffset, nNonAlphaBytes );
633 : 0 : pOutBuf += nNonAlphaBytes;
634 [ # # ]: 0 : *pOutBuf++ = m_pAlphaAcc->GetPixel(pos.Y,pos.X);
635 : : }
636 : : }
637 : :
638 [ # # ]: 0 : return aRet;
639 : : }
640 : :
641 : 0 : uno::Reference< rendering::XBitmapPalette > SAL_CALL VclCanvasBitmap::getPalette() throw (uno::RuntimeException)
642 : : {
643 [ # # ]: 0 : SolarMutexGuard aGuard;
644 : :
645 : 0 : uno::Reference< XBitmapPalette > aRet;
646 [ # # ]: 0 : if( m_bPalette )
647 [ # # ]: 0 : aRet.set(this);
648 : :
649 [ # # ]: 0 : return aRet;
650 : : }
651 : :
652 : 0 : rendering::IntegerBitmapLayout SAL_CALL VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException)
653 : : {
654 [ # # ]: 0 : SolarMutexGuard aGuard;
655 : :
656 [ # # ]: 0 : rendering::IntegerBitmapLayout aLayout( m_aLayout );
657 : :
658 : : // only set references to self on separate copy of
659 : : // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
660 : : // a circular reference!
661 [ # # ]: 0 : if( m_bPalette )
662 [ # # ]: 0 : aLayout.Palette.set( this );
663 : :
664 [ # # ]: 0 : aLayout.ColorSpace.set( this );
665 : :
666 [ # # ]: 0 : return aLayout;
667 : : }
668 : :
669 : 0 : sal_Int32 SAL_CALL VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException)
670 : : {
671 [ # # ]: 0 : SolarMutexGuard aGuard;
672 : :
673 [ # # ]: 0 : if( !m_pBmpAcc )
674 : 0 : return 0;
675 : :
676 [ # # ][ # # ]: 0 : return m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ;
677 : : }
678 : :
679 : 0 : sal_Bool SAL_CALL VclCanvasBitmap::getIndex( uno::Sequence< double >& o_entry, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
680 : : {
681 [ # # ]: 0 : SolarMutexGuard aGuard;
682 : :
683 : : const sal_uInt16 nCount( m_pBmpAcc ?
684 [ # # ][ # # ]: 0 : (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
685 : : OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
686 [ # # ][ # # ]: 0 : if( nIndex < 0 || nIndex >= nCount )
687 : : throw lang::IndexOutOfBoundsException(::rtl::OUString("Palette index out of range"),
688 [ # # ][ # # ]: 0 : static_cast<rendering::XBitmapPalette*>(this));
689 : :
690 : 0 : const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(sal::static_int_cast<sal_uInt16>(nIndex));
691 [ # # ]: 0 : o_entry.realloc(3);
692 [ # # ]: 0 : double* pColor=o_entry.getArray();
693 : 0 : pColor[0] = aCol.GetRed();
694 : 0 : pColor[1] = aCol.GetGreen();
695 : 0 : pColor[2] = aCol.GetBlue();
696 : :
697 [ # # ]: 0 : return sal_True; // no palette transparency here.
698 : : }
699 : :
700 : 0 : sal_Bool SAL_CALL VclCanvasBitmap::setIndex( const uno::Sequence< double >&, sal_Bool, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException)
701 : : {
702 [ # # ]: 0 : SolarMutexGuard aGuard;
703 : :
704 : : const sal_uInt16 nCount( m_pBmpAcc ?
705 [ # # ][ # # ]: 0 : (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
706 : :
707 : : OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
708 [ # # ][ # # ]: 0 : if( nIndex < 0 || nIndex >= nCount )
709 : : throw lang::IndexOutOfBoundsException(::rtl::OUString("Palette index out of range"),
710 [ # # ][ # # ]: 0 : static_cast<rendering::XBitmapPalette*>(this));
711 : :
712 [ # # ]: 0 : return sal_False; // read-only implementation
713 : : }
714 : :
715 : : namespace
716 : : {
717 : : struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
718 : : PaletteColorSpaceHolder>
719 : : {
720 : 0 : uno::Reference<rendering::XColorSpace> operator()()
721 : : {
722 : 0 : return vcl::unotools::createStandardColorSpace();
723 : : }
724 : : };
725 : : }
726 : :
727 : 0 : uno::Reference< rendering::XColorSpace > SAL_CALL VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException)
728 : : {
729 : : // this is the method from XBitmapPalette. Return palette color
730 : : // space here
731 : 0 : return PaletteColorSpaceHolder::get();
732 : : }
733 : :
734 : 0 : sal_Int8 SAL_CALL VclCanvasBitmap::getType( ) throw (uno::RuntimeException)
735 : : {
736 : 0 : return rendering::ColorSpaceType::RGB;
737 : : }
738 : :
739 : 0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException)
740 : : {
741 [ # # ]: 0 : SolarMutexGuard aGuard;
742 [ # # ][ # # ]: 0 : return m_aComponentTags;
743 : : }
744 : :
745 : 0 : sal_Int8 SAL_CALL VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException)
746 : : {
747 : 0 : return rendering::RenderingIntent::PERCEPTUAL;
748 : : }
749 : :
750 : 0 : uno::Sequence< ::beans::PropertyValue > SAL_CALL VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException)
751 : : {
752 : 0 : return uno::Sequence< ::beans::PropertyValue >();
753 : : }
754 : :
755 : 0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertColorSpace( const uno::Sequence< double >& deviceColor,
756 : : const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (uno::RuntimeException)
757 : : {
758 : : // TODO(P3): if we know anything about target
759 : : // colorspace, this can be greatly sped up
760 : : uno::Sequence<rendering::ARGBColor> aIntermediate(
761 [ # # ]: 0 : convertToARGB(deviceColor));
762 [ # # ][ # # ]: 0 : return targetColorSpace->convertFromARGB(aIntermediate);
[ # # ]
763 : : }
764 : :
765 : 0 : uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
766 : : {
767 [ # # ]: 0 : SolarMutexGuard aGuard;
768 : :
769 : 0 : const sal_Size nLen( deviceColor.getLength() );
770 : 0 : const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
771 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
[ # # ][ # # ]
[ # # ]
772 : : "number of channels no multiple of pixel element count",
773 : : static_cast<rendering::XBitmapPalette*>(this), 01);
774 : :
775 [ # # ]: 0 : uno::Sequence< rendering::RGBColor > aRes(nLen/nComponentsPerPixel);
776 [ # # ]: 0 : rendering::RGBColor* pOut( aRes.getArray() );
777 : :
778 [ # # ]: 0 : if( m_bPalette )
779 : : {
780 : : OSL_ENSURE(m_nIndexIndex != -1,
781 : : "Invalid color channel indices");
782 [ # # ][ # # ]: 0 : ENSURE_OR_THROW(m_pBmpAcc,
[ # # ][ # # ]
783 : : "Unable to get BitmapAccess");
784 : :
785 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
786 : : {
787 : : const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
788 : 0 : sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
789 : :
790 : : // TODO(F3): Convert result to sRGB color space
791 : 0 : *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
792 : 0 : toDoubleColor(aCol.GetGreen()),
793 : 0 : toDoubleColor(aCol.GetBlue()));
794 : 0 : }
795 : : }
796 : : else
797 : : {
798 : : OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
799 : : "Invalid color channel indices");
800 : :
801 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
802 : : {
803 : : // TODO(F3): Convert result to sRGB color space
804 : : *pOut++ = rendering::RGBColor(
805 : 0 : deviceColor[i+m_nRedIndex],
806 : 0 : deviceColor[i+m_nGreenIndex],
807 : 0 : deviceColor[i+m_nBlueIndex]);
808 : : }
809 : : }
810 : :
811 [ # # ]: 0 : return aRes;
812 : : }
813 : :
814 : 0 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
815 : : {
816 [ # # ]: 0 : SolarMutexGuard aGuard;
817 : :
818 : 0 : const sal_Size nLen( deviceColor.getLength() );
819 : 0 : const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
820 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
[ # # ][ # # ]
[ # # ]
821 : : "number of channels no multiple of pixel element count",
822 : : static_cast<rendering::XBitmapPalette*>(this), 01);
823 : :
824 [ # # ]: 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/nComponentsPerPixel);
825 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
826 : :
827 [ # # ]: 0 : if( m_bPalette )
828 : : {
829 : : OSL_ENSURE(m_nIndexIndex != -1,
830 : : "Invalid color channel indices");
831 [ # # ][ # # ]: 0 : ENSURE_OR_THROW(m_pBmpAcc,
[ # # ][ # # ]
832 : : "Unable to get BitmapAccess");
833 : :
834 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
835 : : {
836 : : const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
837 : 0 : sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
838 : :
839 : : // TODO(F3): Convert result to sRGB color space
840 [ # # ]: 0 : const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
841 : : *pOut++ = rendering::ARGBColor(nAlpha,
842 : 0 : toDoubleColor(aCol.GetRed()),
843 : 0 : toDoubleColor(aCol.GetGreen()),
844 : 0 : toDoubleColor(aCol.GetBlue()));
845 : 0 : }
846 : : }
847 : : else
848 : : {
849 : : OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
850 : : "Invalid color channel indices");
851 : :
852 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
853 : : {
854 : : // TODO(F3): Convert result to sRGB color space
855 [ # # ]: 0 : const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
856 : : *pOut++ = rendering::ARGBColor(
857 : : nAlpha,
858 : 0 : deviceColor[i+m_nRedIndex],
859 : 0 : deviceColor[i+m_nGreenIndex],
860 : 0 : deviceColor[i+m_nBlueIndex]);
861 : : }
862 : : }
863 : :
864 [ # # ]: 0 : return aRes;
865 : : }
866 : :
867 : 0 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
868 : : {
869 [ # # ]: 0 : SolarMutexGuard aGuard;
870 : :
871 : 0 : const sal_Size nLen( deviceColor.getLength() );
872 : 0 : const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
873 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
[ # # ][ # # ]
[ # # ]
874 : : "number of channels no multiple of pixel element count",
875 : : static_cast<rendering::XBitmapPalette*>(this), 01);
876 : :
877 [ # # ]: 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/nComponentsPerPixel);
878 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
879 : :
880 [ # # ]: 0 : if( m_bPalette )
881 : : {
882 : : OSL_ENSURE(m_nIndexIndex != -1,
883 : : "Invalid color channel indices");
884 [ # # ][ # # ]: 0 : ENSURE_OR_THROW(m_pBmpAcc,
[ # # ][ # # ]
885 : : "Unable to get BitmapAccess");
886 : :
887 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
888 : : {
889 : : const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
890 : 0 : sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
891 : :
892 : : // TODO(F3): Convert result to sRGB color space
893 [ # # ]: 0 : const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
894 : : *pOut++ = rendering::ARGBColor(nAlpha,
895 : 0 : nAlpha*toDoubleColor(aCol.GetRed()),
896 : 0 : nAlpha*toDoubleColor(aCol.GetGreen()),
897 : 0 : nAlpha*toDoubleColor(aCol.GetBlue()));
898 : 0 : }
899 : : }
900 : : else
901 : : {
902 : : OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
903 : : "Invalid color channel indices");
904 : :
905 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
906 : : {
907 : : // TODO(F3): Convert result to sRGB color space
908 [ # # ]: 0 : const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
909 : : *pOut++ = rendering::ARGBColor(
910 : : nAlpha,
911 : 0 : nAlpha*deviceColor[i+m_nRedIndex],
912 : 0 : nAlpha*deviceColor[i+m_nGreenIndex],
913 : 0 : nAlpha*deviceColor[i+m_nBlueIndex]);
914 : : }
915 : : }
916 : :
917 [ # # ]: 0 : return aRes;
918 : : }
919 : :
920 : 0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
921 : : {
922 [ # # ]: 0 : SolarMutexGuard aGuard;
923 : :
924 : 0 : const sal_Size nLen( rgbColor.getLength() );
925 : 0 : const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
926 : :
927 [ # # ]: 0 : uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
928 [ # # ]: 0 : double* pColors=aRes.getArray();
929 : :
930 [ # # ]: 0 : if( m_bPalette )
931 : : {
932 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
933 : : {
934 : 0 : pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
935 [ # # ]: 0 : BitmapColor(toByteColor(rgbColor[i].Red),
936 [ # # ]: 0 : toByteColor(rgbColor[i].Green),
937 [ # # ][ # # ]: 0 : toByteColor(rgbColor[i].Blue)));
938 [ # # ]: 0 : if( m_nAlphaIndex != -1 )
939 : 0 : pColors[m_nAlphaIndex] = 1.0;
940 : :
941 : 0 : pColors += nComponentsPerPixel;
942 : : }
943 : : }
944 : : else
945 : : {
946 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
947 : : {
948 : 0 : pColors[m_nRedIndex] = rgbColor[i].Red;
949 : 0 : pColors[m_nGreenIndex] = rgbColor[i].Green;
950 : 0 : pColors[m_nBlueIndex] = rgbColor[i].Blue;
951 [ # # ]: 0 : if( m_nAlphaIndex != -1 )
952 : 0 : pColors[m_nAlphaIndex] = 1.0;
953 : :
954 : 0 : pColors += nComponentsPerPixel;
955 : : }
956 : : }
957 [ # # ]: 0 : return aRes;
958 : : }
959 : :
960 : 0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
961 : : {
962 [ # # ]: 0 : SolarMutexGuard aGuard;
963 : :
964 : 0 : const sal_Size nLen( rgbColor.getLength() );
965 : 0 : const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
966 : :
967 [ # # ]: 0 : uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
968 [ # # ]: 0 : double* pColors=aRes.getArray();
969 : :
970 [ # # ]: 0 : if( m_bPalette )
971 : : {
972 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
973 : : {
974 : 0 : pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
975 [ # # ]: 0 : BitmapColor(toByteColor(rgbColor[i].Red),
976 [ # # ]: 0 : toByteColor(rgbColor[i].Green),
977 [ # # ][ # # ]: 0 : toByteColor(rgbColor[i].Blue)));
978 [ # # ]: 0 : if( m_nAlphaIndex != -1 )
979 : 0 : pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
980 : :
981 : 0 : pColors += nComponentsPerPixel;
982 : : }
983 : : }
984 : : else
985 : : {
986 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
987 : : {
988 : 0 : pColors[m_nRedIndex] = rgbColor[i].Red;
989 : 0 : pColors[m_nGreenIndex] = rgbColor[i].Green;
990 : 0 : pColors[m_nBlueIndex] = rgbColor[i].Blue;
991 [ # # ]: 0 : if( m_nAlphaIndex != -1 )
992 : 0 : pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
993 : :
994 : 0 : pColors += nComponentsPerPixel;
995 : : }
996 : : }
997 [ # # ]: 0 : return aRes;
998 : : }
999 : :
1000 : 0 : uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1001 : : {
1002 [ # # ]: 0 : SolarMutexGuard aGuard;
1003 : :
1004 : 0 : const sal_Size nLen( rgbColor.getLength() );
1005 : 0 : const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
1006 : :
1007 [ # # ]: 0 : uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
1008 [ # # ]: 0 : double* pColors=aRes.getArray();
1009 : :
1010 [ # # ]: 0 : if( m_bPalette )
1011 : : {
1012 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1013 : : {
1014 : 0 : const double nAlpha( rgbColor[i].Alpha );
1015 : 0 : pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
1016 [ # # ]: 0 : BitmapColor(toByteColor(rgbColor[i].Red / nAlpha),
1017 [ # # ]: 0 : toByteColor(rgbColor[i].Green / nAlpha),
1018 [ # # ][ # # ]: 0 : toByteColor(rgbColor[i].Blue / nAlpha)));
1019 [ # # ]: 0 : if( m_nAlphaIndex != -1 )
1020 : 0 : pColors[m_nAlphaIndex] = nAlpha;
1021 : :
1022 : 0 : pColors += nComponentsPerPixel;
1023 : : }
1024 : : }
1025 : : else
1026 : : {
1027 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1028 : : {
1029 : 0 : const double nAlpha( rgbColor[i].Alpha );
1030 : 0 : pColors[m_nRedIndex] = rgbColor[i].Red / nAlpha;
1031 : 0 : pColors[m_nGreenIndex] = rgbColor[i].Green / nAlpha;
1032 : 0 : pColors[m_nBlueIndex] = rgbColor[i].Blue / nAlpha;
1033 [ # # ]: 0 : if( m_nAlphaIndex != -1 )
1034 : 0 : pColors[m_nAlphaIndex] = nAlpha;
1035 : :
1036 : 0 : pColors += nComponentsPerPixel;
1037 : : }
1038 : : }
1039 [ # # ]: 0 : return aRes;
1040 : : }
1041 : :
1042 : 0 : sal_Int32 SAL_CALL VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException)
1043 : : {
1044 [ # # ]: 0 : SolarMutexGuard aGuard;
1045 [ # # ]: 0 : return m_nBitsPerOutputPixel;
1046 : : }
1047 : :
1048 : 0 : uno::Sequence< ::sal_Int32 > SAL_CALL VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException)
1049 : : {
1050 [ # # ]: 0 : SolarMutexGuard aGuard;
1051 [ # # ][ # # ]: 0 : return m_aComponentBitCounts;
1052 : : }
1053 : :
1054 : 0 : sal_Int8 SAL_CALL VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException)
1055 : : {
1056 [ # # ]: 0 : SolarMutexGuard aGuard;
1057 [ # # ]: 0 : return m_nEndianness;
1058 : : }
1059 : :
1060 : 0 : uno::Sequence<double> SAL_CALL VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
1061 : : const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1062 : : {
1063 [ # # ][ # # ]: 0 : if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
[ # # ]
1064 : : {
1065 [ # # ]: 0 : SolarMutexGuard aGuard;
1066 : :
1067 : 0 : const sal_Size nLen( deviceColor.getLength() );
1068 : 0 : const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
1069 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
[ # # ][ # # ]
[ # # ]
1070 : : "number of channels no multiple of pixel element count",
1071 : : static_cast<rendering::XBitmapPalette*>(this), 01);
1072 : :
1073 [ # # ]: 0 : uno::Sequence<double> aRes(nLen);
1074 [ # # ]: 0 : double* pOut( aRes.getArray() );
1075 : :
1076 [ # # ]: 0 : if( m_bPalette )
1077 : : {
1078 : : OSL_ENSURE(m_nIndexIndex != -1,
1079 : : "Invalid color channel indices");
1080 [ # # ][ # # ]: 0 : ENSURE_OR_THROW(m_pBmpAcc,
[ # # ][ # # ]
1081 : : "Unable to get BitmapAccess");
1082 : :
1083 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
1084 : : {
1085 : : const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
1086 : 0 : sal::static_int_cast<sal_uInt16>(deviceColor[i+m_nIndexIndex]));
1087 : :
1088 : : // TODO(F3): Convert result to sRGB color space
1089 [ # # ]: 0 : const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
1090 : 0 : *pOut++ = toDoubleColor(aCol.GetRed());
1091 : 0 : *pOut++ = toDoubleColor(aCol.GetGreen());
1092 : 0 : *pOut++ = toDoubleColor(aCol.GetBlue());
1093 : 0 : *pOut++ = nAlpha;
1094 : 0 : }
1095 : : }
1096 : : else
1097 : : {
1098 : : OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
1099 : : "Invalid color channel indices");
1100 : :
1101 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
1102 : : {
1103 : : // TODO(F3): Convert result to sRGB color space
1104 [ # # ]: 0 : const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
1105 : 0 : *pOut++ = deviceColor[i+m_nRedIndex];
1106 : 0 : *pOut++ = deviceColor[i+m_nGreenIndex];
1107 : 0 : *pOut++ = deviceColor[i+m_nBlueIndex];
1108 : 0 : *pOut++ = nAlpha;
1109 : : }
1110 : : }
1111 : :
1112 [ # # ][ # # ]: 0 : return aRes;
[ # # ]
1113 : : }
1114 : : else
1115 : : {
1116 : : // TODO(P3): if we know anything about target
1117 : : // colorspace, this can be greatly sped up
1118 : : uno::Sequence<rendering::ARGBColor> aIntermediate(
1119 [ # # ]: 0 : convertIntegerToARGB(deviceColor));
1120 [ # # ][ # # ]: 0 : return targetColorSpace->convertFromARGB(aIntermediate);
[ # # ]
1121 : : }
1122 : : }
1123 : :
1124 : 0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
1125 : : const uno::Reference< ::rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1126 : : {
1127 [ # # ][ # # ]: 0 : if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
[ # # ]
1128 : : {
1129 : : // it's us, so simply pass-through the data
1130 : 0 : return deviceColor;
1131 : : }
1132 : : else
1133 : : {
1134 : : // TODO(P3): if we know anything about target
1135 : : // colorspace, this can be greatly sped up
1136 : : uno::Sequence<rendering::ARGBColor> aIntermediate(
1137 [ # # ]: 0 : convertIntegerToARGB(deviceColor));
1138 [ # # ][ # # ]: 0 : return targetColorSpace->convertIntegerFromARGB(aIntermediate);
[ # # ]
1139 : : }
1140 : : }
1141 : :
1142 : 0 : uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1143 : : {
1144 [ # # ]: 0 : SolarMutexGuard aGuard;
1145 : :
1146 : 0 : const sal_uInt8* pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
1147 : 0 : const sal_Size nLen( deviceColor.getLength() );
1148 : 0 : const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
1149 : :
1150 [ # # ]: 0 : uno::Sequence< rendering::RGBColor > aRes(nNumColors);
1151 [ # # ]: 0 : rendering::RGBColor* pOut( aRes.getArray() );
1152 : :
1153 [ # # ][ # # ]: 0 : ENSURE_OR_THROW(m_pBmpAcc,
[ # # ][ # # ]
1154 : : "Unable to get BitmapAccess");
1155 : :
1156 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
1157 : : {
1158 : 0 : const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
1159 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
1160 : : {
1161 : : // if palette, index is guaranteed to be 8 bit
1162 : : const BitmapColor aCol =
1163 : : m_bPalette ?
1164 : 0 : m_pBmpAcc->GetPaletteColor(*pIn) :
1165 [ # # ][ # # ]: 0 : m_pBmpAcc->GetPixelFromData(pIn,0);
1166 : :
1167 : : // TODO(F3): Convert result to sRGB color space
1168 : 0 : *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
1169 : 0 : toDoubleColor(aCol.GetGreen()),
1170 : 0 : toDoubleColor(aCol.GetBlue()));
1171 : : // skips alpha
1172 : 0 : pIn += nBytesPerPixel;
1173 : 0 : }
1174 : : }
1175 : : else
1176 : : {
1177 [ # # ]: 0 : for( sal_Int32 i=0; i<nNumColors; ++i )
1178 : : {
1179 : : const BitmapColor aCol =
1180 : : m_bPalette ?
1181 : : m_pBmpAcc->GetPaletteColor(
1182 : : sal::static_int_cast<sal_uInt16>(
1183 : : m_pBmpAcc->GetPixelFromData(
1184 [ # # ][ # # ]: 0 : pIn, i ))) :
[ # # ]
1185 [ # # ][ # # ]: 0 : m_pBmpAcc->GetPixelFromData(pIn, i);
1186 : :
1187 : : // TODO(F3): Convert result to sRGB color space
1188 : 0 : *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
1189 : 0 : toDoubleColor(aCol.GetGreen()),
1190 : 0 : toDoubleColor(aCol.GetBlue()));
1191 : 0 : }
1192 : : }
1193 : :
1194 [ # # ]: 0 : return aRes;
1195 : : }
1196 : :
1197 : 0 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1198 : : {
1199 [ # # ]: 0 : SolarMutexGuard aGuard;
1200 : :
1201 : 0 : const sal_uInt8* pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
1202 : 0 : const sal_Size nLen( deviceColor.getLength() );
1203 : 0 : const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
1204 : :
1205 [ # # ]: 0 : uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
1206 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
1207 : :
1208 [ # # ][ # # ]: 0 : ENSURE_OR_THROW(m_pBmpAcc,
[ # # ][ # # ]
1209 : : "Unable to get BitmapAccess");
1210 : :
1211 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
1212 : : {
1213 : 0 : const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
1214 : 0 : const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
1215 [ # # ][ # # ]: 0 : const sal_uInt8 nAlphaFactor( m_aBmpEx.IsAlpha() ? 1 : 255 );
1216 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
1217 : : {
1218 : : // if palette, index is guaranteed to be 8 bit
1219 : : const BitmapColor aCol =
1220 : : m_bPalette ?
1221 : 0 : m_pBmpAcc->GetPaletteColor(*pIn) :
1222 [ # # ][ # # ]: 0 : m_pBmpAcc->GetPixelFromData(pIn,0);
1223 : :
1224 : : // TODO(F3): Convert result to sRGB color space
1225 : 0 : *pOut++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]),
1226 : 0 : toDoubleColor(aCol.GetRed()),
1227 : 0 : toDoubleColor(aCol.GetGreen()),
1228 : 0 : toDoubleColor(aCol.GetBlue()));
1229 : 0 : pIn += nBytesPerPixel;
1230 : 0 : }
1231 : : }
1232 : : else
1233 : : {
1234 [ # # ]: 0 : for( sal_Int32 i=0; i<nNumColors; ++i )
1235 : : {
1236 : : const BitmapColor aCol =
1237 : : m_bPalette ?
1238 : : m_pBmpAcc->GetPaletteColor(
1239 : : sal::static_int_cast<sal_uInt16>(
1240 : : m_pBmpAcc->GetPixelFromData(
1241 [ # # ][ # # ]: 0 : pIn, i ))) :
[ # # ]
1242 [ # # ][ # # ]: 0 : m_pBmpAcc->GetPixelFromData(pIn, i);
1243 : :
1244 : : // TODO(F3): Convert result to sRGB color space
1245 : : *pOut++ = rendering::ARGBColor(1.0,
1246 : 0 : toDoubleColor(aCol.GetRed()),
1247 : 0 : toDoubleColor(aCol.GetGreen()),
1248 : 0 : toDoubleColor(aCol.GetBlue()));
1249 : 0 : }
1250 : : }
1251 : :
1252 [ # # ]: 0 : return aRes;
1253 : : }
1254 : :
1255 : 0 : uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1256 : : {
1257 [ # # ]: 0 : SolarMutexGuard aGuard;
1258 : :
1259 : 0 : const sal_uInt8* pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
1260 : 0 : const sal_Size nLen( deviceColor.getLength() );
1261 : 0 : const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
1262 : :
1263 [ # # ]: 0 : uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
1264 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
1265 : :
1266 [ # # ][ # # ]: 0 : ENSURE_OR_THROW(m_pBmpAcc,
[ # # ][ # # ]
1267 : : "Unable to get BitmapAccess");
1268 : :
1269 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
1270 : : {
1271 : 0 : const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
1272 : 0 : const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
1273 [ # # ][ # # ]: 0 : const sal_uInt8 nAlphaFactor( m_aBmpEx.IsAlpha() ? 1 : 255 );
1274 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
1275 : : {
1276 : : // if palette, index is guaranteed to be 8 bit
1277 : : const BitmapColor aCol =
1278 : : m_bPalette ?
1279 : 0 : m_pBmpAcc->GetPaletteColor(*pIn) :
1280 [ # # ][ # # ]: 0 : m_pBmpAcc->GetPixelFromData(pIn,0);
1281 : :
1282 : : // TODO(F3): Convert result to sRGB color space
1283 : 0 : const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]) );
1284 : : *pOut++ = rendering::ARGBColor(nAlpha,
1285 : 0 : nAlpha*toDoubleColor(aCol.GetRed()),
1286 : 0 : nAlpha*toDoubleColor(aCol.GetGreen()),
1287 : 0 : nAlpha*toDoubleColor(aCol.GetBlue()));
1288 : 0 : pIn += nBytesPerPixel;
1289 : 0 : }
1290 : : }
1291 : : else
1292 : : {
1293 [ # # ]: 0 : for( sal_Int32 i=0; i<nNumColors; ++i )
1294 : : {
1295 : : const BitmapColor aCol =
1296 : : m_bPalette ?
1297 : : m_pBmpAcc->GetPaletteColor(
1298 : : sal::static_int_cast<sal_uInt16>(
1299 : : m_pBmpAcc->GetPixelFromData(
1300 [ # # ][ # # ]: 0 : pIn, i ))) :
[ # # ]
1301 [ # # ][ # # ]: 0 : m_pBmpAcc->GetPixelFromData(pIn, i);
1302 : :
1303 : : // TODO(F3): Convert result to sRGB color space
1304 : : *pOut++ = rendering::ARGBColor(1.0,
1305 : 0 : toDoubleColor(aCol.GetRed()),
1306 : 0 : toDoubleColor(aCol.GetGreen()),
1307 : 0 : toDoubleColor(aCol.GetBlue()));
1308 : 0 : }
1309 : : }
1310 : :
1311 [ # # ]: 0 : return aRes;
1312 : : }
1313 : :
1314 : 0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1315 : : {
1316 [ # # ]: 0 : SolarMutexGuard aGuard;
1317 : :
1318 : 0 : const sal_Size nLen( rgbColor.getLength() );
1319 : 0 : const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
1320 : :
1321 [ # # ]: 0 : uno::Sequence< sal_Int8 > aRes(nNumBytes);
1322 [ # # ]: 0 : sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray());
1323 : :
1324 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
1325 : : {
1326 : 0 : const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
1327 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1328 : : {
1329 [ # # ]: 0 : const BitmapColor aCol(toByteColor(rgbColor[i].Red),
1330 [ # # ]: 0 : toByteColor(rgbColor[i].Green),
1331 [ # # ]: 0 : toByteColor(rgbColor[i].Blue));
1332 : : const BitmapColor aCol2 =
1333 : : m_bPalette ?
1334 : : BitmapColor(
1335 [ # # ]: 0 : sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
1336 [ # # ]: 0 : aCol;
1337 : :
1338 [ # # ]: 0 : m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
1339 : 0 : pColors += nNonAlphaBytes;
1340 : 0 : *pColors++ = sal_uInt8(255);
1341 : 0 : }
1342 : : }
1343 : : else
1344 : : {
1345 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1346 : : {
1347 [ # # ]: 0 : const BitmapColor aCol(toByteColor(rgbColor[i].Red),
1348 [ # # ]: 0 : toByteColor(rgbColor[i].Green),
1349 [ # # ]: 0 : toByteColor(rgbColor[i].Blue));
1350 : : const BitmapColor aCol2 =
1351 : : m_bPalette ?
1352 : : BitmapColor(
1353 [ # # ]: 0 : sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
1354 [ # # ]: 0 : aCol;
1355 : :
1356 [ # # ]: 0 : m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
1357 : 0 : }
1358 : : }
1359 : :
1360 [ # # ]: 0 : return aRes;
1361 : : }
1362 : :
1363 : 0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1364 : : {
1365 [ # # ]: 0 : SolarMutexGuard aGuard;
1366 : :
1367 : 0 : const sal_Size nLen( rgbColor.getLength() );
1368 : 0 : const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
1369 : :
1370 [ # # ]: 0 : uno::Sequence< sal_Int8 > aRes(nNumBytes);
1371 [ # # ]: 0 : sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray());
1372 : :
1373 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
1374 : : {
1375 : 0 : const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
1376 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1377 : : {
1378 [ # # ]: 0 : const BitmapColor aCol(toByteColor(rgbColor[i].Red),
1379 [ # # ]: 0 : toByteColor(rgbColor[i].Green),
1380 [ # # ]: 0 : toByteColor(rgbColor[i].Blue));
1381 : : const BitmapColor aCol2 =
1382 : : m_bPalette ?
1383 : : BitmapColor(
1384 [ # # ]: 0 : sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
1385 [ # # ]: 0 : aCol;
1386 : :
1387 [ # # ]: 0 : m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
1388 : 0 : pColors += nNonAlphaBytes;
1389 [ # # ]: 0 : *pColors++ = 255 - toByteColor(rgbColor[i].Alpha);
1390 : 0 : }
1391 : : }
1392 : : else
1393 : : {
1394 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1395 : : {
1396 [ # # ]: 0 : const BitmapColor aCol(toByteColor(rgbColor[i].Red),
1397 [ # # ]: 0 : toByteColor(rgbColor[i].Green),
1398 [ # # ]: 0 : toByteColor(rgbColor[i].Blue));
1399 : : const BitmapColor aCol2 =
1400 : : m_bPalette ?
1401 : : BitmapColor(
1402 [ # # ]: 0 : sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
1403 [ # # ]: 0 : aCol;
1404 : :
1405 [ # # ]: 0 : m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
1406 : 0 : }
1407 : : }
1408 : :
1409 [ # # ]: 0 : return aRes;
1410 : : }
1411 : :
1412 : 0 : uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
1413 : : {
1414 [ # # ]: 0 : SolarMutexGuard aGuard;
1415 : :
1416 : 0 : const sal_Size nLen( rgbColor.getLength() );
1417 : 0 : const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
1418 : :
1419 [ # # ]: 0 : uno::Sequence< sal_Int8 > aRes(nNumBytes);
1420 [ # # ]: 0 : sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray());
1421 : :
1422 [ # # ][ # # ]: 0 : if( m_aBmpEx.IsTransparent() )
1423 : : {
1424 : 0 : const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
1425 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1426 : : {
1427 : 0 : const double nAlpha( rgbColor[i].Alpha );
1428 [ # # ]: 0 : const BitmapColor aCol(toByteColor(rgbColor[i].Red / nAlpha),
1429 [ # # ]: 0 : toByteColor(rgbColor[i].Green / nAlpha),
1430 [ # # ]: 0 : toByteColor(rgbColor[i].Blue / nAlpha));
1431 : : const BitmapColor aCol2 =
1432 : : m_bPalette ?
1433 : : BitmapColor(
1434 [ # # ]: 0 : sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
1435 [ # # ]: 0 : aCol;
1436 : :
1437 [ # # ]: 0 : m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
1438 : 0 : pColors += nNonAlphaBytes;
1439 [ # # ]: 0 : *pColors++ = 255 - toByteColor(nAlpha);
1440 : 0 : }
1441 : : }
1442 : : else
1443 : : {
1444 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
1445 : : {
1446 [ # # ]: 0 : const BitmapColor aCol(toByteColor(rgbColor[i].Red),
1447 [ # # ]: 0 : toByteColor(rgbColor[i].Green),
1448 [ # # ]: 0 : toByteColor(rgbColor[i].Blue));
1449 : : const BitmapColor aCol2 =
1450 : : m_bPalette ?
1451 : : BitmapColor(
1452 [ # # ]: 0 : sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
1453 [ # # ]: 0 : aCol;
1454 : :
1455 [ # # ]: 0 : m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
1456 : 0 : }
1457 : : }
1458 : :
1459 [ # # ]: 0 : return aRes;
1460 : : }
1461 : :
1462 : 0 : BitmapEx VclCanvasBitmap::getBitmapEx() const
1463 : : {
1464 : 0 : return m_aBmpEx;
1465 : : }
1466 : :
1467 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|