1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <com/sun/star/util/Endianness.hpp>
22 #include <com/sun/star/rendering/ColorComponentTag.hpp>
23 #include <com/sun/star/rendering/ColorSpaceType.hpp>
24 #include <com/sun/star/rendering/RenderingIntent.hpp>
26 #include <rtl/instance.hxx>
27 #include <osl/mutex.hxx>
29 #include <tools/diagnose_ex.h>
30 #include <canvasbitmap.hxx>
31 #include <vcl/canvastools.hxx>
32 #include <vcl/bmpacc.hxx>
33 #include <vcl/svapp.hxx>
38 using namespace ::vcl::unotools
;
39 using namespace ::com::sun::star
;
43 // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
45 // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
46 // unrolled loop. See e.g. Hackers Delight, p. 66
47 inline sal_Int32
bitcount( sal_uInt32 val
)
49 val
= val
- ((val
>> 1) & 0x55555555);
50 val
= (val
& 0x33333333) + ((val
>> 2) & 0x33333333);
51 val
= (val
+ (val
>> 4)) & 0x0F0F0F0F;
52 val
= val
+ (val
>> 8);
53 val
= val
+ (val
>> 16);
54 return sal_Int32(val
& 0x0000003F);
58 void VclCanvasBitmap::setComponentInfo( sal_uLong redShift
, sal_uLong greenShift
, sal_uLong blueShift
)
60 // sort channels in increasing order of appearance in the pixel
61 // (starting with the least significant bits)
66 if( redShift
> greenShift
)
68 std::swap(redPos
,greenPos
);
69 if( redShift
> blueShift
)
71 std::swap(redPos
,bluePos
);
72 if( greenShift
> blueShift
)
73 std::swap(greenPos
,bluePos
);
78 if( greenShift
> blueShift
)
80 std::swap(greenPos
,bluePos
);
81 if( redShift
> blueShift
)
82 std::swap(redPos
,bluePos
);
86 m_aComponentTags
.realloc(3);
87 sal_Int8
* pTags
= m_aComponentTags
.getArray();
88 pTags
[redPos
] = rendering::ColorComponentTag::RGB_RED
;
89 pTags
[greenPos
] = rendering::ColorComponentTag::RGB_GREEN
;
90 pTags
[bluePos
] = rendering::ColorComponentTag::RGB_BLUE
;
92 m_aComponentBitCounts
.realloc(3);
93 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
94 pCounts
[redPos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(redShift
));
95 pCounts
[greenPos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(greenShift
));
96 pCounts
[bluePos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(blueShift
));
99 VclCanvasBitmap::VclCanvasBitmap( const BitmapEx
& rBitmap
) :
101 m_aBitmap( rBitmap
.GetBitmap() ),
103 m_pBmpAcc( m_aBitmap
.AcquireReadAccess() ),
106 m_aComponentBitCounts(),
108 m_nBitsPerInputPixel(0),
109 m_nBitsPerOutputPixel(0),
118 if( m_aBmpEx
.IsTransparent() )
120 m_aAlpha
= m_aBmpEx
.IsAlpha() ? m_aBmpEx
.GetAlpha().GetBitmap() : m_aBmpEx
.GetMask();
121 m_pAlphaAcc
= m_aAlpha
.AcquireReadAccess();
124 m_aLayout
.ScanLines
= 0;
125 m_aLayout
.ScanLineBytes
= 0;
126 m_aLayout
.ScanLineStride
= 0;
127 m_aLayout
.PlaneStride
= 0;
128 m_aLayout
.ColorSpace
.clear();
129 m_aLayout
.Palette
.clear();
130 m_aLayout
.IsMsbFirst
= sal_False
;
134 m_aLayout
.ScanLines
= m_pBmpAcc
->Height();
135 m_aLayout
.ScanLineBytes
= (m_pBmpAcc
->GetBitCount()*m_pBmpAcc
->Width() + 7) / 8;
136 m_aLayout
.ScanLineStride
= m_pBmpAcc
->GetScanlineSize();
137 m_aLayout
.PlaneStride
= 0;
139 switch( m_pBmpAcc
->GetScanlineFormat() )
141 case BMP_FORMAT_1BIT_MSB_PAL
:
143 m_nBitsPerInputPixel
= 1;
144 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
145 m_aLayout
.IsMsbFirst
= sal_True
;
148 case BMP_FORMAT_1BIT_LSB_PAL
:
150 m_nBitsPerInputPixel
= 1;
151 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
152 m_aLayout
.IsMsbFirst
= sal_False
;
155 case BMP_FORMAT_4BIT_MSN_PAL
:
157 m_nBitsPerInputPixel
= 4;
158 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
159 m_aLayout
.IsMsbFirst
= sal_True
;
162 case BMP_FORMAT_4BIT_LSN_PAL
:
164 m_nBitsPerInputPixel
= 4;
165 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
166 m_aLayout
.IsMsbFirst
= sal_False
;
169 case BMP_FORMAT_8BIT_PAL
:
171 m_nBitsPerInputPixel
= 8;
172 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
173 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
176 case BMP_FORMAT_8BIT_TC_MASK
:
178 m_nBitsPerInputPixel
= 8;
179 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
180 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
181 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
182 m_pBmpAcc
->GetColorMask().GetGreenMask(),
183 m_pBmpAcc
->GetColorMask().GetBlueMask() );
186 case BMP_FORMAT_16BIT_TC_MSB_MASK
:
188 m_nBitsPerInputPixel
= 16;
189 m_nEndianness
= util::Endianness::BIG
;
190 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
191 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
192 m_pBmpAcc
->GetColorMask().GetGreenMask(),
193 m_pBmpAcc
->GetColorMask().GetBlueMask() );
196 case BMP_FORMAT_16BIT_TC_LSB_MASK
:
198 m_nBitsPerInputPixel
= 16;
199 m_nEndianness
= util::Endianness::LITTLE
;
200 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
201 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
202 m_pBmpAcc
->GetColorMask().GetGreenMask(),
203 m_pBmpAcc
->GetColorMask().GetBlueMask() );
206 case BMP_FORMAT_24BIT_TC_BGR
:
208 m_nBitsPerInputPixel
= 24;
209 m_nEndianness
= util::Endianness::LITTLE
;
210 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
211 setComponentInfo( 0xff0000LL
,
216 case BMP_FORMAT_24BIT_TC_RGB
:
218 m_nBitsPerInputPixel
= 24;
219 m_nEndianness
= util::Endianness::LITTLE
;
220 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
221 setComponentInfo( 0x0000ffLL
,
226 case BMP_FORMAT_24BIT_TC_MASK
:
228 m_nBitsPerInputPixel
= 24;
229 m_nEndianness
= util::Endianness::LITTLE
;
230 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
231 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
232 m_pBmpAcc
->GetColorMask().GetGreenMask(),
233 m_pBmpAcc
->GetColorMask().GetBlueMask() );
236 case BMP_FORMAT_32BIT_TC_ABGR
:
239 m_nBitsPerInputPixel
= 32;
240 m_nEndianness
= util::Endianness::LITTLE
;
241 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
243 m_aComponentTags
.realloc(4);
244 sal_Int8
* pTags
= m_aComponentTags
.getArray();
245 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
246 pTags
[1] = rendering::ColorComponentTag::RGB_BLUE
;
247 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
248 pTags
[3] = rendering::ColorComponentTag::RGB_RED
;
250 m_aComponentBitCounts
.realloc(4);
251 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
264 case BMP_FORMAT_32BIT_TC_ARGB
:
267 m_nBitsPerInputPixel
= 32;
268 m_nEndianness
= util::Endianness::LITTLE
;
269 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
271 m_aComponentTags
.realloc(4);
272 sal_Int8
* pTags
= m_aComponentTags
.getArray();
273 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
274 pTags
[1] = rendering::ColorComponentTag::RGB_RED
;
275 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
276 pTags
[3] = rendering::ColorComponentTag::RGB_BLUE
;
278 m_aComponentBitCounts
.realloc(4);
279 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
292 case BMP_FORMAT_32BIT_TC_BGRA
:
295 m_nBitsPerInputPixel
= 32;
296 m_nEndianness
= util::Endianness::LITTLE
;
297 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
299 m_aComponentTags
.realloc(4);
300 sal_Int8
* pTags
= m_aComponentTags
.getArray();
301 pTags
[0] = rendering::ColorComponentTag::RGB_BLUE
;
302 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
303 pTags
[2] = rendering::ColorComponentTag::RGB_RED
;
304 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
306 m_aComponentBitCounts
.realloc(4);
307 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
320 case BMP_FORMAT_32BIT_TC_RGBA
:
323 m_nBitsPerInputPixel
= 32;
324 m_nEndianness
= util::Endianness::LITTLE
;
325 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
327 m_aComponentTags
.realloc(4);
328 sal_Int8
* pTags
= m_aComponentTags
.getArray();
329 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
330 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
331 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
332 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
334 m_aComponentBitCounts
.realloc(4);
335 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
348 case BMP_FORMAT_32BIT_TC_MASK
:
350 m_nBitsPerInputPixel
= 32;
351 m_nEndianness
= util::Endianness::LITTLE
;
352 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
353 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
354 m_pBmpAcc
->GetColorMask().GetGreenMask(),
355 m_pBmpAcc
->GetColorMask().GetBlueMask() );
359 OSL_FAIL( "unsupported bitmap format" );
365 m_aComponentTags
.realloc(1);
366 m_aComponentTags
[0] = rendering::ColorComponentTag::INDEX
;
368 m_aComponentBitCounts
.realloc(1);
369 m_aComponentBitCounts
[0] = m_nBitsPerInputPixel
;
374 m_nBitsPerOutputPixel
= m_nBitsPerInputPixel
;
375 if( m_aBmpEx
.IsTransparent() )
377 // TODO(P1): need to interleave alpha with bitmap data -
378 // won't fuss with less-than-8 bit for now
379 m_nBitsPerOutputPixel
= std::max(sal_Int32(8),m_nBitsPerInputPixel
);
381 // check whether alpha goes in front or behind the
382 // bitcount sequence. If pixel format is little endian,
383 // put it behind all the other channels. If it's big
384 // endian, put it in front (because later, the actual data
385 // always gets written after the pixel data)
387 // TODO(Q1): slight catch - in the case of the
388 // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
389 // channels might happen!
390 m_aComponentTags
.realloc(m_aComponentTags
.getLength()+1);
391 m_aComponentTags
[m_aComponentTags
.getLength()-1] = rendering::ColorComponentTag::ALPHA
;
393 m_aComponentBitCounts
.realloc(m_aComponentBitCounts
.getLength()+1);
394 m_aComponentBitCounts
[m_aComponentBitCounts
.getLength()-1] = m_aBmpEx
.IsAlpha() ? 8 : 1;
396 if( m_nEndianness
== util::Endianness::BIG
)
398 // put alpha in front of all the color channels
399 sal_Int8
* pTags
=m_aComponentTags
.getArray();
400 sal_Int32
* pCounts
=m_aComponentBitCounts
.getArray();
402 pTags
+m_aComponentTags
.getLength()-1,
403 pTags
+m_aComponentTags
.getLength());
405 pCounts
+m_aComponentBitCounts
.getLength()-1,
406 pCounts
+m_aComponentBitCounts
.getLength());
414 // always add a full byte to the pixel size, otherwise
415 // pixel packing hell breaks loose.
416 m_nBitsPerOutputPixel
+= 8;
418 // adapt scanline parameters
419 const Size aSize
= m_aBitmap
.GetSizePixel();
420 m_aLayout
.ScanLineBytes
=
421 m_aLayout
.ScanLineStride
= (aSize
.Width()*m_nBitsPerOutputPixel
+ 7)/8;
426 VclCanvasBitmap::~VclCanvasBitmap()
429 m_aAlpha
.ReleaseAccess(m_pAlphaAcc
);
431 m_aBitmap
.ReleaseAccess(m_pBmpAcc
);
435 geometry::IntegerSize2D SAL_CALL
VclCanvasBitmap::getSize() throw (uno::RuntimeException
)
437 SolarMutexGuard aGuard
;
438 return integerSize2DFromSize( m_aBitmap
.GetSizePixel() );
441 ::sal_Bool SAL_CALL
VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException
)
443 SolarMutexGuard aGuard
;
444 return m_aBmpEx
.IsTransparent();
447 uno::Reference
< rendering::XBitmap
> SAL_CALL
VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D
& newSize
,
448 sal_Bool beFast
) throw (uno::RuntimeException
)
450 SolarMutexGuard aGuard
;
452 BitmapEx
aNewBmp( m_aBitmap
);
453 aNewBmp
.Scale( sizeFromRealSize2D( newSize
), beFast
? BMP_SCALE_FAST
: BMP_SCALE_DEFAULT
);
454 return uno::Reference
<rendering::XBitmap
>( new VclCanvasBitmap( aNewBmp
) );
457 // XIntegerReadOnlyBitmap
458 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getData( rendering::IntegerBitmapLayout
& bitmapLayout
,
459 const geometry::IntegerRectangle2D
& rect
) throw( lang::IndexOutOfBoundsException
,
460 rendering::VolatileContentDestroyedException
,
461 uno::RuntimeException
)
463 SolarMutexGuard aGuard
;
465 bitmapLayout
= getMemoryLayout();
467 const ::Rectangle
aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect
) );
468 if( aRequestedArea
.IsEmpty() )
469 return uno::Sequence
< sal_Int8
>();
471 // Invalid/empty bitmap: no data available
473 throw lang::IndexOutOfBoundsException();
474 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
475 throw lang::IndexOutOfBoundsException();
477 if( aRequestedArea
.Left() < 0 || aRequestedArea
.Top() < 0 ||
478 aRequestedArea
.Right() > m_pBmpAcc
->Width() ||
479 aRequestedArea
.Bottom() > m_pBmpAcc
->Height() )
481 throw lang::IndexOutOfBoundsException();
484 uno::Sequence
< sal_Int8
> aRet
;
485 Rectangle
aRequestedBytes( aRequestedArea
);
487 // adapt to byte boundaries
488 aRequestedBytes
.Left() = aRequestedArea
.Left()*m_nBitsPerOutputPixel
/8;
489 aRequestedBytes
.Right() = (aRequestedArea
.Right()*m_nBitsPerOutputPixel
+ 7)/8;
491 // copy stuff to output sequence
492 aRet
.realloc(aRequestedBytes
.getWidth()*aRequestedBytes
.getHeight());
493 sal_Int8
* pOutBuf
= aRet
.getArray();
495 bitmapLayout
.ScanLines
= aRequestedBytes
.getHeight();
496 bitmapLayout
.ScanLineBytes
=
497 bitmapLayout
.ScanLineStride
= aRequestedBytes
.getWidth();
499 sal_Int32 nScanlineStride
=bitmapLayout
.ScanLineStride
;
500 if( !(m_pBmpAcc
->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN
) )
502 pOutBuf
+= bitmapLayout
.ScanLineStride
*(aRequestedBytes
.getHeight()-1);
503 nScanlineStride
*= -1;
506 if( !m_aBmpEx
.IsTransparent() )
508 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
510 // can return bitmap data as-is
511 for( long y
=aRequestedBytes
.Top(); y
<aRequestedBytes
.Bottom(); ++y
)
513 Scanline pScan
= m_pBmpAcc
->GetScanline(y
);
514 memcpy(pOutBuf
, pScan
+aRequestedBytes
.Left(), aRequestedBytes
.getWidth());
515 pOutBuf
+= nScanlineStride
;
520 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
521 OSL_ENSURE(m_pAlphaAcc
,"Invalid alpha read access");
523 // interleave alpha with bitmap data - note, bitcount is
524 // always integer multiple of 8
525 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
526 "Transparent bitmap bitcount not integer multiple of 8" );
528 for( long y
=aRequestedArea
.Top(); y
<aRequestedArea
.Bottom(); ++y
)
530 sal_Int8
* pOutScan
= pOutBuf
;
532 if( m_nBitsPerInputPixel
< 8 )
534 // input less than a byte - copy via GetPixel()
535 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
537 *pOutScan
++ = m_pBmpAcc
->GetPixel(y
,x
);
538 *pOutScan
++ = m_pAlphaAcc
->GetPixel(y
,x
);
543 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
544 const long nScanlineOffsetLeft(aRequestedArea
.Left()*nNonAlphaBytes
);
545 Scanline pScan
= m_pBmpAcc
->GetScanline(y
) + nScanlineOffsetLeft
;
547 // input integer multiple of byte - copy directly
548 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
550 for( long i
=0; i
<nNonAlphaBytes
; ++i
)
551 *pOutScan
++ = *pScan
++;
552 *pOutScan
++ = m_pAlphaAcc
->GetPixel(y
,x
);
556 pOutBuf
+= nScanlineStride
;
563 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout
& bitmapLayout
,
564 const geometry::IntegerPoint2D
& pos
) throw (lang::IndexOutOfBoundsException
,
565 rendering::VolatileContentDestroyedException
,
566 uno::RuntimeException
)
568 SolarMutexGuard aGuard
;
570 bitmapLayout
= getMemoryLayout();
572 // Invalid/empty bitmap: no data available
574 throw lang::IndexOutOfBoundsException();
575 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
576 throw lang::IndexOutOfBoundsException();
578 if( pos
.X
< 0 || pos
.Y
< 0 ||
579 pos
.X
> m_pBmpAcc
->Width() || pos
.Y
> m_pBmpAcc
->Height() )
581 throw lang::IndexOutOfBoundsException();
584 uno::Sequence
< sal_Int8
> aRet((m_nBitsPerOutputPixel
+ 7)/8);
585 sal_Int8
* pOutBuf
= aRet
.getArray();
587 // copy stuff to output sequence
588 bitmapLayout
.ScanLines
= 1;
589 bitmapLayout
.ScanLineBytes
=
590 bitmapLayout
.ScanLineStride
= aRet
.getLength();
592 const long nScanlineLeftOffset( pos
.X
*m_nBitsPerInputPixel
/8 );
593 if( !m_aBmpEx
.IsTransparent() )
595 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
597 // can return bitmap data as-is
598 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
599 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, aRet
.getLength() );
603 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
604 OSL_ENSURE(m_pAlphaAcc
,"Invalid alpha read access");
606 // interleave alpha with bitmap data - note, bitcount is
607 // always integer multiple of 8
608 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
609 "Transparent bitmap bitcount not integer multiple of 8" );
611 if( m_nBitsPerInputPixel
< 8 )
613 // input less than a byte - copy via GetPixel()
614 *pOutBuf
++ = m_pBmpAcc
->GetPixel(pos
.Y
,pos
.X
);
615 *pOutBuf
= m_pAlphaAcc
->GetPixel(pos
.Y
,pos
.X
);
619 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
620 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
622 // input integer multiple of byte - copy directly
623 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, nNonAlphaBytes
);
624 pOutBuf
+= nNonAlphaBytes
;
625 *pOutBuf
++ = m_pAlphaAcc
->GetPixel(pos
.Y
,pos
.X
);
632 uno::Reference
< rendering::XBitmapPalette
> SAL_CALL
VclCanvasBitmap::getPalette() throw (uno::RuntimeException
)
634 SolarMutexGuard aGuard
;
636 uno::Reference
< XBitmapPalette
> aRet
;
643 rendering::IntegerBitmapLayout SAL_CALL
VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException
)
645 SolarMutexGuard aGuard
;
647 rendering::IntegerBitmapLayout
aLayout( m_aLayout
);
649 // only set references to self on separate copy of
650 // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
651 // a circular reference!
653 aLayout
.Palette
.set( this );
655 aLayout
.ColorSpace
.set( this );
660 sal_Int32 SAL_CALL
VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException
)
662 SolarMutexGuard aGuard
;
667 return m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ;
670 sal_Bool SAL_CALL
VclCanvasBitmap::getIndex( uno::Sequence
< double >& o_entry
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
672 SolarMutexGuard aGuard
;
674 const sal_uInt16
nCount( m_pBmpAcc
?
675 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
676 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
677 if( nIndex
< 0 || nIndex
>= nCount
)
678 throw lang::IndexOutOfBoundsException(::rtl::OUString("Palette index out of range"),
679 static_cast<rendering::XBitmapPalette
*>(this));
681 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(sal::static_int_cast
<sal_uInt16
>(nIndex
));
683 double* pColor
=o_entry
.getArray();
684 pColor
[0] = aCol
.GetRed();
685 pColor
[1] = aCol
.GetGreen();
686 pColor
[2] = aCol
.GetBlue();
688 return sal_True
; // no palette transparency here.
691 sal_Bool SAL_CALL
VclCanvasBitmap::setIndex( const uno::Sequence
< double >&, sal_Bool
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, lang::IllegalArgumentException
, uno::RuntimeException
)
693 SolarMutexGuard aGuard
;
695 const sal_uInt16
nCount( m_pBmpAcc
?
696 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
698 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
699 if( nIndex
< 0 || nIndex
>= nCount
)
700 throw lang::IndexOutOfBoundsException(::rtl::OUString("Palette index out of range"),
701 static_cast<rendering::XBitmapPalette
*>(this));
703 return sal_False
; // read-only implementation
708 struct PaletteColorSpaceHolder
: public rtl::StaticWithInit
<uno::Reference
<rendering::XColorSpace
>,
709 PaletteColorSpaceHolder
>
711 uno::Reference
<rendering::XColorSpace
> operator()()
713 return vcl::unotools::createStandardColorSpace();
718 uno::Reference
< rendering::XColorSpace
> SAL_CALL
VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException
)
720 // this is the method from XBitmapPalette. Return palette color
722 return PaletteColorSpaceHolder::get();
725 sal_Int8 SAL_CALL
VclCanvasBitmap::getType( ) throw (uno::RuntimeException
)
727 return rendering::ColorSpaceType::RGB
;
730 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException
)
732 SolarMutexGuard aGuard
;
733 return m_aComponentTags
;
736 sal_Int8 SAL_CALL
VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException
)
738 return rendering::RenderingIntent::PERCEPTUAL
;
741 uno::Sequence
< ::beans::PropertyValue
> SAL_CALL
VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException
)
743 return uno::Sequence
< ::beans::PropertyValue
>();
746 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertColorSpace( const uno::Sequence
< double >& deviceColor
,
747 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (uno::RuntimeException
)
749 // TODO(P3): if we know anything about target
750 // colorspace, this can be greatly sped up
751 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
752 convertToARGB(deviceColor
));
753 return targetColorSpace
->convertFromARGB(aIntermediate
);
756 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertToRGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
758 SolarMutexGuard aGuard
;
760 const sal_Size
nLen( deviceColor
.getLength() );
761 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
762 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
763 "number of channels no multiple of pixel element count",
764 static_cast<rendering::XBitmapPalette
*>(this), 01);
766 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/nComponentsPerPixel
);
767 rendering::RGBColor
* pOut( aRes
.getArray() );
771 OSL_ENSURE(m_nIndexIndex
!= -1,
772 "Invalid color channel indices");
773 ENSURE_OR_THROW(m_pBmpAcc
,
774 "Unable to get BitmapAccess");
776 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
778 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
779 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
781 // TODO(F3): Convert result to sRGB color space
782 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
783 toDoubleColor(aCol
.GetGreen()),
784 toDoubleColor(aCol
.GetBlue()));
789 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
790 "Invalid color channel indices");
792 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
794 // TODO(F3): Convert result to sRGB color space
795 *pOut
++ = rendering::RGBColor(
796 deviceColor
[i
+m_nRedIndex
],
797 deviceColor
[i
+m_nGreenIndex
],
798 deviceColor
[i
+m_nBlueIndex
]);
805 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
807 SolarMutexGuard aGuard
;
809 const sal_Size
nLen( deviceColor
.getLength() );
810 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
811 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
812 "number of channels no multiple of pixel element count",
813 static_cast<rendering::XBitmapPalette
*>(this), 01);
815 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
816 rendering::ARGBColor
* pOut( aRes
.getArray() );
820 OSL_ENSURE(m_nIndexIndex
!= -1,
821 "Invalid color channel indices");
822 ENSURE_OR_THROW(m_pBmpAcc
,
823 "Unable to get BitmapAccess");
825 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
827 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
828 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
830 // TODO(F3): Convert result to sRGB color space
831 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
832 *pOut
++ = rendering::ARGBColor(nAlpha
,
833 toDoubleColor(aCol
.GetRed()),
834 toDoubleColor(aCol
.GetGreen()),
835 toDoubleColor(aCol
.GetBlue()));
840 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
841 "Invalid color channel indices");
843 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
845 // TODO(F3): Convert result to sRGB color space
846 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
847 *pOut
++ = rendering::ARGBColor(
849 deviceColor
[i
+m_nRedIndex
],
850 deviceColor
[i
+m_nGreenIndex
],
851 deviceColor
[i
+m_nBlueIndex
]);
858 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToPARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
860 SolarMutexGuard aGuard
;
862 const sal_Size
nLen( deviceColor
.getLength() );
863 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
864 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
865 "number of channels no multiple of pixel element count",
866 static_cast<rendering::XBitmapPalette
*>(this), 01);
868 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
869 rendering::ARGBColor
* pOut( aRes
.getArray() );
873 OSL_ENSURE(m_nIndexIndex
!= -1,
874 "Invalid color channel indices");
875 ENSURE_OR_THROW(m_pBmpAcc
,
876 "Unable to get BitmapAccess");
878 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
880 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
881 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
883 // TODO(F3): Convert result to sRGB color space
884 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
885 *pOut
++ = rendering::ARGBColor(nAlpha
,
886 nAlpha
*toDoubleColor(aCol
.GetRed()),
887 nAlpha
*toDoubleColor(aCol
.GetGreen()),
888 nAlpha
*toDoubleColor(aCol
.GetBlue()));
893 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
894 "Invalid color channel indices");
896 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
898 // TODO(F3): Convert result to sRGB color space
899 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
900 *pOut
++ = rendering::ARGBColor(
902 nAlpha
*deviceColor
[i
+m_nRedIndex
],
903 nAlpha
*deviceColor
[i
+m_nGreenIndex
],
904 nAlpha
*deviceColor
[i
+m_nBlueIndex
]);
911 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
913 SolarMutexGuard aGuard
;
915 const sal_Size
nLen( rgbColor
.getLength() );
916 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
918 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
919 double* pColors
=aRes
.getArray();
923 for( sal_Size i
=0; i
<nLen
; ++i
)
925 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
926 BitmapColor(toByteColor(rgbColor
[i
].Red
),
927 toByteColor(rgbColor
[i
].Green
),
928 toByteColor(rgbColor
[i
].Blue
)));
929 if( m_nAlphaIndex
!= -1 )
930 pColors
[m_nAlphaIndex
] = 1.0;
932 pColors
+= nComponentsPerPixel
;
937 for( sal_Size i
=0; i
<nLen
; ++i
)
939 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
940 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
941 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
942 if( m_nAlphaIndex
!= -1 )
943 pColors
[m_nAlphaIndex
] = 1.0;
945 pColors
+= nComponentsPerPixel
;
951 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
953 SolarMutexGuard aGuard
;
955 const sal_Size
nLen( rgbColor
.getLength() );
956 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
958 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
959 double* pColors
=aRes
.getArray();
963 for( sal_Size i
=0; i
<nLen
; ++i
)
965 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
966 BitmapColor(toByteColor(rgbColor
[i
].Red
),
967 toByteColor(rgbColor
[i
].Green
),
968 toByteColor(rgbColor
[i
].Blue
)));
969 if( m_nAlphaIndex
!= -1 )
970 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
972 pColors
+= nComponentsPerPixel
;
977 for( sal_Size i
=0; i
<nLen
; ++i
)
979 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
980 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
981 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
982 if( m_nAlphaIndex
!= -1 )
983 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
985 pColors
+= nComponentsPerPixel
;
991 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
993 SolarMutexGuard aGuard
;
995 const sal_Size
nLen( rgbColor
.getLength() );
996 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
998 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
999 double* pColors
=aRes
.getArray();
1003 for( sal_Size i
=0; i
<nLen
; ++i
)
1005 const double nAlpha( rgbColor
[i
].Alpha
);
1006 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
1007 BitmapColor(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1008 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1009 toByteColor(rgbColor
[i
].Blue
/ nAlpha
)));
1010 if( m_nAlphaIndex
!= -1 )
1011 pColors
[m_nAlphaIndex
] = nAlpha
;
1013 pColors
+= nComponentsPerPixel
;
1018 for( sal_Size i
=0; i
<nLen
; ++i
)
1020 const double nAlpha( rgbColor
[i
].Alpha
);
1021 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
/ nAlpha
;
1022 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
/ nAlpha
;
1023 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
/ nAlpha
;
1024 if( m_nAlphaIndex
!= -1 )
1025 pColors
[m_nAlphaIndex
] = nAlpha
;
1027 pColors
+= nComponentsPerPixel
;
1033 sal_Int32 SAL_CALL
VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException
)
1035 SolarMutexGuard aGuard
;
1036 return m_nBitsPerOutputPixel
;
1039 uno::Sequence
< ::sal_Int32
> SAL_CALL
VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException
)
1041 SolarMutexGuard aGuard
;
1042 return m_aComponentBitCounts
;
1045 sal_Int8 SAL_CALL
VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException
)
1047 SolarMutexGuard aGuard
;
1048 return m_nEndianness
;
1051 uno::Sequence
<double> SAL_CALL
VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1052 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1054 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1056 SolarMutexGuard aGuard
;
1058 const sal_Size
nLen( deviceColor
.getLength() );
1059 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
1060 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
1061 "number of channels no multiple of pixel element count",
1062 static_cast<rendering::XBitmapPalette
*>(this), 01);
1064 uno::Sequence
<double> aRes(nLen
);
1065 double* pOut( aRes
.getArray() );
1069 OSL_ENSURE(m_nIndexIndex
!= -1,
1070 "Invalid color channel indices");
1071 ENSURE_OR_THROW(m_pBmpAcc
,
1072 "Unable to get BitmapAccess");
1074 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1076 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
1077 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
1079 // TODO(F3): Convert result to sRGB color space
1080 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1081 *pOut
++ = toDoubleColor(aCol
.GetRed());
1082 *pOut
++ = toDoubleColor(aCol
.GetGreen());
1083 *pOut
++ = toDoubleColor(aCol
.GetBlue());
1089 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
1090 "Invalid color channel indices");
1092 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1094 // TODO(F3): Convert result to sRGB color space
1095 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1096 *pOut
++ = deviceColor
[i
+m_nRedIndex
];
1097 *pOut
++ = deviceColor
[i
+m_nGreenIndex
];
1098 *pOut
++ = deviceColor
[i
+m_nBlueIndex
];
1107 // TODO(P3): if we know anything about target
1108 // colorspace, this can be greatly sped up
1109 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1110 convertIntegerToARGB(deviceColor
));
1111 return targetColorSpace
->convertFromARGB(aIntermediate
);
1115 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1116 const uno::Reference
< ::rendering::XIntegerBitmapColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1118 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1120 // it's us, so simply pass-through the data
1125 // TODO(P3): if we know anything about target
1126 // colorspace, this can be greatly sped up
1127 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1128 convertIntegerToARGB(deviceColor
));
1129 return targetColorSpace
->convertIntegerFromARGB(aIntermediate
);
1133 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1135 SolarMutexGuard aGuard
;
1137 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1138 const sal_Size
nLen( deviceColor
.getLength() );
1139 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1141 uno::Sequence
< rendering::RGBColor
> aRes(nNumColors
);
1142 rendering::RGBColor
* pOut( aRes
.getArray() );
1144 ENSURE_OR_THROW(m_pBmpAcc
,
1145 "Unable to get BitmapAccess");
1147 if( m_aBmpEx
.IsTransparent() )
1149 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1150 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1152 // if palette, index is guaranteed to be 8 bit
1153 const BitmapColor aCol
=
1155 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1156 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1158 // TODO(F3): Convert result to sRGB color space
1159 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1160 toDoubleColor(aCol
.GetGreen()),
1161 toDoubleColor(aCol
.GetBlue()));
1163 pIn
+= nBytesPerPixel
;
1168 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1170 const BitmapColor aCol
=
1172 m_pBmpAcc
->GetPaletteColor(
1173 sal::static_int_cast
<sal_uInt16
>(
1174 m_pBmpAcc
->GetPixelFromData(
1176 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1178 // TODO(F3): Convert result to sRGB color space
1179 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1180 toDoubleColor(aCol
.GetGreen()),
1181 toDoubleColor(aCol
.GetBlue()));
1188 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1190 SolarMutexGuard aGuard
;
1192 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1193 const sal_Size
nLen( deviceColor
.getLength() );
1194 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1196 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1197 rendering::ARGBColor
* pOut( aRes
.getArray() );
1199 ENSURE_OR_THROW(m_pBmpAcc
,
1200 "Unable to get BitmapAccess");
1202 if( m_aBmpEx
.IsTransparent() )
1204 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1205 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1206 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1207 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1209 // if palette, index is guaranteed to be 8 bit
1210 const BitmapColor aCol
=
1212 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1213 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1215 // TODO(F3): Convert result to sRGB color space
1216 *pOut
++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]),
1217 toDoubleColor(aCol
.GetRed()),
1218 toDoubleColor(aCol
.GetGreen()),
1219 toDoubleColor(aCol
.GetBlue()));
1220 pIn
+= nBytesPerPixel
;
1225 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1227 const BitmapColor aCol
=
1229 m_pBmpAcc
->GetPaletteColor(
1230 sal::static_int_cast
<sal_uInt16
>(
1231 m_pBmpAcc
->GetPixelFromData(
1233 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1235 // TODO(F3): Convert result to sRGB color space
1236 *pOut
++ = rendering::ARGBColor(1.0,
1237 toDoubleColor(aCol
.GetRed()),
1238 toDoubleColor(aCol
.GetGreen()),
1239 toDoubleColor(aCol
.GetBlue()));
1246 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1248 SolarMutexGuard aGuard
;
1250 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1251 const sal_Size
nLen( deviceColor
.getLength() );
1252 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1254 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1255 rendering::ARGBColor
* pOut( aRes
.getArray() );
1257 ENSURE_OR_THROW(m_pBmpAcc
,
1258 "Unable to get BitmapAccess");
1260 if( m_aBmpEx
.IsTransparent() )
1262 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1263 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1264 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1265 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1267 // if palette, index is guaranteed to be 8 bit
1268 const BitmapColor aCol
=
1270 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1271 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1273 // TODO(F3): Convert result to sRGB color space
1274 const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]) );
1275 *pOut
++ = rendering::ARGBColor(nAlpha
,
1276 nAlpha
*toDoubleColor(aCol
.GetRed()),
1277 nAlpha
*toDoubleColor(aCol
.GetGreen()),
1278 nAlpha
*toDoubleColor(aCol
.GetBlue()));
1279 pIn
+= nBytesPerPixel
;
1284 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1286 const BitmapColor aCol
=
1288 m_pBmpAcc
->GetPaletteColor(
1289 sal::static_int_cast
<sal_uInt16
>(
1290 m_pBmpAcc
->GetPixelFromData(
1292 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1294 // TODO(F3): Convert result to sRGB color space
1295 *pOut
++ = rendering::ARGBColor(1.0,
1296 toDoubleColor(aCol
.GetRed()),
1297 toDoubleColor(aCol
.GetGreen()),
1298 toDoubleColor(aCol
.GetBlue()));
1305 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1307 SolarMutexGuard aGuard
;
1309 const sal_Size
nLen( rgbColor
.getLength() );
1310 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1312 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1313 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1315 if( m_aBmpEx
.IsTransparent() )
1317 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1318 for( sal_Size i
=0; i
<nLen
; ++i
)
1320 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1321 toByteColor(rgbColor
[i
].Green
),
1322 toByteColor(rgbColor
[i
].Blue
));
1323 const BitmapColor aCol2
=
1326 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1329 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1330 pColors
+= nNonAlphaBytes
;
1331 *pColors
++ = sal_uInt8(255);
1336 for( sal_Size i
=0; i
<nLen
; ++i
)
1338 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1339 toByteColor(rgbColor
[i
].Green
),
1340 toByteColor(rgbColor
[i
].Blue
));
1341 const BitmapColor aCol2
=
1344 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1347 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1354 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1356 SolarMutexGuard aGuard
;
1358 const sal_Size
nLen( rgbColor
.getLength() );
1359 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1361 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1362 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1364 if( m_aBmpEx
.IsTransparent() )
1366 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1367 for( sal_Size i
=0; i
<nLen
; ++i
)
1369 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1370 toByteColor(rgbColor
[i
].Green
),
1371 toByteColor(rgbColor
[i
].Blue
));
1372 const BitmapColor aCol2
=
1375 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1378 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1379 pColors
+= nNonAlphaBytes
;
1380 *pColors
++ = 255 - toByteColor(rgbColor
[i
].Alpha
);
1385 for( sal_Size i
=0; i
<nLen
; ++i
)
1387 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1388 toByteColor(rgbColor
[i
].Green
),
1389 toByteColor(rgbColor
[i
].Blue
));
1390 const BitmapColor aCol2
=
1393 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1396 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1403 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1405 SolarMutexGuard aGuard
;
1407 const sal_Size
nLen( rgbColor
.getLength() );
1408 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1410 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1411 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1413 if( m_aBmpEx
.IsTransparent() )
1415 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1416 for( sal_Size i
=0; i
<nLen
; ++i
)
1418 const double nAlpha( rgbColor
[i
].Alpha
);
1419 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1420 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1421 toByteColor(rgbColor
[i
].Blue
/ nAlpha
));
1422 const BitmapColor aCol2
=
1425 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1428 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1429 pColors
+= nNonAlphaBytes
;
1430 *pColors
++ = 255 - toByteColor(nAlpha
);
1435 for( sal_Size i
=0; i
<nLen
; ++i
)
1437 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1438 toByteColor(rgbColor
[i
].Green
),
1439 toByteColor(rgbColor
[i
].Blue
));
1440 const BitmapColor aCol2
=
1443 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1446 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1453 BitmapEx
VclCanvasBitmap::getBitmapEx() const
1458 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */