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 <sal/config.h>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <com/sun/star/util/Endianness.hpp>
24 #include <com/sun/star/rendering/ColorComponentTag.hpp>
25 #include <com/sun/star/rendering/ColorSpaceType.hpp>
26 #include <com/sun/star/rendering/RenderingIntent.hpp>
28 #include <rtl/instance.hxx>
30 #include <tools/diagnose_ex.h>
31 #include <canvasbitmap.hxx>
32 #include <vcl/canvastools.hxx>
33 #include <vcl/bitmapaccess.hxx>
34 #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 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_uInt32 redShift
, sal_uInt32 greenShift
, sal_uInt32 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(redShift
);
95 pCounts
[greenPos
] = bitcount(greenShift
);
96 pCounts
[bluePos
] = bitcount(blueShift
);
99 VclCanvasBitmap::VclCanvasBitmap( const BitmapEx
& rBitmap
) :
101 m_aBitmap( rBitmap
.GetBitmap() ),
103 m_pBmpAcc( m_aBitmap
),
105 m_aComponentBitCounts(),
107 m_nBitsPerInputPixel(0),
108 m_nBitsPerOutputPixel(0),
117 if( m_aBmpEx
.IsTransparent() )
119 m_aAlpha
= m_aBmpEx
.IsAlpha() ? m_aBmpEx
.GetAlpha().GetBitmap() : m_aBmpEx
.GetMask();
120 m_pAlphaAcc
= Bitmap::ScopedReadAccess(m_aAlpha
);
123 m_aLayout
.ScanLines
= 0;
124 m_aLayout
.ScanLineBytes
= 0;
125 m_aLayout
.ScanLineStride
= 0;
126 m_aLayout
.PlaneStride
= 0;
127 m_aLayout
.ColorSpace
.clear();
128 m_aLayout
.Palette
.clear();
129 m_aLayout
.IsMsbFirst
= 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 ScanlineFormat::N1BitMsbPal
:
143 m_nBitsPerInputPixel
= 1;
144 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
145 m_aLayout
.IsMsbFirst
= true;
148 case ScanlineFormat::N1BitLsbPal
:
150 m_nBitsPerInputPixel
= 1;
151 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
152 m_aLayout
.IsMsbFirst
= false;
155 case ScanlineFormat::N4BitMsnPal
:
157 m_nBitsPerInputPixel
= 4;
158 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
159 m_aLayout
.IsMsbFirst
= true;
162 case ScanlineFormat::N4BitLsnPal
:
164 m_nBitsPerInputPixel
= 4;
165 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
166 m_aLayout
.IsMsbFirst
= false;
169 case ScanlineFormat::N8BitPal
:
171 m_nBitsPerInputPixel
= 8;
172 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
173 m_aLayout
.IsMsbFirst
= false; // doesn't matter
176 case ScanlineFormat::N24BitTcBgr
:
178 m_nBitsPerInputPixel
= 24;
179 m_nEndianness
= util::Endianness::LITTLE
;
180 m_aLayout
.IsMsbFirst
= false; // doesn't matter
181 setComponentInfo( static_cast<sal_uInt32
>(0xff0000UL
),
182 static_cast<sal_uInt32
>(0x00ff00UL
),
183 static_cast<sal_uInt32
>(0x0000ffUL
) );
186 case ScanlineFormat::N24BitTcRgb
:
188 m_nBitsPerInputPixel
= 24;
189 m_nEndianness
= util::Endianness::LITTLE
;
190 m_aLayout
.IsMsbFirst
= false; // doesn't matter
191 setComponentInfo( static_cast<sal_uInt32
>(0x0000ffUL
),
192 static_cast<sal_uInt32
>(0x00ff00UL
),
193 static_cast<sal_uInt32
>(0xff0000UL
) );
196 case ScanlineFormat::N32BitTcAbgr
:
199 m_nBitsPerInputPixel
= 32;
200 m_nEndianness
= util::Endianness::LITTLE
;
201 m_aLayout
.IsMsbFirst
= false; // doesn't matter
203 m_aComponentTags
.realloc(4);
204 sal_Int8
* pTags
= m_aComponentTags
.getArray();
205 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
206 pTags
[1] = rendering::ColorComponentTag::RGB_BLUE
;
207 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
208 pTags
[3] = rendering::ColorComponentTag::RGB_RED
;
210 m_aComponentBitCounts
.realloc(4);
211 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
224 case ScanlineFormat::N32BitTcArgb
:
227 m_nBitsPerInputPixel
= 32;
228 m_nEndianness
= util::Endianness::LITTLE
;
229 m_aLayout
.IsMsbFirst
= false; // doesn't matter
231 m_aComponentTags
.realloc(4);
232 sal_Int8
* pTags
= m_aComponentTags
.getArray();
233 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
234 pTags
[1] = rendering::ColorComponentTag::RGB_RED
;
235 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
236 pTags
[3] = rendering::ColorComponentTag::RGB_BLUE
;
238 m_aComponentBitCounts
.realloc(4);
239 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
252 case ScanlineFormat::N32BitTcBgra
:
255 m_nBitsPerInputPixel
= 32;
256 m_nEndianness
= util::Endianness::LITTLE
;
257 m_aLayout
.IsMsbFirst
= false; // doesn't matter
259 m_aComponentTags
.realloc(4);
260 sal_Int8
* pTags
= m_aComponentTags
.getArray();
261 pTags
[0] = rendering::ColorComponentTag::RGB_BLUE
;
262 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
263 pTags
[2] = rendering::ColorComponentTag::RGB_RED
;
264 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
266 m_aComponentBitCounts
.realloc(4);
267 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
280 case ScanlineFormat::N32BitTcRgba
:
283 m_nBitsPerInputPixel
= 32;
284 m_nEndianness
= util::Endianness::LITTLE
;
285 m_aLayout
.IsMsbFirst
= false; // doesn't matter
287 m_aComponentTags
.realloc(4);
288 sal_Int8
* pTags
= m_aComponentTags
.getArray();
289 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
290 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
291 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
292 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
294 m_aComponentBitCounts
.realloc(4);
295 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
308 case ScanlineFormat::N32BitTcMask
:
310 m_nBitsPerInputPixel
= 32;
311 m_nEndianness
= util::Endianness::LITTLE
;
312 m_aLayout
.IsMsbFirst
= false; // doesn't matter
313 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
314 m_pBmpAcc
->GetColorMask().GetGreenMask(),
315 m_pBmpAcc
->GetColorMask().GetBlueMask() );
319 OSL_FAIL( "unsupported bitmap format" );
325 m_aComponentTags
.realloc(1);
326 m_aComponentTags
[0] = rendering::ColorComponentTag::INDEX
;
328 m_aComponentBitCounts
.realloc(1);
329 m_aComponentBitCounts
[0] = m_nBitsPerInputPixel
;
334 m_nBitsPerOutputPixel
= m_nBitsPerInputPixel
;
335 if( !m_aBmpEx
.IsTransparent() )
338 // TODO(P1): need to interleave alpha with bitmap data -
339 // won't fuss with less-than-8 bit for now
340 m_nBitsPerOutputPixel
= std::max(sal_Int32(8),m_nBitsPerInputPixel
);
342 // check whether alpha goes in front or behind the
343 // bitcount sequence. If pixel format is little endian,
344 // put it behind all the other channels. If it's big
345 // endian, put it in front (because later, the actual data
346 // always gets written after the pixel data)
348 // TODO(Q1): slight catch - in the case of the
349 // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
350 // channels might happen!
351 m_aComponentTags
.realloc(m_aComponentTags
.getLength()+1);
352 m_aComponentTags
[m_aComponentTags
.getLength()-1] = rendering::ColorComponentTag::ALPHA
;
354 m_aComponentBitCounts
.realloc(m_aComponentBitCounts
.getLength()+1);
355 m_aComponentBitCounts
[m_aComponentBitCounts
.getLength()-1] = m_aBmpEx
.IsAlpha() ? 8 : 1;
357 if( m_nEndianness
== util::Endianness::BIG
)
359 // put alpha in front of all the color channels
360 sal_Int8
* pTags
=m_aComponentTags
.getArray();
361 sal_Int32
* pCounts
=m_aComponentBitCounts
.getArray();
363 pTags
+m_aComponentTags
.getLength()-1,
364 pTags
+m_aComponentTags
.getLength());
366 pCounts
+m_aComponentBitCounts
.getLength()-1,
367 pCounts
+m_aComponentBitCounts
.getLength());
375 // always add a full byte to the pixel size, otherwise
376 // pixel packing hell breaks loose.
377 m_nBitsPerOutputPixel
+= 8;
379 // adapt scanline parameters
380 const Size aSize
= m_aBitmap
.GetSizePixel();
381 m_aLayout
.ScanLineBytes
=
382 m_aLayout
.ScanLineStride
= (aSize
.Width()*m_nBitsPerOutputPixel
+ 7)/8;
385 VclCanvasBitmap::~VclCanvasBitmap()
390 geometry::IntegerSize2D SAL_CALL
VclCanvasBitmap::getSize()
392 SolarMutexGuard aGuard
;
393 return integerSize2DFromSize( m_aBitmap
.GetSizePixel() );
396 sal_Bool SAL_CALL
VclCanvasBitmap::hasAlpha()
398 SolarMutexGuard aGuard
;
399 return m_aBmpEx
.IsTransparent();
402 uno::Reference
< rendering::XBitmap
> SAL_CALL
VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D
& newSize
,
405 SolarMutexGuard aGuard
;
407 BitmapEx
aNewBmp( m_aBitmap
);
408 aNewBmp
.Scale( sizeFromRealSize2D( newSize
), beFast
? BmpScaleFlag::Default
: BmpScaleFlag::BestQuality
);
409 return uno::Reference
<rendering::XBitmap
>( new VclCanvasBitmap( aNewBmp
) );
412 // XIntegerReadOnlyBitmap
413 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getData( rendering::IntegerBitmapLayout
& bitmapLayout
,
414 const geometry::IntegerRectangle2D
& rect
)
416 SolarMutexGuard aGuard
;
418 bitmapLayout
= getMemoryLayout();
420 const ::tools::Rectangle
aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect
) );
421 if( aRequestedArea
.IsEmpty() )
422 return uno::Sequence
< sal_Int8
>();
424 // Invalid/empty bitmap: no data available
426 throw lang::IndexOutOfBoundsException();
427 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
428 throw lang::IndexOutOfBoundsException();
430 if( aRequestedArea
.Left() < 0 || aRequestedArea
.Top() < 0 ||
431 aRequestedArea
.Right() > m_pBmpAcc
->Width() ||
432 aRequestedArea
.Bottom() > m_pBmpAcc
->Height() )
434 throw lang::IndexOutOfBoundsException();
437 uno::Sequence
< sal_Int8
> aRet
;
438 tools::Rectangle
aRequestedBytes( aRequestedArea
);
440 // adapt to byte boundaries
441 aRequestedBytes
.SetLeft( aRequestedArea
.Left()*m_nBitsPerOutputPixel
/8 );
442 aRequestedBytes
.SetRight( (aRequestedArea
.Right()*m_nBitsPerOutputPixel
+ 7)/8 );
444 // copy stuff to output sequence
445 aRet
.realloc(aRequestedBytes
.getWidth()*aRequestedBytes
.getHeight());
446 sal_Int8
* pOutBuf
= aRet
.getArray();
448 bitmapLayout
.ScanLines
= aRequestedBytes
.getHeight();
449 bitmapLayout
.ScanLineBytes
=
450 bitmapLayout
.ScanLineStride
= aRequestedBytes
.getWidth();
452 sal_Int32 nScanlineStride
=bitmapLayout
.ScanLineStride
;
453 if( !(m_pBmpAcc
->GetScanlineFormat() & ScanlineFormat::TopDown
) )
455 pOutBuf
+= bitmapLayout
.ScanLineStride
*(aRequestedBytes
.getHeight()-1);
456 nScanlineStride
*= -1;
459 if( !m_aBmpEx
.IsTransparent() )
461 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
463 // can return bitmap data as-is
464 for( tools::Long y
=aRequestedBytes
.Top(); y
<aRequestedBytes
.Bottom(); ++y
)
466 Scanline pScan
= m_pBmpAcc
->GetScanline(y
);
467 memcpy(pOutBuf
, pScan
+aRequestedBytes
.Left(), aRequestedBytes
.getWidth());
468 pOutBuf
+= nScanlineStride
;
473 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
474 OSL_ENSURE(m_pAlphaAcc
,"Invalid alpha read access");
476 // interleave alpha with bitmap data - note, bitcount is
477 // always integer multiple of 8
478 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
479 "Transparent bitmap bitcount not integer multiple of 8" );
481 for( tools::Long y
=aRequestedArea
.Top(); y
<aRequestedArea
.Bottom(); ++y
)
483 sal_Int8
* pOutScan
= pOutBuf
;
485 if( m_nBitsPerInputPixel
< 8 )
487 // input less than a byte - copy via GetPixel()
488 for( tools::Long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
490 *pOutScan
++ = m_pBmpAcc
->GetPixelIndex(y
,x
);
491 *pOutScan
++ = m_pAlphaAcc
->GetPixelIndex(y
,x
);
496 const tools::Long
nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
497 const tools::Long
nScanlineOffsetLeft(aRequestedArea
.Left()*nNonAlphaBytes
);
498 Scanline pScan
= m_pBmpAcc
->GetScanline(y
) + nScanlineOffsetLeft
;
499 Scanline pScanlineAlpha
= m_pAlphaAcc
->GetScanline( y
);
501 // input integer multiple of byte - copy directly
502 for( tools::Long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
504 for( tools::Long i
=0; i
<nNonAlphaBytes
; ++i
)
505 *pOutScan
++ = *pScan
++;
506 *pOutScan
++ = m_pAlphaAcc
->GetIndexFromData( pScanlineAlpha
, x
);
510 pOutBuf
+= nScanlineStride
;
517 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout
& bitmapLayout
,
518 const geometry::IntegerPoint2D
& pos
)
520 SolarMutexGuard aGuard
;
522 bitmapLayout
= getMemoryLayout();
524 // Invalid/empty bitmap: no data available
526 throw lang::IndexOutOfBoundsException();
527 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
528 throw lang::IndexOutOfBoundsException();
530 if( pos
.X
< 0 || pos
.Y
< 0 ||
531 pos
.X
> m_pBmpAcc
->Width() || pos
.Y
> m_pBmpAcc
->Height() )
533 throw lang::IndexOutOfBoundsException();
536 uno::Sequence
< sal_Int8
> aRet((m_nBitsPerOutputPixel
+ 7)/8);
537 sal_Int8
* pOutBuf
= aRet
.getArray();
539 // copy stuff to output sequence
540 bitmapLayout
.ScanLines
= 1;
541 bitmapLayout
.ScanLineBytes
=
542 bitmapLayout
.ScanLineStride
= aRet
.getLength();
544 const tools::Long
nScanlineLeftOffset( pos
.X
*m_nBitsPerInputPixel
/8 );
545 if( !m_aBmpEx
.IsTransparent() )
547 assert(m_pBmpAcc
&& "Invalid bmp read access");
549 // can return bitmap data as-is
550 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
551 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, aRet
.getLength() );
555 assert(m_pBmpAcc
&& "Invalid bmp read access");
556 assert(m_pAlphaAcc
&& "Invalid alpha read access");
558 // interleave alpha with bitmap data - note, bitcount is
559 // always integer multiple of 8
560 assert((m_nBitsPerOutputPixel
& 0x07) == 0 &&
561 "Transparent bitmap bitcount not integer multiple of 8" );
563 if( m_nBitsPerInputPixel
< 8 )
565 // input less than a byte - copy via GetPixel()
566 *pOutBuf
++ = m_pBmpAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
567 *pOutBuf
= m_pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
571 const tools::Long
nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
572 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
574 // input integer multiple of byte - copy directly
575 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, nNonAlphaBytes
);
576 pOutBuf
+= nNonAlphaBytes
;
577 *pOutBuf
++ = m_pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
584 uno::Reference
< rendering::XBitmapPalette
> VclCanvasBitmap::getPalette()
586 SolarMutexGuard aGuard
;
588 uno::Reference
< XBitmapPalette
> aRet
;
595 rendering::IntegerBitmapLayout SAL_CALL
VclCanvasBitmap::getMemoryLayout()
597 SolarMutexGuard aGuard
;
599 rendering::IntegerBitmapLayout
aLayout( m_aLayout
);
601 // only set references to self on separate copy of
602 // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
603 // a circular reference!
605 aLayout
.Palette
.set( this );
607 aLayout
.ColorSpace
.set( this );
612 sal_Int32 SAL_CALL
VclCanvasBitmap::getNumberOfEntries()
614 SolarMutexGuard aGuard
;
619 return m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ;
622 sal_Bool SAL_CALL
VclCanvasBitmap::getIndex( uno::Sequence
< double >& o_entry
, sal_Int32 nIndex
)
624 SolarMutexGuard aGuard
;
626 const sal_uInt16
nCount( m_pBmpAcc
?
627 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
628 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
629 if( nIndex
< 0 || nIndex
>= nCount
)
630 throw lang::IndexOutOfBoundsException("Palette index out of range",
631 static_cast<rendering::XBitmapPalette
*>(this));
633 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(sal::static_int_cast
<sal_uInt16
>(nIndex
));
635 double* pColor
=o_entry
.getArray();
636 pColor
[0] = aCol
.GetRed();
637 pColor
[1] = aCol
.GetGreen();
638 pColor
[2] = aCol
.GetBlue();
640 return true; // no palette transparency here.
643 sal_Bool SAL_CALL
VclCanvasBitmap::setIndex( const uno::Sequence
< double >&, sal_Bool
, sal_Int32 nIndex
)
645 SolarMutexGuard aGuard
;
647 const sal_uInt16
nCount( m_pBmpAcc
?
648 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
650 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
651 if( nIndex
< 0 || nIndex
>= nCount
)
652 throw lang::IndexOutOfBoundsException("Palette index out of range",
653 static_cast<rendering::XBitmapPalette
*>(this));
655 return false; // read-only implementation
660 struct PaletteColorSpaceHolder
: public rtl::StaticWithInit
<uno::Reference
<rendering::XColorSpace
>,
661 PaletteColorSpaceHolder
>
663 uno::Reference
<rendering::XColorSpace
> operator()()
665 return vcl::unotools::createStandardColorSpace();
670 uno::Reference
< rendering::XColorSpace
> SAL_CALL
VclCanvasBitmap::getColorSpace( )
672 // this is the method from XBitmapPalette. Return palette color
674 return PaletteColorSpaceHolder::get();
677 sal_Int8 SAL_CALL
VclCanvasBitmap::getType( )
679 return rendering::ColorSpaceType::RGB
;
682 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::getComponentTags( )
684 SolarMutexGuard aGuard
;
685 return m_aComponentTags
;
688 sal_Int8 SAL_CALL
VclCanvasBitmap::getRenderingIntent( )
690 return rendering::RenderingIntent::PERCEPTUAL
;
693 uno::Sequence
< ::beans::PropertyValue
> SAL_CALL
VclCanvasBitmap::getProperties( )
695 return uno::Sequence
< ::beans::PropertyValue
>();
698 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertColorSpace( const uno::Sequence
< double >& deviceColor
,
699 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
)
701 // TODO(P3): if we know anything about target
702 // colorspace, this can be greatly sped up
703 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
704 convertToARGB(deviceColor
));
705 return targetColorSpace
->convertFromARGB(aIntermediate
);
708 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertToRGB( const uno::Sequence
< double >& deviceColor
)
710 SolarMutexGuard aGuard
;
712 const std::size_t nLen( deviceColor
.getLength() );
713 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
714 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
715 "number of channels no multiple of pixel element count",
716 static_cast<rendering::XBitmapPalette
*>(this), 01);
718 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/nComponentsPerPixel
);
719 rendering::RGBColor
* pOut( aRes
.getArray() );
723 OSL_ENSURE(m_nIndexIndex
!= -1,
724 "Invalid color channel indices");
725 ENSURE_OR_THROW(m_pBmpAcc
,
726 "Unable to get BitmapAccess");
728 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
730 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
731 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
733 // TODO(F3): Convert result to sRGB color space
734 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
735 toDoubleColor(aCol
.GetGreen()),
736 toDoubleColor(aCol
.GetBlue()));
741 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
742 "Invalid color channel indices");
744 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
746 // TODO(F3): Convert result to sRGB color space
747 *pOut
++ = rendering::RGBColor(
748 deviceColor
[i
+m_nRedIndex
],
749 deviceColor
[i
+m_nGreenIndex
],
750 deviceColor
[i
+m_nBlueIndex
]);
757 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToARGB( const uno::Sequence
< double >& deviceColor
)
759 SolarMutexGuard aGuard
;
761 const std::size_t nLen( deviceColor
.getLength() );
762 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
763 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
764 "number of channels no multiple of pixel element count",
765 static_cast<rendering::XBitmapPalette
*>(this), 01);
767 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
768 rendering::ARGBColor
* pOut( aRes
.getArray() );
772 OSL_ENSURE(m_nIndexIndex
!= -1,
773 "Invalid color channel indices");
774 ENSURE_OR_THROW(m_pBmpAcc
,
775 "Unable to get BitmapAccess");
777 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
779 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
780 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
782 // TODO(F3): Convert result to sRGB color space
783 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
784 *pOut
++ = rendering::ARGBColor(nAlpha
,
785 toDoubleColor(aCol
.GetRed()),
786 toDoubleColor(aCol
.GetGreen()),
787 toDoubleColor(aCol
.GetBlue()));
792 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
793 "Invalid color channel indices");
795 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
797 // TODO(F3): Convert result to sRGB color space
798 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
799 *pOut
++ = rendering::ARGBColor(
801 deviceColor
[i
+m_nRedIndex
],
802 deviceColor
[i
+m_nGreenIndex
],
803 deviceColor
[i
+m_nBlueIndex
]);
810 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToPARGB( const uno::Sequence
< double >& deviceColor
)
812 SolarMutexGuard aGuard
;
814 const std::size_t nLen( deviceColor
.getLength() );
815 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
816 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
817 "number of channels no multiple of pixel element count",
818 static_cast<rendering::XBitmapPalette
*>(this), 01);
820 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
821 rendering::ARGBColor
* pOut( aRes
.getArray() );
825 OSL_ENSURE(m_nIndexIndex
!= -1,
826 "Invalid color channel indices");
827 ENSURE_OR_THROW(m_pBmpAcc
,
828 "Unable to get BitmapAccess");
830 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
832 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
833 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
835 // TODO(F3): Convert result to sRGB color space
836 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
837 *pOut
++ = rendering::ARGBColor(nAlpha
,
838 nAlpha
*toDoubleColor(aCol
.GetRed()),
839 nAlpha
*toDoubleColor(aCol
.GetGreen()),
840 nAlpha
*toDoubleColor(aCol
.GetBlue()));
845 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
846 "Invalid color channel indices");
848 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
850 // TODO(F3): Convert result to sRGB color space
851 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
852 *pOut
++ = rendering::ARGBColor(
854 nAlpha
*deviceColor
[i
+m_nRedIndex
],
855 nAlpha
*deviceColor
[i
+m_nGreenIndex
],
856 nAlpha
*deviceColor
[i
+m_nBlueIndex
]);
863 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
)
865 SolarMutexGuard aGuard
;
867 const std::size_t nLen( rgbColor
.getLength() );
868 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
870 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
871 double* pColors
=aRes
.getArray();
875 for( const auto& rIn
: rgbColor
)
877 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
878 BitmapColor(toByteColor(rIn
.Red
),
879 toByteColor(rIn
.Green
),
880 toByteColor(rIn
.Blue
)));
881 if( m_nAlphaIndex
!= -1 )
882 pColors
[m_nAlphaIndex
] = 1.0;
884 pColors
+= nComponentsPerPixel
;
889 for( const auto& rIn
: rgbColor
)
891 pColors
[m_nRedIndex
] = rIn
.Red
;
892 pColors
[m_nGreenIndex
] = rIn
.Green
;
893 pColors
[m_nBlueIndex
] = rIn
.Blue
;
894 if( m_nAlphaIndex
!= -1 )
895 pColors
[m_nAlphaIndex
] = 1.0;
897 pColors
+= nComponentsPerPixel
;
903 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
905 SolarMutexGuard aGuard
;
907 const std::size_t nLen( rgbColor
.getLength() );
908 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
910 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
911 double* pColors
=aRes
.getArray();
915 for( const auto& rIn
: rgbColor
)
917 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
918 BitmapColor(toByteColor(rIn
.Red
),
919 toByteColor(rIn
.Green
),
920 toByteColor(rIn
.Blue
)));
921 if( m_nAlphaIndex
!= -1 )
922 pColors
[m_nAlphaIndex
] = rIn
.Alpha
;
924 pColors
+= nComponentsPerPixel
;
929 for( const auto& rIn
: rgbColor
)
931 pColors
[m_nRedIndex
] = rIn
.Red
;
932 pColors
[m_nGreenIndex
] = rIn
.Green
;
933 pColors
[m_nBlueIndex
] = rIn
.Blue
;
934 if( m_nAlphaIndex
!= -1 )
935 pColors
[m_nAlphaIndex
] = rIn
.Alpha
;
937 pColors
+= nComponentsPerPixel
;
943 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
945 SolarMutexGuard aGuard
;
947 const std::size_t nLen( rgbColor
.getLength() );
948 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
950 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
951 double* pColors
=aRes
.getArray();
955 for( const auto& rIn
: rgbColor
)
957 const double nAlpha( rIn
.Alpha
);
958 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
959 BitmapColor(toByteColor(rIn
.Red
/ nAlpha
),
960 toByteColor(rIn
.Green
/ nAlpha
),
961 toByteColor(rIn
.Blue
/ nAlpha
)));
962 if( m_nAlphaIndex
!= -1 )
963 pColors
[m_nAlphaIndex
] = nAlpha
;
965 pColors
+= nComponentsPerPixel
;
970 for( const auto& rIn
: rgbColor
)
972 const double nAlpha( rIn
.Alpha
);
973 pColors
[m_nRedIndex
] = rIn
.Red
/ nAlpha
;
974 pColors
[m_nGreenIndex
] = rIn
.Green
/ nAlpha
;
975 pColors
[m_nBlueIndex
] = rIn
.Blue
/ nAlpha
;
976 if( m_nAlphaIndex
!= -1 )
977 pColors
[m_nAlphaIndex
] = nAlpha
;
979 pColors
+= nComponentsPerPixel
;
985 sal_Int32 SAL_CALL
VclCanvasBitmap::getBitsPerPixel( )
987 SolarMutexGuard aGuard
;
988 return m_nBitsPerOutputPixel
;
991 uno::Sequence
< ::sal_Int32
> SAL_CALL
VclCanvasBitmap::getComponentBitCounts( )
993 SolarMutexGuard aGuard
;
994 return m_aComponentBitCounts
;
997 sal_Int8 SAL_CALL
VclCanvasBitmap::getEndianness( )
999 SolarMutexGuard aGuard
;
1000 return m_nEndianness
;
1003 uno::Sequence
<double> SAL_CALL
VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1004 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
)
1006 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1008 SolarMutexGuard aGuard
;
1010 const std::size_t nLen( deviceColor
.getLength() );
1011 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
1012 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
1013 "number of channels no multiple of pixel element count",
1014 static_cast<rendering::XBitmapPalette
*>(this), 01);
1016 uno::Sequence
<double> aRes(nLen
);
1017 double* pOut( aRes
.getArray() );
1021 OSL_ENSURE(m_nIndexIndex
!= -1,
1022 "Invalid color channel indices");
1023 ENSURE_OR_THROW(m_pBmpAcc
,
1024 "Unable to get BitmapAccess");
1026 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1028 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
1029 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
1031 // TODO(F3): Convert result to sRGB color space
1032 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1033 *pOut
++ = toDoubleColor(aCol
.GetRed());
1034 *pOut
++ = toDoubleColor(aCol
.GetGreen());
1035 *pOut
++ = toDoubleColor(aCol
.GetBlue());
1041 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
1042 "Invalid color channel indices");
1044 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1046 // TODO(F3): Convert result to sRGB color space
1047 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1048 *pOut
++ = deviceColor
[i
+m_nRedIndex
];
1049 *pOut
++ = deviceColor
[i
+m_nGreenIndex
];
1050 *pOut
++ = deviceColor
[i
+m_nBlueIndex
];
1059 // TODO(P3): if we know anything about target
1060 // colorspace, this can be greatly sped up
1061 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1062 convertIntegerToARGB(deviceColor
));
1063 return targetColorSpace
->convertFromARGB(aIntermediate
);
1067 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1068 const uno::Reference
< ::rendering::XIntegerBitmapColorSpace
>& targetColorSpace
)
1070 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1072 // it's us, so simply pass-through the data
1077 // TODO(P3): if we know anything about target
1078 // colorspace, this can be greatly sped up
1079 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1080 convertIntegerToARGB(deviceColor
));
1081 return targetColorSpace
->convertIntegerFromARGB(aIntermediate
);
1085 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
)
1087 SolarMutexGuard aGuard
;
1089 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1090 const std::size_t nLen( deviceColor
.getLength() );
1091 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1093 uno::Sequence
< rendering::RGBColor
> aRes(nNumColors
);
1094 rendering::RGBColor
* pOut( aRes
.getArray() );
1096 ENSURE_OR_THROW(m_pBmpAcc
,
1097 "Unable to get BitmapAccess");
1099 if( m_aBmpEx
.IsTransparent() )
1101 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1102 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1104 // if palette, index is guaranteed to be 8 bit
1105 const BitmapColor aCol
=
1107 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1108 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1110 // TODO(F3): Convert result to sRGB color space
1111 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1112 toDoubleColor(aCol
.GetGreen()),
1113 toDoubleColor(aCol
.GetBlue()));
1115 pIn
+= nBytesPerPixel
;
1120 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1122 const BitmapColor aCol
=
1124 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex()) :
1125 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1127 // TODO(F3): Convert result to sRGB color space
1128 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1129 toDoubleColor(aCol
.GetGreen()),
1130 toDoubleColor(aCol
.GetBlue()));
1137 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
)
1139 SolarMutexGuard aGuard
;
1141 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1142 const std::size_t nLen( deviceColor
.getLength() );
1143 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1145 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1146 rendering::ARGBColor
* pOut( aRes
.getArray() );
1148 ENSURE_OR_THROW(m_pBmpAcc
,
1149 "Unable to get BitmapAccess");
1151 if( m_aBmpEx
.IsTransparent() )
1153 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1154 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1155 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1156 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1158 // if palette, index is guaranteed to be 8 bit
1159 const BitmapColor aCol
=
1161 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1162 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1164 // TODO(F3): Convert result to sRGB color space
1165 *pOut
++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]),
1166 toDoubleColor(aCol
.GetRed()),
1167 toDoubleColor(aCol
.GetGreen()),
1168 toDoubleColor(aCol
.GetBlue()));
1169 pIn
+= nBytesPerPixel
;
1174 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1176 const BitmapColor aCol
=
1178 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1179 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1181 // TODO(F3): Convert result to sRGB color space
1182 *pOut
++ = rendering::ARGBColor(1.0,
1183 toDoubleColor(aCol
.GetRed()),
1184 toDoubleColor(aCol
.GetGreen()),
1185 toDoubleColor(aCol
.GetBlue()));
1192 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
)
1194 SolarMutexGuard aGuard
;
1196 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1197 const std::size_t nLen( deviceColor
.getLength() );
1198 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1200 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1201 rendering::ARGBColor
* pOut( aRes
.getArray() );
1203 ENSURE_OR_THROW(m_pBmpAcc
,
1204 "Unable to get BitmapAccess");
1206 if( m_aBmpEx
.IsTransparent() )
1208 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1209 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1210 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1211 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1213 // if palette, index is guaranteed to be 8 bit
1214 const BitmapColor aCol
=
1216 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1217 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1219 // TODO(F3): Convert result to sRGB color space
1220 const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]) );
1221 *pOut
++ = rendering::ARGBColor(nAlpha
,
1222 nAlpha
*toDoubleColor(aCol
.GetRed()),
1223 nAlpha
*toDoubleColor(aCol
.GetGreen()),
1224 nAlpha
*toDoubleColor(aCol
.GetBlue()));
1225 pIn
+= nBytesPerPixel
;
1230 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1232 const BitmapColor aCol
=
1234 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1235 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1237 // TODO(F3): Convert result to sRGB color space
1238 *pOut
++ = rendering::ARGBColor(1.0,
1239 toDoubleColor(aCol
.GetRed()),
1240 toDoubleColor(aCol
.GetGreen()),
1241 toDoubleColor(aCol
.GetBlue()));
1248 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
)
1250 SolarMutexGuard aGuard
;
1252 const std::size_t nLen( rgbColor
.getLength() );
1253 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1255 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1256 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1258 if( m_aBmpEx
.IsTransparent() )
1260 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1261 for( std::size_t i
=0; i
<nLen
; ++i
)
1263 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1264 toByteColor(rgbColor
[i
].Green
),
1265 toByteColor(rgbColor
[i
].Blue
));
1266 const BitmapColor aCol2
=
1269 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1272 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1273 pColors
+= nNonAlphaBytes
;
1274 *pColors
++ = sal_uInt8(255);
1279 for( std::size_t i
=0; i
<nLen
; ++i
)
1281 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1282 toByteColor(rgbColor
[i
].Green
),
1283 toByteColor(rgbColor
[i
].Blue
));
1284 const BitmapColor aCol2
=
1287 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1290 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1297 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
1299 SolarMutexGuard aGuard
;
1301 const std::size_t nLen( rgbColor
.getLength() );
1302 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1304 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1305 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1307 if( m_aBmpEx
.IsTransparent() )
1309 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1310 for( std::size_t i
=0; i
<nLen
; ++i
)
1312 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1313 toByteColor(rgbColor
[i
].Green
),
1314 toByteColor(rgbColor
[i
].Blue
));
1315 const BitmapColor aCol2
=
1318 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1321 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1322 pColors
+= nNonAlphaBytes
;
1323 *pColors
++ = 255 - toByteColor(rgbColor
[i
].Alpha
);
1328 for( std::size_t i
=0; i
<nLen
; ++i
)
1330 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1331 toByteColor(rgbColor
[i
].Green
),
1332 toByteColor(rgbColor
[i
].Blue
));
1333 const BitmapColor aCol2
=
1336 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1339 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1346 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
1348 SolarMutexGuard aGuard
;
1350 const std::size_t nLen( rgbColor
.getLength() );
1351 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1353 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1354 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1356 if( m_aBmpEx
.IsTransparent() )
1358 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1359 for( std::size_t i
=0; i
<nLen
; ++i
)
1361 const double nAlpha( rgbColor
[i
].Alpha
);
1362 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1363 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1364 toByteColor(rgbColor
[i
].Blue
/ nAlpha
));
1365 const BitmapColor aCol2
=
1368 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1371 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1372 pColors
+= nNonAlphaBytes
;
1373 *pColors
++ = 255 - toByteColor(nAlpha
);
1378 for( std::size_t i
=0; i
<nLen
; ++i
)
1380 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1381 toByteColor(rgbColor
[i
].Green
),
1382 toByteColor(rgbColor
[i
].Blue
));
1383 const BitmapColor aCol2
=
1386 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1389 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */