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 .
20 #include <com/sun/star/util/Endianness.hpp>
21 #include <com/sun/star/rendering/ColorComponentTag.hpp>
22 #include <com/sun/star/rendering/ColorSpaceType.hpp>
23 #include <com/sun/star/rendering/RenderingIntent.hpp>
25 #include <rtl/instance.hxx>
26 #include <osl/mutex.hxx>
28 #include <tools/diagnose_ex.h>
29 #include <canvasbitmap.hxx>
30 #include <vcl/canvastools.hxx>
31 #include <vcl/bmpacc.hxx>
32 #include <vcl/svapp.hxx>
36 using namespace vcl::unotools
;
37 using namespace ::com::sun::star
;
41 // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
43 // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
44 // unrolled loop. See e.g. Hackers Delight, p. 66
45 inline sal_Int32
bitcount( sal_uInt32 val
)
47 val
= val
- ((val
>> 1) & 0x55555555);
48 val
= (val
& 0x33333333) + ((val
>> 2) & 0x33333333);
49 val
= (val
+ (val
>> 4)) & 0x0F0F0F0F;
50 val
= val
+ (val
>> 8);
51 val
= val
+ (val
>> 16);
52 return sal_Int32(val
& 0x0000003F);
56 void VclCanvasBitmap::setComponentInfo( sal_uLong redShift
, sal_uLong greenShift
, sal_uLong blueShift
)
58 // sort channels in increasing order of appearance in the pixel
59 // (starting with the least significant bits)
64 if( redShift
> greenShift
)
66 std::swap(redPos
,greenPos
);
67 if( redShift
> blueShift
)
69 std::swap(redPos
,bluePos
);
70 if( greenShift
> blueShift
)
71 std::swap(greenPos
,bluePos
);
76 if( greenShift
> blueShift
)
78 std::swap(greenPos
,bluePos
);
79 if( redShift
> blueShift
)
80 std::swap(redPos
,bluePos
);
84 m_aComponentTags
.realloc(3);
85 sal_Int8
* pTags
= m_aComponentTags
.getArray();
86 pTags
[redPos
] = rendering::ColorComponentTag::RGB_RED
;
87 pTags
[greenPos
] = rendering::ColorComponentTag::RGB_GREEN
;
88 pTags
[bluePos
] = rendering::ColorComponentTag::RGB_BLUE
;
90 m_aComponentBitCounts
.realloc(3);
91 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
92 pCounts
[redPos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(redShift
));
93 pCounts
[greenPos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(greenShift
));
94 pCounts
[bluePos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(blueShift
));
97 VclCanvasBitmap::VclCanvasBitmap( const BitmapEx
& rBitmap
) :
99 m_aBitmap( rBitmap
.GetBitmap() ),
101 m_pBmpAcc( m_aBitmap
.AcquireReadAccess() ),
104 m_aComponentBitCounts(),
106 m_nBitsPerInputPixel(0),
107 m_nBitsPerOutputPixel(0),
116 if( m_aBmpEx
.IsTransparent() )
118 m_aAlpha
= m_aBmpEx
.IsAlpha() ? m_aBmpEx
.GetAlpha().GetBitmap() : m_aBmpEx
.GetMask();
119 m_pAlphaAcc
= m_aAlpha
.AcquireReadAccess();
122 m_aLayout
.ScanLines
= 0;
123 m_aLayout
.ScanLineBytes
= 0;
124 m_aLayout
.ScanLineStride
= 0;
125 m_aLayout
.PlaneStride
= 0;
126 m_aLayout
.ColorSpace
.clear();
127 m_aLayout
.Palette
.clear();
128 m_aLayout
.IsMsbFirst
= false;
132 m_aLayout
.ScanLines
= m_pBmpAcc
->Height();
133 m_aLayout
.ScanLineBytes
= (m_pBmpAcc
->GetBitCount()*m_pBmpAcc
->Width() + 7) / 8;
134 m_aLayout
.ScanLineStride
= m_pBmpAcc
->GetScanlineSize();
135 m_aLayout
.PlaneStride
= 0;
137 switch( m_pBmpAcc
->GetScanlineFormat() )
139 case BMP_FORMAT_1BIT_MSB_PAL
:
141 m_nBitsPerInputPixel
= 1;
142 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
143 m_aLayout
.IsMsbFirst
= true;
146 case BMP_FORMAT_1BIT_LSB_PAL
:
148 m_nBitsPerInputPixel
= 1;
149 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
150 m_aLayout
.IsMsbFirst
= false;
153 case BMP_FORMAT_4BIT_MSN_PAL
:
155 m_nBitsPerInputPixel
= 4;
156 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
157 m_aLayout
.IsMsbFirst
= true;
160 case BMP_FORMAT_4BIT_LSN_PAL
:
162 m_nBitsPerInputPixel
= 4;
163 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
164 m_aLayout
.IsMsbFirst
= false;
167 case BMP_FORMAT_8BIT_PAL
:
169 m_nBitsPerInputPixel
= 8;
170 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
171 m_aLayout
.IsMsbFirst
= false; // doesn't matter
174 case BMP_FORMAT_8BIT_TC_MASK
:
176 m_nBitsPerInputPixel
= 8;
177 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
178 m_aLayout
.IsMsbFirst
= false; // doesn't matter
179 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
180 m_pBmpAcc
->GetColorMask().GetGreenMask(),
181 m_pBmpAcc
->GetColorMask().GetBlueMask() );
184 case BMP_FORMAT_16BIT_TC_MSB_MASK
:
186 m_nBitsPerInputPixel
= 16;
187 m_nEndianness
= util::Endianness::BIG
;
188 m_aLayout
.IsMsbFirst
= false; // doesn't matter
189 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
190 m_pBmpAcc
->GetColorMask().GetGreenMask(),
191 m_pBmpAcc
->GetColorMask().GetBlueMask() );
194 case BMP_FORMAT_16BIT_TC_LSB_MASK
:
196 m_nBitsPerInputPixel
= 16;
197 m_nEndianness
= util::Endianness::LITTLE
;
198 m_aLayout
.IsMsbFirst
= false; // doesn't matter
199 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
200 m_pBmpAcc
->GetColorMask().GetGreenMask(),
201 m_pBmpAcc
->GetColorMask().GetBlueMask() );
204 case BMP_FORMAT_24BIT_TC_BGR
:
206 m_nBitsPerInputPixel
= 24;
207 m_nEndianness
= util::Endianness::LITTLE
;
208 m_aLayout
.IsMsbFirst
= false; // doesn't matter
209 setComponentInfo( 0xff0000LL
,
214 case BMP_FORMAT_24BIT_TC_RGB
:
216 m_nBitsPerInputPixel
= 24;
217 m_nEndianness
= util::Endianness::LITTLE
;
218 m_aLayout
.IsMsbFirst
= false; // doesn't matter
219 setComponentInfo( 0x0000ffLL
,
224 case BMP_FORMAT_24BIT_TC_MASK
:
226 m_nBitsPerInputPixel
= 24;
227 m_nEndianness
= util::Endianness::LITTLE
;
228 m_aLayout
.IsMsbFirst
= false; // doesn't matter
229 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
230 m_pBmpAcc
->GetColorMask().GetGreenMask(),
231 m_pBmpAcc
->GetColorMask().GetBlueMask() );
234 case BMP_FORMAT_32BIT_TC_ABGR
:
237 m_nBitsPerInputPixel
= 32;
238 m_nEndianness
= util::Endianness::LITTLE
;
239 m_aLayout
.IsMsbFirst
= false; // doesn't matter
241 m_aComponentTags
.realloc(4);
242 sal_Int8
* pTags
= m_aComponentTags
.getArray();
243 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
244 pTags
[1] = rendering::ColorComponentTag::RGB_BLUE
;
245 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
246 pTags
[3] = rendering::ColorComponentTag::RGB_RED
;
248 m_aComponentBitCounts
.realloc(4);
249 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
262 case BMP_FORMAT_32BIT_TC_ARGB
:
265 m_nBitsPerInputPixel
= 32;
266 m_nEndianness
= util::Endianness::LITTLE
;
267 m_aLayout
.IsMsbFirst
= false; // doesn't matter
269 m_aComponentTags
.realloc(4);
270 sal_Int8
* pTags
= m_aComponentTags
.getArray();
271 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
272 pTags
[1] = rendering::ColorComponentTag::RGB_RED
;
273 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
274 pTags
[3] = rendering::ColorComponentTag::RGB_BLUE
;
276 m_aComponentBitCounts
.realloc(4);
277 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
290 case BMP_FORMAT_32BIT_TC_BGRA
:
293 m_nBitsPerInputPixel
= 32;
294 m_nEndianness
= util::Endianness::LITTLE
;
295 m_aLayout
.IsMsbFirst
= false; // doesn't matter
297 m_aComponentTags
.realloc(4);
298 sal_Int8
* pTags
= m_aComponentTags
.getArray();
299 pTags
[0] = rendering::ColorComponentTag::RGB_BLUE
;
300 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
301 pTags
[2] = rendering::ColorComponentTag::RGB_RED
;
302 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
304 m_aComponentBitCounts
.realloc(4);
305 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
318 case BMP_FORMAT_32BIT_TC_RGBA
:
321 m_nBitsPerInputPixel
= 32;
322 m_nEndianness
= util::Endianness::LITTLE
;
323 m_aLayout
.IsMsbFirst
= false; // doesn't matter
325 m_aComponentTags
.realloc(4);
326 sal_Int8
* pTags
= m_aComponentTags
.getArray();
327 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
328 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
329 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
330 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
332 m_aComponentBitCounts
.realloc(4);
333 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
346 case BMP_FORMAT_32BIT_TC_MASK
:
348 m_nBitsPerInputPixel
= 32;
349 m_nEndianness
= util::Endianness::LITTLE
;
350 m_aLayout
.IsMsbFirst
= false; // doesn't matter
351 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
352 m_pBmpAcc
->GetColorMask().GetGreenMask(),
353 m_pBmpAcc
->GetColorMask().GetBlueMask() );
357 OSL_FAIL( "unsupported bitmap format" );
363 m_aComponentTags
.realloc(1);
364 m_aComponentTags
[0] = rendering::ColorComponentTag::INDEX
;
366 m_aComponentBitCounts
.realloc(1);
367 m_aComponentBitCounts
[0] = m_nBitsPerInputPixel
;
372 m_nBitsPerOutputPixel
= m_nBitsPerInputPixel
;
373 if( m_aBmpEx
.IsTransparent() )
375 // TODO(P1): need to interleave alpha with bitmap data -
376 // won't fuss with less-than-8 bit for now
377 m_nBitsPerOutputPixel
= std::max(sal_Int32(8),m_nBitsPerInputPixel
);
379 // check whether alpha goes in front or behind the
380 // bitcount sequence. If pixel format is little endian,
381 // put it behind all the other channels. If it's big
382 // endian, put it in front (because later, the actual data
383 // always gets written after the pixel data)
385 // TODO(Q1): slight catch - in the case of the
386 // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
387 // channels might happen!
388 m_aComponentTags
.realloc(m_aComponentTags
.getLength()+1);
389 m_aComponentTags
[m_aComponentTags
.getLength()-1] = rendering::ColorComponentTag::ALPHA
;
391 m_aComponentBitCounts
.realloc(m_aComponentBitCounts
.getLength()+1);
392 m_aComponentBitCounts
[m_aComponentBitCounts
.getLength()-1] = m_aBmpEx
.IsAlpha() ? 8 : 1;
394 if( m_nEndianness
== util::Endianness::BIG
)
396 // put alpha in front of all the color channels
397 sal_Int8
* pTags
=m_aComponentTags
.getArray();
398 sal_Int32
* pCounts
=m_aComponentBitCounts
.getArray();
400 pTags
+m_aComponentTags
.getLength()-1,
401 pTags
+m_aComponentTags
.getLength());
403 pCounts
+m_aComponentBitCounts
.getLength()-1,
404 pCounts
+m_aComponentBitCounts
.getLength());
412 // always add a full byte to the pixel size, otherwise
413 // pixel packing hell breaks loose.
414 m_nBitsPerOutputPixel
+= 8;
416 // adapt scanline parameters
417 const Size aSize
= m_aBitmap
.GetSizePixel();
418 m_aLayout
.ScanLineBytes
=
419 m_aLayout
.ScanLineStride
= (aSize
.Width()*m_nBitsPerOutputPixel
+ 7)/8;
424 VclCanvasBitmap::~VclCanvasBitmap()
427 Bitmap::ReleaseAccess(m_pAlphaAcc
);
429 Bitmap::ReleaseAccess(m_pBmpAcc
);
433 geometry::IntegerSize2D SAL_CALL
VclCanvasBitmap::getSize() throw (uno::RuntimeException
, std::exception
)
435 SolarMutexGuard aGuard
;
436 return integerSize2DFromSize( m_aBitmap
.GetSizePixel() );
439 sal_Bool SAL_CALL
VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException
, std::exception
)
441 SolarMutexGuard aGuard
;
442 return m_aBmpEx
.IsTransparent();
445 uno::Reference
< rendering::XBitmap
> SAL_CALL
VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D
& newSize
,
446 sal_Bool beFast
) throw (uno::RuntimeException
, std::exception
)
448 SolarMutexGuard aGuard
;
450 BitmapEx
aNewBmp( m_aBitmap
);
451 aNewBmp
.Scale( sizeFromRealSize2D( newSize
), beFast
? BmpScaleFlag::Default
: BmpScaleFlag::BestQuality
);
452 return uno::Reference
<rendering::XBitmap
>( new VclCanvasBitmap( aNewBmp
) );
455 // XIntegerReadOnlyBitmap
456 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getData( rendering::IntegerBitmapLayout
& bitmapLayout
,
457 const geometry::IntegerRectangle2D
& rect
) throw( lang::IndexOutOfBoundsException
,
458 rendering::VolatileContentDestroyedException
,
459 uno::RuntimeException
, std::exception
)
461 SolarMutexGuard aGuard
;
463 bitmapLayout
= getMemoryLayout();
465 const ::Rectangle
aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect
) );
466 if( aRequestedArea
.IsEmpty() )
467 return uno::Sequence
< sal_Int8
>();
469 // Invalid/empty bitmap: no data available
471 throw lang::IndexOutOfBoundsException();
472 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
473 throw lang::IndexOutOfBoundsException();
475 if( aRequestedArea
.Left() < 0 || aRequestedArea
.Top() < 0 ||
476 aRequestedArea
.Right() > m_pBmpAcc
->Width() ||
477 aRequestedArea
.Bottom() > m_pBmpAcc
->Height() )
479 throw lang::IndexOutOfBoundsException();
482 uno::Sequence
< sal_Int8
> aRet
;
483 Rectangle
aRequestedBytes( aRequestedArea
);
485 // adapt to byte boundaries
486 aRequestedBytes
.Left() = aRequestedArea
.Left()*m_nBitsPerOutputPixel
/8;
487 aRequestedBytes
.Right() = (aRequestedArea
.Right()*m_nBitsPerOutputPixel
+ 7)/8;
489 // copy stuff to output sequence
490 aRet
.realloc(aRequestedBytes
.getWidth()*aRequestedBytes
.getHeight());
491 sal_Int8
* pOutBuf
= aRet
.getArray();
493 bitmapLayout
.ScanLines
= aRequestedBytes
.getHeight();
494 bitmapLayout
.ScanLineBytes
=
495 bitmapLayout
.ScanLineStride
= aRequestedBytes
.getWidth();
497 sal_Int32 nScanlineStride
=bitmapLayout
.ScanLineStride
;
498 if( !(m_pBmpAcc
->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN
) )
500 pOutBuf
+= bitmapLayout
.ScanLineStride
*(aRequestedBytes
.getHeight()-1);
501 nScanlineStride
*= -1;
504 if( !m_aBmpEx
.IsTransparent() )
506 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
508 // can return bitmap data as-is
509 for( long y
=aRequestedBytes
.Top(); y
<aRequestedBytes
.Bottom(); ++y
)
511 Scanline pScan
= m_pBmpAcc
->GetScanline(y
);
512 memcpy(pOutBuf
, pScan
+aRequestedBytes
.Left(), aRequestedBytes
.getWidth());
513 pOutBuf
+= nScanlineStride
;
518 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
519 OSL_ENSURE(m_pAlphaAcc
,"Invalid alpha read access");
521 // interleave alpha with bitmap data - note, bitcount is
522 // always integer multiple of 8
523 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
524 "Transparent bitmap bitcount not integer multiple of 8" );
526 for( long y
=aRequestedArea
.Top(); y
<aRequestedArea
.Bottom(); ++y
)
528 sal_Int8
* pOutScan
= pOutBuf
;
530 if( m_nBitsPerInputPixel
< 8 )
532 // input less than a byte - copy via GetPixel()
533 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
535 *pOutScan
++ = m_pBmpAcc
->GetPixelIndex(y
,x
);
536 *pOutScan
++ = m_pAlphaAcc
->GetPixelIndex(y
,x
);
541 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
542 const long nScanlineOffsetLeft(aRequestedArea
.Left()*nNonAlphaBytes
);
543 Scanline pScan
= m_pBmpAcc
->GetScanline(y
) + nScanlineOffsetLeft
;
545 // input integer multiple of byte - copy directly
546 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
548 for( long i
=0; i
<nNonAlphaBytes
; ++i
)
549 *pOutScan
++ = *pScan
++;
550 *pOutScan
++ = m_pAlphaAcc
->GetPixelIndex( y
, x
);
554 pOutBuf
+= nScanlineStride
;
561 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout
& bitmapLayout
,
562 const geometry::IntegerPoint2D
& pos
) throw (lang::IndexOutOfBoundsException
,
563 rendering::VolatileContentDestroyedException
,
564 uno::RuntimeException
, std::exception
)
566 SolarMutexGuard aGuard
;
568 bitmapLayout
= getMemoryLayout();
570 // Invalid/empty bitmap: no data available
572 throw lang::IndexOutOfBoundsException();
573 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
574 throw lang::IndexOutOfBoundsException();
576 if( pos
.X
< 0 || pos
.Y
< 0 ||
577 pos
.X
> m_pBmpAcc
->Width() || pos
.Y
> m_pBmpAcc
->Height() )
579 throw lang::IndexOutOfBoundsException();
582 uno::Sequence
< sal_Int8
> aRet((m_nBitsPerOutputPixel
+ 7)/8);
583 sal_Int8
* pOutBuf
= aRet
.getArray();
585 // copy stuff to output sequence
586 bitmapLayout
.ScanLines
= 1;
587 bitmapLayout
.ScanLineBytes
=
588 bitmapLayout
.ScanLineStride
= aRet
.getLength();
590 const long nScanlineLeftOffset( pos
.X
*m_nBitsPerInputPixel
/8 );
591 if( !m_aBmpEx
.IsTransparent() )
593 assert(m_pBmpAcc
&& "Invalid bmp read access");
595 // can return bitmap data as-is
596 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
597 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, aRet
.getLength() );
601 assert(m_pBmpAcc
&& "Invalid bmp read access");
602 assert(m_pAlphaAcc
&& "Invalid alpha read access");
604 // interleave alpha with bitmap data - note, bitcount is
605 // always integer multiple of 8
606 assert((m_nBitsPerOutputPixel
& 0x07) == 0 &&
607 "Transparent bitmap bitcount not integer multiple of 8" );
609 if( m_nBitsPerInputPixel
< 8 )
611 // input less than a byte - copy via GetPixel()
612 *pOutBuf
++ = m_pBmpAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
613 *pOutBuf
= m_pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
617 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
618 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
620 // input integer multiple of byte - copy directly
621 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, nNonAlphaBytes
);
622 pOutBuf
+= nNonAlphaBytes
;
623 *pOutBuf
++ = m_pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
630 uno::Reference
< rendering::XBitmapPalette
> SAL_CALL
VclCanvasBitmap::getPalette() throw (uno::RuntimeException
)
632 SolarMutexGuard aGuard
;
634 uno::Reference
< XBitmapPalette
> aRet
;
641 rendering::IntegerBitmapLayout SAL_CALL
VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException
, std::exception
)
643 SolarMutexGuard aGuard
;
645 rendering::IntegerBitmapLayout
aLayout( m_aLayout
);
647 // only set references to self on separate copy of
648 // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
649 // a circular reference!
651 aLayout
.Palette
.set( this );
653 aLayout
.ColorSpace
.set( this );
658 sal_Int32 SAL_CALL
VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException
, std::exception
)
660 SolarMutexGuard aGuard
;
665 return m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ;
668 sal_Bool SAL_CALL
VclCanvasBitmap::getIndex( uno::Sequence
< double >& o_entry
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
670 SolarMutexGuard aGuard
;
672 const sal_uInt16
nCount( m_pBmpAcc
?
673 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
674 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
675 if( nIndex
< 0 || nIndex
>= nCount
)
676 throw lang::IndexOutOfBoundsException("Palette index out of range",
677 static_cast<rendering::XBitmapPalette
*>(this));
679 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(sal::static_int_cast
<sal_uInt16
>(nIndex
));
681 double* pColor
=o_entry
.getArray();
682 pColor
[0] = aCol
.GetRed();
683 pColor
[1] = aCol
.GetGreen();
684 pColor
[2] = aCol
.GetBlue();
686 return sal_True
; // no palette transparency here.
689 sal_Bool SAL_CALL
VclCanvasBitmap::setIndex( const uno::Sequence
< double >&, sal_Bool
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, lang::IllegalArgumentException
, uno::RuntimeException
, std::exception
)
691 SolarMutexGuard aGuard
;
693 const sal_uInt16
nCount( m_pBmpAcc
?
694 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
696 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
697 if( nIndex
< 0 || nIndex
>= nCount
)
698 throw lang::IndexOutOfBoundsException("Palette index out of range",
699 static_cast<rendering::XBitmapPalette
*>(this));
701 return sal_False
; // read-only implementation
706 struct PaletteColorSpaceHolder
: public rtl::StaticWithInit
<uno::Reference
<rendering::XColorSpace
>,
707 PaletteColorSpaceHolder
>
709 uno::Reference
<rendering::XColorSpace
> operator()()
711 return vcl::unotools::createStandardColorSpace();
716 uno::Reference
< rendering::XColorSpace
> SAL_CALL
VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException
, std::exception
)
718 // this is the method from XBitmapPalette. Return palette color
720 return PaletteColorSpaceHolder::get();
723 sal_Int8 SAL_CALL
VclCanvasBitmap::getType( ) throw (uno::RuntimeException
, std::exception
)
725 return rendering::ColorSpaceType::RGB
;
728 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException
, std::exception
)
730 SolarMutexGuard aGuard
;
731 return m_aComponentTags
;
734 sal_Int8 SAL_CALL
VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException
, std::exception
)
736 return rendering::RenderingIntent::PERCEPTUAL
;
739 uno::Sequence
< ::beans::PropertyValue
> SAL_CALL
VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException
, std::exception
)
741 return uno::Sequence
< ::beans::PropertyValue
>();
744 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertColorSpace( const uno::Sequence
< double >& deviceColor
,
745 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (uno::RuntimeException
, std::exception
)
747 // TODO(P3): if we know anything about target
748 // colorspace, this can be greatly sped up
749 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
750 convertToARGB(deviceColor
));
751 return targetColorSpace
->convertFromARGB(aIntermediate
);
754 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertToRGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
756 SolarMutexGuard aGuard
;
758 const sal_Size
nLen( deviceColor
.getLength() );
759 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
760 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
761 "number of channels no multiple of pixel element count",
762 static_cast<rendering::XBitmapPalette
*>(this), 01);
764 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/nComponentsPerPixel
);
765 rendering::RGBColor
* pOut( aRes
.getArray() );
769 OSL_ENSURE(m_nIndexIndex
!= -1,
770 "Invalid color channel indices");
771 ENSURE_OR_THROW(m_pBmpAcc
,
772 "Unable to get BitmapAccess");
774 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
776 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
777 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
779 // TODO(F3): Convert result to sRGB color space
780 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
781 toDoubleColor(aCol
.GetGreen()),
782 toDoubleColor(aCol
.GetBlue()));
787 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
788 "Invalid color channel indices");
790 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
792 // TODO(F3): Convert result to sRGB color space
793 *pOut
++ = rendering::RGBColor(
794 deviceColor
[i
+m_nRedIndex
],
795 deviceColor
[i
+m_nGreenIndex
],
796 deviceColor
[i
+m_nBlueIndex
]);
803 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
805 SolarMutexGuard aGuard
;
807 const sal_Size
nLen( deviceColor
.getLength() );
808 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
809 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
810 "number of channels no multiple of pixel element count",
811 static_cast<rendering::XBitmapPalette
*>(this), 01);
813 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
814 rendering::ARGBColor
* pOut( aRes
.getArray() );
818 OSL_ENSURE(m_nIndexIndex
!= -1,
819 "Invalid color channel indices");
820 ENSURE_OR_THROW(m_pBmpAcc
,
821 "Unable to get BitmapAccess");
823 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
825 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
826 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
828 // TODO(F3): Convert result to sRGB color space
829 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
830 *pOut
++ = rendering::ARGBColor(nAlpha
,
831 toDoubleColor(aCol
.GetRed()),
832 toDoubleColor(aCol
.GetGreen()),
833 toDoubleColor(aCol
.GetBlue()));
838 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
839 "Invalid color channel indices");
841 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
843 // TODO(F3): Convert result to sRGB color space
844 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
845 *pOut
++ = rendering::ARGBColor(
847 deviceColor
[i
+m_nRedIndex
],
848 deviceColor
[i
+m_nGreenIndex
],
849 deviceColor
[i
+m_nBlueIndex
]);
856 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToPARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
858 SolarMutexGuard aGuard
;
860 const sal_Size
nLen( deviceColor
.getLength() );
861 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
862 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
863 "number of channels no multiple of pixel element count",
864 static_cast<rendering::XBitmapPalette
*>(this), 01);
866 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
867 rendering::ARGBColor
* pOut( aRes
.getArray() );
871 OSL_ENSURE(m_nIndexIndex
!= -1,
872 "Invalid color channel indices");
873 ENSURE_OR_THROW(m_pBmpAcc
,
874 "Unable to get BitmapAccess");
876 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
878 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
879 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
881 // TODO(F3): Convert result to sRGB color space
882 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
883 *pOut
++ = rendering::ARGBColor(nAlpha
,
884 nAlpha
*toDoubleColor(aCol
.GetRed()),
885 nAlpha
*toDoubleColor(aCol
.GetGreen()),
886 nAlpha
*toDoubleColor(aCol
.GetBlue()));
891 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
892 "Invalid color channel indices");
894 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
896 // TODO(F3): Convert result to sRGB color space
897 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
898 *pOut
++ = rendering::ARGBColor(
900 nAlpha
*deviceColor
[i
+m_nRedIndex
],
901 nAlpha
*deviceColor
[i
+m_nGreenIndex
],
902 nAlpha
*deviceColor
[i
+m_nBlueIndex
]);
909 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
911 SolarMutexGuard aGuard
;
913 const sal_Size
nLen( rgbColor
.getLength() );
914 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
916 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
917 double* pColors
=aRes
.getArray();
921 for( sal_Size i
=0; i
<nLen
; ++i
)
923 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
924 BitmapColor(toByteColor(rgbColor
[i
].Red
),
925 toByteColor(rgbColor
[i
].Green
),
926 toByteColor(rgbColor
[i
].Blue
)));
927 if( m_nAlphaIndex
!= -1 )
928 pColors
[m_nAlphaIndex
] = 1.0;
930 pColors
+= nComponentsPerPixel
;
935 for( sal_Size i
=0; i
<nLen
; ++i
)
937 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
938 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
939 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
940 if( m_nAlphaIndex
!= -1 )
941 pColors
[m_nAlphaIndex
] = 1.0;
943 pColors
+= nComponentsPerPixel
;
949 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
951 SolarMutexGuard aGuard
;
953 const sal_Size
nLen( rgbColor
.getLength() );
954 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
956 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
957 double* pColors
=aRes
.getArray();
961 for( sal_Size i
=0; i
<nLen
; ++i
)
963 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
964 BitmapColor(toByteColor(rgbColor
[i
].Red
),
965 toByteColor(rgbColor
[i
].Green
),
966 toByteColor(rgbColor
[i
].Blue
)));
967 if( m_nAlphaIndex
!= -1 )
968 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
970 pColors
+= nComponentsPerPixel
;
975 for( sal_Size i
=0; i
<nLen
; ++i
)
977 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
978 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
979 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
980 if( m_nAlphaIndex
!= -1 )
981 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
983 pColors
+= nComponentsPerPixel
;
989 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
991 SolarMutexGuard aGuard
;
993 const sal_Size
nLen( rgbColor
.getLength() );
994 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
996 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
997 double* pColors
=aRes
.getArray();
1001 for( sal_Size i
=0; i
<nLen
; ++i
)
1003 const double nAlpha( rgbColor
[i
].Alpha
);
1004 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
1005 BitmapColor(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1006 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1007 toByteColor(rgbColor
[i
].Blue
/ nAlpha
)));
1008 if( m_nAlphaIndex
!= -1 )
1009 pColors
[m_nAlphaIndex
] = nAlpha
;
1011 pColors
+= nComponentsPerPixel
;
1016 for( sal_Size i
=0; i
<nLen
; ++i
)
1018 const double nAlpha( rgbColor
[i
].Alpha
);
1019 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
/ nAlpha
;
1020 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
/ nAlpha
;
1021 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
/ nAlpha
;
1022 if( m_nAlphaIndex
!= -1 )
1023 pColors
[m_nAlphaIndex
] = nAlpha
;
1025 pColors
+= nComponentsPerPixel
;
1031 sal_Int32 SAL_CALL
VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException
, std::exception
)
1033 SolarMutexGuard aGuard
;
1034 return m_nBitsPerOutputPixel
;
1037 uno::Sequence
< ::sal_Int32
> SAL_CALL
VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException
, std::exception
)
1039 SolarMutexGuard aGuard
;
1040 return m_aComponentBitCounts
;
1043 sal_Int8 SAL_CALL
VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException
, std::exception
)
1045 SolarMutexGuard aGuard
;
1046 return m_nEndianness
;
1049 uno::Sequence
<double> SAL_CALL
VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1050 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1052 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1054 SolarMutexGuard aGuard
;
1056 const sal_Size
nLen( deviceColor
.getLength() );
1057 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
1058 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
1059 "number of channels no multiple of pixel element count",
1060 static_cast<rendering::XBitmapPalette
*>(this), 01);
1062 uno::Sequence
<double> aRes(nLen
);
1063 double* pOut( aRes
.getArray() );
1067 OSL_ENSURE(m_nIndexIndex
!= -1,
1068 "Invalid color channel indices");
1069 ENSURE_OR_THROW(m_pBmpAcc
,
1070 "Unable to get BitmapAccess");
1072 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1074 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
1075 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
1077 // TODO(F3): Convert result to sRGB color space
1078 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1079 *pOut
++ = toDoubleColor(aCol
.GetRed());
1080 *pOut
++ = toDoubleColor(aCol
.GetGreen());
1081 *pOut
++ = toDoubleColor(aCol
.GetBlue());
1087 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
1088 "Invalid color channel indices");
1090 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1092 // TODO(F3): Convert result to sRGB color space
1093 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1094 *pOut
++ = deviceColor
[i
+m_nRedIndex
];
1095 *pOut
++ = deviceColor
[i
+m_nGreenIndex
];
1096 *pOut
++ = deviceColor
[i
+m_nBlueIndex
];
1105 // TODO(P3): if we know anything about target
1106 // colorspace, this can be greatly sped up
1107 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1108 convertIntegerToARGB(deviceColor
));
1109 return targetColorSpace
->convertFromARGB(aIntermediate
);
1113 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1114 const uno::Reference
< ::rendering::XIntegerBitmapColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1116 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1118 // it's us, so simply pass-through the data
1123 // TODO(P3): if we know anything about target
1124 // colorspace, this can be greatly sped up
1125 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1126 convertIntegerToARGB(deviceColor
));
1127 return targetColorSpace
->convertIntegerFromARGB(aIntermediate
);
1131 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1133 SolarMutexGuard aGuard
;
1135 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1136 const sal_Size
nLen( deviceColor
.getLength() );
1137 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1139 uno::Sequence
< rendering::RGBColor
> aRes(nNumColors
);
1140 rendering::RGBColor
* pOut( aRes
.getArray() );
1142 ENSURE_OR_THROW(m_pBmpAcc
,
1143 "Unable to get BitmapAccess");
1145 if( m_aBmpEx
.IsTransparent() )
1147 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1148 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1150 // if palette, index is guaranteed to be 8 bit
1151 const BitmapColor aCol
=
1153 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1154 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1156 // TODO(F3): Convert result to sRGB color space
1157 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1158 toDoubleColor(aCol
.GetGreen()),
1159 toDoubleColor(aCol
.GetBlue()));
1161 pIn
+= nBytesPerPixel
;
1166 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1168 const BitmapColor aCol
=
1170 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex()) :
1171 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1173 // TODO(F3): Convert result to sRGB color space
1174 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1175 toDoubleColor(aCol
.GetGreen()),
1176 toDoubleColor(aCol
.GetBlue()));
1183 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1185 SolarMutexGuard aGuard
;
1187 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1188 const sal_Size
nLen( deviceColor
.getLength() );
1189 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1191 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1192 rendering::ARGBColor
* pOut( aRes
.getArray() );
1194 ENSURE_OR_THROW(m_pBmpAcc
,
1195 "Unable to get BitmapAccess");
1197 if( m_aBmpEx
.IsTransparent() )
1199 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1200 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1201 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1202 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1204 // if palette, index is guaranteed to be 8 bit
1205 const BitmapColor aCol
=
1207 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1208 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1210 // TODO(F3): Convert result to sRGB color space
1211 *pOut
++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]),
1212 toDoubleColor(aCol
.GetRed()),
1213 toDoubleColor(aCol
.GetGreen()),
1214 toDoubleColor(aCol
.GetBlue()));
1215 pIn
+= nBytesPerPixel
;
1220 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1222 const BitmapColor aCol
=
1224 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1225 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1227 // TODO(F3): Convert result to sRGB color space
1228 *pOut
++ = rendering::ARGBColor(1.0,
1229 toDoubleColor(aCol
.GetRed()),
1230 toDoubleColor(aCol
.GetGreen()),
1231 toDoubleColor(aCol
.GetBlue()));
1238 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1240 SolarMutexGuard aGuard
;
1242 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1243 const sal_Size
nLen( deviceColor
.getLength() );
1244 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1246 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1247 rendering::ARGBColor
* pOut( aRes
.getArray() );
1249 ENSURE_OR_THROW(m_pBmpAcc
,
1250 "Unable to get BitmapAccess");
1252 if( m_aBmpEx
.IsTransparent() )
1254 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1255 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1256 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1257 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1259 // if palette, index is guaranteed to be 8 bit
1260 const BitmapColor aCol
=
1262 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1263 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1265 // TODO(F3): Convert result to sRGB color space
1266 const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]) );
1267 *pOut
++ = rendering::ARGBColor(nAlpha
,
1268 nAlpha
*toDoubleColor(aCol
.GetRed()),
1269 nAlpha
*toDoubleColor(aCol
.GetGreen()),
1270 nAlpha
*toDoubleColor(aCol
.GetBlue()));
1271 pIn
+= nBytesPerPixel
;
1276 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1278 const BitmapColor aCol
=
1280 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1281 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1283 // TODO(F3): Convert result to sRGB color space
1284 *pOut
++ = rendering::ARGBColor(1.0,
1285 toDoubleColor(aCol
.GetRed()),
1286 toDoubleColor(aCol
.GetGreen()),
1287 toDoubleColor(aCol
.GetBlue()));
1294 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1296 SolarMutexGuard aGuard
;
1298 const sal_Size
nLen( rgbColor
.getLength() );
1299 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1301 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1302 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1304 if( m_aBmpEx
.IsTransparent() )
1306 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1307 for( sal_Size i
=0; i
<nLen
; ++i
)
1309 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1310 toByteColor(rgbColor
[i
].Green
),
1311 toByteColor(rgbColor
[i
].Blue
));
1312 const BitmapColor aCol2
=
1315 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1318 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1319 pColors
+= nNonAlphaBytes
;
1320 *pColors
++ = sal_uInt8(255);
1325 for( sal_Size i
=0; i
<nLen
; ++i
)
1327 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1328 toByteColor(rgbColor
[i
].Green
),
1329 toByteColor(rgbColor
[i
].Blue
));
1330 const BitmapColor aCol2
=
1333 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1336 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1343 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1345 SolarMutexGuard aGuard
;
1347 const sal_Size
nLen( rgbColor
.getLength() );
1348 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1350 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1351 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1353 if( m_aBmpEx
.IsTransparent() )
1355 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1356 for( sal_Size i
=0; i
<nLen
; ++i
)
1358 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1359 toByteColor(rgbColor
[i
].Green
),
1360 toByteColor(rgbColor
[i
].Blue
));
1361 const BitmapColor aCol2
=
1364 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1367 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1368 pColors
+= nNonAlphaBytes
;
1369 *pColors
++ = 255 - toByteColor(rgbColor
[i
].Alpha
);
1374 for( sal_Size i
=0; i
<nLen
; ++i
)
1376 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1377 toByteColor(rgbColor
[i
].Green
),
1378 toByteColor(rgbColor
[i
].Blue
));
1379 const BitmapColor aCol2
=
1382 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1385 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1392 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1394 SolarMutexGuard aGuard
;
1396 const sal_Size
nLen( rgbColor
.getLength() );
1397 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1399 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1400 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1402 if( m_aBmpEx
.IsTransparent() )
1404 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1405 for( sal_Size i
=0; i
<nLen
; ++i
)
1407 const double nAlpha( rgbColor
[i
].Alpha
);
1408 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1409 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1410 toByteColor(rgbColor
[i
].Blue
/ nAlpha
));
1411 const BitmapColor aCol2
=
1414 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1417 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1418 pColors
+= nNonAlphaBytes
;
1419 *pColors
++ = 255 - toByteColor(nAlpha
);
1424 for( sal_Size i
=0; i
<nLen
; ++i
)
1426 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1427 toByteColor(rgbColor
[i
].Green
),
1428 toByteColor(rgbColor
[i
].Blue
));
1429 const BitmapColor aCol2
=
1432 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1435 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1443 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */