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 <comphelper/diagnose_ex.hxx>
29 #include <canvasbitmap.hxx>
30 #include <vcl/canvastools.hxx>
31 #include <vcl/BitmapReadAccess.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 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_uInt32 redShift
, sal_uInt32 greenShift
, sal_uInt32 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(redShift
);
93 pCounts
[greenPos
] = bitcount(greenShift
);
94 pCounts
[bluePos
] = bitcount(blueShift
);
97 Bitmap::ScopedReadAccess
& VclCanvasBitmap::getBitmapReadAccess()
99 // BitmapReadAccess is more expensive than BitmapInfoAccess,
100 // as the latter requires also pixels, which may need converted
101 // from the system format (and even fetched). Most calls here
102 // need only info access, create read access only on demand.
104 m_pBmpReadAcc
.emplace(m_aBitmap
);
105 return *m_pBmpReadAcc
;
108 Bitmap::ScopedReadAccess
& VclCanvasBitmap::getAlphaReadAccess()
111 m_pAlphaReadAcc
.emplace(m_aAlpha
);
112 return *m_pAlphaReadAcc
;
115 VclCanvasBitmap::VclCanvasBitmap( const BitmapEx
& rBitmap
) :
117 m_aBitmap( rBitmap
.GetBitmap() ),
118 m_pBmpAcc( m_aBitmap
),
119 m_nBitsPerInputPixel(0),
120 m_nBitsPerOutputPixel(0),
128 if( m_aBmpEx
.IsAlpha() )
130 m_aAlpha
= m_aBmpEx
.GetAlphaMask().GetBitmap();
131 m_pAlphaAcc
= Bitmap::ScopedInfoAccess(m_aAlpha
);
134 m_aLayout
.ScanLines
= 0;
135 m_aLayout
.ScanLineBytes
= 0;
136 m_aLayout
.ScanLineStride
= 0;
137 m_aLayout
.PlaneStride
= 0;
138 m_aLayout
.ColorSpace
.clear();
139 m_aLayout
.Palette
.clear();
140 m_aLayout
.IsMsbFirst
= false;
145 m_aLayout
.ScanLines
= m_pBmpAcc
->Height();
146 m_aLayout
.ScanLineBytes
= (m_pBmpAcc
->GetBitCount()*m_pBmpAcc
->Width() + 7) / 8;
147 m_aLayout
.ScanLineStride
= m_pBmpAcc
->GetScanlineSize();
148 m_aLayout
.PlaneStride
= 0;
150 switch( m_pBmpAcc
->GetScanlineFormat() )
152 case ScanlineFormat::N1BitMsbPal
:
154 m_nBitsPerInputPixel
= 1;
155 m_aLayout
.IsMsbFirst
= true;
158 case ScanlineFormat::N1BitLsbPal
:
160 m_nBitsPerInputPixel
= 1;
161 m_aLayout
.IsMsbFirst
= false;
164 case ScanlineFormat::N8BitPal
:
166 m_nBitsPerInputPixel
= 8;
167 m_aLayout
.IsMsbFirst
= false; // doesn't matter
170 case ScanlineFormat::N24BitTcBgr
:
172 m_nBitsPerInputPixel
= 24;
173 m_aLayout
.IsMsbFirst
= false; // doesn't matter
174 setComponentInfo( static_cast<sal_uInt32
>(0xff0000UL
),
175 static_cast<sal_uInt32
>(0x00ff00UL
),
176 static_cast<sal_uInt32
>(0x0000ffUL
) );
179 case ScanlineFormat::N24BitTcRgb
:
181 m_nBitsPerInputPixel
= 24;
182 m_aLayout
.IsMsbFirst
= false; // doesn't matter
183 setComponentInfo( static_cast<sal_uInt32
>(0x0000ffUL
),
184 static_cast<sal_uInt32
>(0x00ff00UL
),
185 static_cast<sal_uInt32
>(0xff0000UL
) );
188 case ScanlineFormat::N32BitTcAbgr
:
191 m_nBitsPerInputPixel
= 32;
192 m_aLayout
.IsMsbFirst
= false; // doesn't matter
194 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::ALPHA
,
195 /* 1 */ rendering::ColorComponentTag::RGB_BLUE
,
196 /* 2 */ rendering::ColorComponentTag::RGB_GREEN
,
197 /* 3 */ rendering::ColorComponentTag::RGB_RED
};
199 m_aComponentBitCounts
= { /* 0 */ 8,
211 case ScanlineFormat::N32BitTcArgb
:
214 m_nBitsPerInputPixel
= 32;
215 m_aLayout
.IsMsbFirst
= false; // doesn't matter
217 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::ALPHA
,
218 /* 1 */ rendering::ColorComponentTag::RGB_RED
,
219 /* 2 */ rendering::ColorComponentTag::RGB_GREEN
,
220 /* 3 */ rendering::ColorComponentTag::RGB_BLUE
};
222 m_aComponentBitCounts
= { /* 0 */ 8,
234 case ScanlineFormat::N32BitTcBgra
:
237 m_nBitsPerInputPixel
= 32;
238 m_aLayout
.IsMsbFirst
= false; // doesn't matter
240 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::RGB_BLUE
,
241 /* 1 */ rendering::ColorComponentTag::RGB_GREEN
,
242 /* 2 */ rendering::ColorComponentTag::RGB_RED
,
243 /* 3 */ rendering::ColorComponentTag::ALPHA
};
245 m_aComponentBitCounts
= { /* 0 */ 8,
257 case ScanlineFormat::N32BitTcRgba
:
260 m_nBitsPerInputPixel
= 32;
261 m_aLayout
.IsMsbFirst
= false; // doesn't matter
263 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::RGB_RED
,
264 /* 1 */ rendering::ColorComponentTag::RGB_GREEN
,
265 /* 2 */ rendering::ColorComponentTag::RGB_BLUE
,
266 /* 3 */ rendering::ColorComponentTag::ALPHA
};
268 m_aComponentBitCounts
= { /* 0 */ 8,
280 case ScanlineFormat::N32BitTcMask
:
282 m_nBitsPerInputPixel
= 32;
283 m_aLayout
.IsMsbFirst
= false; // doesn't matter
284 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
285 m_pBmpAcc
->GetColorMask().GetGreenMask(),
286 m_pBmpAcc
->GetColorMask().GetBlueMask() );
290 OSL_FAIL( "unsupported bitmap format" );
296 m_aComponentTags
= { rendering::ColorComponentTag::INDEX
};
298 m_aComponentBitCounts
= { m_nBitsPerInputPixel
};
303 m_nBitsPerOutputPixel
= m_nBitsPerInputPixel
;
304 if( !m_aBmpEx
.IsAlpha() )
307 // TODO(P1): need to interleave alpha with bitmap data -
308 // won't fuss with less-than-8 bit for now
309 m_nBitsPerOutputPixel
= std::max(sal_Int32(8),m_nBitsPerInputPixel
);
311 // check whether alpha goes in front or behind the
312 // bitcount sequence. If pixel format is little endian,
313 // put it behind all the other channels. If it's big
314 // endian, put it in front (because later, the actual data
315 // always gets written after the pixel data)
317 // TODO(Q1): slight catch - in the case of the
318 // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
319 // channels might happen!
320 m_aComponentTags
.realloc(m_aComponentTags
.getLength()+1);
321 m_aComponentTags
.getArray()[m_aComponentTags
.getLength()-1] = rendering::ColorComponentTag::ALPHA
;
323 m_aComponentBitCounts
.realloc(m_aComponentBitCounts
.getLength()+1);
324 m_aComponentBitCounts
.getArray()[m_aComponentBitCounts
.getLength()-1] = m_aBmpEx
.IsAlpha() ? 8 : 1;
326 // always add a full byte to the pixel size, otherwise
327 // pixel packing hell breaks loose.
328 m_nBitsPerOutputPixel
+= 8;
330 // adapt scanline parameters
331 const Size aSize
= m_aBitmap
.GetSizePixel();
332 m_aLayout
.ScanLineBytes
=
333 m_aLayout
.ScanLineStride
= (aSize
.Width()*m_nBitsPerOutputPixel
+ 7)/8;
336 VclCanvasBitmap::~VclCanvasBitmap()
341 geometry::IntegerSize2D SAL_CALL
VclCanvasBitmap::getSize()
343 SolarMutexGuard aGuard
;
344 return integerSize2DFromSize( m_aBitmap
.GetSizePixel() );
347 sal_Bool SAL_CALL
VclCanvasBitmap::hasAlpha()
349 SolarMutexGuard aGuard
;
350 return m_aBmpEx
.IsAlpha();
353 uno::Reference
< rendering::XBitmap
> SAL_CALL
VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D
& newSize
,
356 SolarMutexGuard aGuard
;
358 BitmapEx
aNewBmp( m_aBitmap
);
359 aNewBmp
.Scale( sizeFromRealSize2D( newSize
), beFast
? BmpScaleFlag::Default
: BmpScaleFlag::BestQuality
);
360 return uno::Reference
<rendering::XBitmap
>( new VclCanvasBitmap( aNewBmp
) );
363 // XIntegerReadOnlyBitmap
364 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getData( rendering::IntegerBitmapLayout
& bitmapLayout
,
365 const geometry::IntegerRectangle2D
& rect
)
367 SolarMutexGuard aGuard
;
369 bitmapLayout
= getMemoryLayout();
371 const ::tools::Rectangle
aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect
) );
372 if( aRequestedArea
.IsEmpty() )
373 return uno::Sequence
< sal_Int8
>();
375 // Invalid/empty bitmap: no data available
377 throw lang::IndexOutOfBoundsException();
378 if( m_aBmpEx
.IsAlpha() && !m_pAlphaAcc
)
379 throw lang::IndexOutOfBoundsException();
381 if( aRequestedArea
.Left() < 0 || aRequestedArea
.Top() < 0 ||
382 aRequestedArea
.Right() > m_pBmpAcc
->Width() ||
383 aRequestedArea
.Bottom() > m_pBmpAcc
->Height() )
385 throw lang::IndexOutOfBoundsException();
388 uno::Sequence
< sal_Int8
> aRet
;
389 tools::Rectangle
aRequestedBytes( aRequestedArea
);
391 // adapt to byte boundaries
392 aRequestedBytes
.SetLeft( aRequestedArea
.Left()*m_nBitsPerOutputPixel
/8 );
393 aRequestedBytes
.SetRight( (aRequestedArea
.Right()*m_nBitsPerOutputPixel
+ 7)/8 );
395 // copy stuff to output sequence
396 aRet
.realloc(aRequestedBytes
.getOpenWidth()*aRequestedBytes
.getOpenHeight());
397 sal_Int8
* pOutBuf
= aRet
.getArray();
399 bitmapLayout
.ScanLines
= aRequestedBytes
.getOpenHeight();
400 bitmapLayout
.ScanLineBytes
=
401 bitmapLayout
.ScanLineStride
= aRequestedBytes
.getOpenWidth();
403 sal_Int32 nScanlineStride
=bitmapLayout
.ScanLineStride
;
404 if( !(m_pBmpAcc
->GetScanlineFormat() & ScanlineFormat::TopDown
) )
406 pOutBuf
+= bitmapLayout
.ScanLineStride
*(aRequestedBytes
.getOpenHeight()-1);
407 nScanlineStride
*= -1;
410 if( !m_aBmpEx
.IsAlpha() )
412 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
413 OSL_ENSURE(pBmpAcc
,"Invalid bmp read access");
415 // can return bitmap data as-is
416 for( tools::Long y
=aRequestedBytes
.Top(); y
<aRequestedBytes
.Bottom(); ++y
)
418 Scanline pScan
= pBmpAcc
->GetScanline(y
);
419 memcpy(pOutBuf
, pScan
+aRequestedBytes
.Left(), aRequestedBytes
.getOpenWidth());
420 pOutBuf
+= nScanlineStride
;
425 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
426 Bitmap::ScopedReadAccess
& pAlphaAcc
= getAlphaReadAccess();
427 OSL_ENSURE(pBmpAcc
,"Invalid bmp read access");
428 OSL_ENSURE(pAlphaAcc
,"Invalid alpha read access");
430 // interleave alpha with bitmap data - note, bitcount is
431 // always integer multiple of 8
432 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
433 "Transparent bitmap bitcount not integer multiple of 8" );
435 for( tools::Long y
=aRequestedArea
.Top(); y
<aRequestedArea
.Bottom(); ++y
)
437 sal_Int8
* pOutScan
= pOutBuf
;
439 if( m_nBitsPerInputPixel
< 8 )
441 // input less than a byte - copy via GetPixel()
442 for( tools::Long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
444 *pOutScan
++ = pBmpAcc
->GetPixelIndex(y
,x
);
445 *pOutScan
++ = pAlphaAcc
->GetPixelIndex(y
,x
);
450 const tools::Long
nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
451 const tools::Long
nScanlineOffsetLeft(aRequestedArea
.Left()*nNonAlphaBytes
);
452 Scanline pScan
= pBmpAcc
->GetScanline(y
) + nScanlineOffsetLeft
;
453 Scanline pScanlineAlpha
= pAlphaAcc
->GetScanline( y
);
455 // input integer multiple of byte - copy directly
456 for( tools::Long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
458 for( tools::Long i
=0; i
<nNonAlphaBytes
; ++i
)
459 *pOutScan
++ = *pScan
++;
460 *pOutScan
++ = pAlphaAcc
->GetIndexFromData( pScanlineAlpha
, x
);
464 pOutBuf
+= nScanlineStride
;
471 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout
& bitmapLayout
,
472 const geometry::IntegerPoint2D
& pos
)
474 SolarMutexGuard aGuard
;
476 bitmapLayout
= getMemoryLayout();
478 // Invalid/empty bitmap: no data available
480 throw lang::IndexOutOfBoundsException();
481 if( m_aBmpEx
.IsAlpha() && !m_pAlphaAcc
)
482 throw lang::IndexOutOfBoundsException();
484 if( pos
.X
< 0 || pos
.Y
< 0 ||
485 pos
.X
> m_pBmpAcc
->Width() || pos
.Y
> m_pBmpAcc
->Height() )
487 throw lang::IndexOutOfBoundsException();
490 uno::Sequence
< sal_Int8
> aRet((m_nBitsPerOutputPixel
+ 7)/8);
491 sal_Int8
* pOutBuf
= aRet
.getArray();
493 // copy stuff to output sequence
494 bitmapLayout
.ScanLines
= 1;
495 bitmapLayout
.ScanLineBytes
=
496 bitmapLayout
.ScanLineStride
= aRet
.getLength();
498 const tools::Long
nScanlineLeftOffset( pos
.X
*m_nBitsPerInputPixel
/8 );
499 if( !m_aBmpEx
.IsAlpha() )
501 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
502 assert(pBmpAcc
&& "Invalid bmp read access");
504 // can return bitmap data as-is
505 Scanline pScan
= pBmpAcc
->GetScanline(pos
.Y
);
506 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, aRet
.getLength() );
510 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
511 Bitmap::ScopedReadAccess
& pAlphaAcc
= getAlphaReadAccess();
512 assert(pBmpAcc
&& "Invalid bmp read access");
513 assert(pAlphaAcc
&& "Invalid alpha read access");
515 // interleave alpha with bitmap data - note, bitcount is
516 // always integer multiple of 8
517 assert((m_nBitsPerOutputPixel
& 0x07) == 0 &&
518 "Transparent bitmap bitcount not integer multiple of 8" );
520 if( m_nBitsPerInputPixel
< 8 )
522 // input less than a byte - copy via GetPixel()
523 *pOutBuf
++ = pBmpAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
524 *pOutBuf
= pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
528 const tools::Long
nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
529 Scanline pScan
= pBmpAcc
->GetScanline(pos
.Y
);
531 // input integer multiple of byte - copy directly
532 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, nNonAlphaBytes
);
533 pOutBuf
+= nNonAlphaBytes
;
534 *pOutBuf
++ = pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
541 uno::Reference
< rendering::XBitmapPalette
> VclCanvasBitmap::getPalette()
543 SolarMutexGuard aGuard
;
545 uno::Reference
< XBitmapPalette
> aRet
;
552 rendering::IntegerBitmapLayout SAL_CALL
VclCanvasBitmap::getMemoryLayout()
554 SolarMutexGuard aGuard
;
556 rendering::IntegerBitmapLayout
aLayout( m_aLayout
);
558 // only set references to self on separate copy of
559 // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
560 // a circular reference!
562 aLayout
.Palette
.set( this );
564 aLayout
.ColorSpace
.set( this );
569 sal_Int32 SAL_CALL
VclCanvasBitmap::getNumberOfEntries()
571 SolarMutexGuard aGuard
;
576 return m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ;
579 sal_Bool SAL_CALL
VclCanvasBitmap::getIndex( uno::Sequence
< double >& o_entry
, sal_Int32 nIndex
)
581 SolarMutexGuard aGuard
;
583 const sal_uInt16
nCount( m_pBmpAcc
?
584 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
585 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
586 if( nIndex
< 0 || nIndex
>= nCount
)
587 throw lang::IndexOutOfBoundsException("Palette index out of range",
588 static_cast<rendering::XBitmapPalette
*>(this));
590 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(sal::static_int_cast
<sal_uInt16
>(nIndex
));
592 double* pColor
=o_entry
.getArray();
593 pColor
[0] = aCol
.GetRed();
594 pColor
[1] = aCol
.GetGreen();
595 pColor
[2] = aCol
.GetBlue();
597 return true; // no palette transparency here.
600 sal_Bool SAL_CALL
VclCanvasBitmap::setIndex( const uno::Sequence
< double >&, sal_Bool
, sal_Int32 nIndex
)
602 SolarMutexGuard aGuard
;
604 const sal_uInt16
nCount( m_pBmpAcc
?
605 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
607 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
608 if( nIndex
< 0 || nIndex
>= nCount
)
609 throw lang::IndexOutOfBoundsException("Palette index out of range",
610 static_cast<rendering::XBitmapPalette
*>(this));
612 return false; // read-only implementation
615 uno::Reference
< rendering::XColorSpace
> SAL_CALL
VclCanvasBitmap::getColorSpace( )
617 // this is the method from XBitmapPalette. Return palette color
619 static uno::Reference
<rendering::XColorSpace
> gColorSpace
= vcl::unotools::createStandardColorSpace();
623 sal_Int8 SAL_CALL
VclCanvasBitmap::getType( )
625 return rendering::ColorSpaceType::RGB
;
628 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::getComponentTags( )
630 SolarMutexGuard aGuard
;
631 return m_aComponentTags
;
634 sal_Int8 SAL_CALL
VclCanvasBitmap::getRenderingIntent( )
636 return rendering::RenderingIntent::PERCEPTUAL
;
639 uno::Sequence
< ::beans::PropertyValue
> SAL_CALL
VclCanvasBitmap::getProperties( )
641 return uno::Sequence
< ::beans::PropertyValue
>();
644 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertColorSpace( const uno::Sequence
< double >& deviceColor
,
645 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
)
647 // TODO(P3): if we know anything about target
648 // colorspace, this can be greatly sped up
649 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
650 convertToARGB(deviceColor
));
651 return targetColorSpace
->convertFromARGB(aIntermediate
);
654 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertToRGB( const uno::Sequence
< double >& deviceColor
)
656 SolarMutexGuard aGuard
;
658 const std::size_t nLen( deviceColor
.getLength() );
659 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
660 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
661 "number of channels no multiple of pixel element count",
662 static_cast<rendering::XBitmapPalette
*>(this), 01);
664 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/nComponentsPerPixel
);
665 rendering::RGBColor
* pOut( aRes
.getArray() );
669 OSL_ENSURE(m_nIndexIndex
!= -1,
670 "Invalid color channel indices");
671 ENSURE_OR_THROW(m_pBmpAcc
,
672 "Unable to get BitmapAccess");
674 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
676 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
677 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
679 // TODO(F3): Convert result to sRGB color space
680 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
681 toDoubleColor(aCol
.GetGreen()),
682 toDoubleColor(aCol
.GetBlue()));
687 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
688 "Invalid color channel indices");
690 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
692 // TODO(F3): Convert result to sRGB color space
693 *pOut
++ = rendering::RGBColor(
694 deviceColor
[i
+m_nRedIndex
],
695 deviceColor
[i
+m_nGreenIndex
],
696 deviceColor
[i
+m_nBlueIndex
]);
703 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToARGB( const uno::Sequence
< double >& deviceColor
)
705 SolarMutexGuard aGuard
;
707 const std::size_t nLen( deviceColor
.getLength() );
708 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
709 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
710 "number of channels no multiple of pixel element count",
711 static_cast<rendering::XBitmapPalette
*>(this), 01);
713 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
714 rendering::ARGBColor
* pOut( aRes
.getArray() );
718 OSL_ENSURE(m_nIndexIndex
!= -1,
719 "Invalid color channel indices");
720 ENSURE_OR_THROW(m_pBmpAcc
,
721 "Unable to get BitmapAccess");
723 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
725 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
726 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
728 // TODO(F3): Convert result to sRGB color space
729 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
730 *pOut
++ = rendering::ARGBColor(nAlpha
,
731 toDoubleColor(aCol
.GetRed()),
732 toDoubleColor(aCol
.GetGreen()),
733 toDoubleColor(aCol
.GetBlue()));
738 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
739 "Invalid color channel indices");
741 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
743 // TODO(F3): Convert result to sRGB color space
744 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
745 *pOut
++ = rendering::ARGBColor(
747 deviceColor
[i
+m_nRedIndex
],
748 deviceColor
[i
+m_nGreenIndex
],
749 deviceColor
[i
+m_nBlueIndex
]);
756 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToPARGB( const uno::Sequence
< double >& deviceColor
)
758 SolarMutexGuard aGuard
;
760 const std::size_t 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::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
767 rendering::ARGBColor
* 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( std::size_t 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 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
783 *pOut
++ = rendering::ARGBColor(nAlpha
,
784 nAlpha
*toDoubleColor(aCol
.GetRed()),
785 nAlpha
*toDoubleColor(aCol
.GetGreen()),
786 nAlpha
*toDoubleColor(aCol
.GetBlue()));
791 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
792 "Invalid color channel indices");
794 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
796 // TODO(F3): Convert result to sRGB color space
797 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
798 *pOut
++ = rendering::ARGBColor(
800 nAlpha
*deviceColor
[i
+m_nRedIndex
],
801 nAlpha
*deviceColor
[i
+m_nGreenIndex
],
802 nAlpha
*deviceColor
[i
+m_nBlueIndex
]);
809 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
)
811 SolarMutexGuard aGuard
;
813 const std::size_t nLen( rgbColor
.getLength() );
814 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
816 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
817 double* pColors
=aRes
.getArray();
821 for( const auto& rIn
: rgbColor
)
823 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
824 BitmapColor(toByteColor(rIn
.Red
),
825 toByteColor(rIn
.Green
),
826 toByteColor(rIn
.Blue
)));
827 if( m_nAlphaIndex
!= -1 )
828 pColors
[m_nAlphaIndex
] = 1.0;
830 pColors
+= nComponentsPerPixel
;
835 for( const auto& rIn
: rgbColor
)
837 pColors
[m_nRedIndex
] = rIn
.Red
;
838 pColors
[m_nGreenIndex
] = rIn
.Green
;
839 pColors
[m_nBlueIndex
] = rIn
.Blue
;
840 if( m_nAlphaIndex
!= -1 )
841 pColors
[m_nAlphaIndex
] = 1.0;
843 pColors
+= nComponentsPerPixel
;
849 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
851 SolarMutexGuard aGuard
;
853 const std::size_t nLen( rgbColor
.getLength() );
854 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
856 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
857 double* pColors
=aRes
.getArray();
861 for( const auto& rIn
: rgbColor
)
863 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
864 BitmapColor(toByteColor(rIn
.Red
),
865 toByteColor(rIn
.Green
),
866 toByteColor(rIn
.Blue
)));
867 if( m_nAlphaIndex
!= -1 )
868 pColors
[m_nAlphaIndex
] = rIn
.Alpha
;
870 pColors
+= nComponentsPerPixel
;
875 for( const auto& rIn
: rgbColor
)
877 pColors
[m_nRedIndex
] = rIn
.Red
;
878 pColors
[m_nGreenIndex
] = rIn
.Green
;
879 pColors
[m_nBlueIndex
] = rIn
.Blue
;
880 if( m_nAlphaIndex
!= -1 )
881 pColors
[m_nAlphaIndex
] = rIn
.Alpha
;
883 pColors
+= nComponentsPerPixel
;
889 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
891 SolarMutexGuard aGuard
;
893 const std::size_t nLen( rgbColor
.getLength() );
894 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
896 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
897 double* pColors
=aRes
.getArray();
901 for( const auto& rIn
: rgbColor
)
903 const double nAlpha( rIn
.Alpha
);
904 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
905 BitmapColor(toByteColor(rIn
.Red
/ nAlpha
),
906 toByteColor(rIn
.Green
/ nAlpha
),
907 toByteColor(rIn
.Blue
/ nAlpha
)));
908 if( m_nAlphaIndex
!= -1 )
909 pColors
[m_nAlphaIndex
] = nAlpha
;
911 pColors
+= nComponentsPerPixel
;
916 for( const auto& rIn
: rgbColor
)
918 const double nAlpha( rIn
.Alpha
);
919 pColors
[m_nRedIndex
] = rIn
.Red
/ nAlpha
;
920 pColors
[m_nGreenIndex
] = rIn
.Green
/ nAlpha
;
921 pColors
[m_nBlueIndex
] = rIn
.Blue
/ nAlpha
;
922 if( m_nAlphaIndex
!= -1 )
923 pColors
[m_nAlphaIndex
] = nAlpha
;
925 pColors
+= nComponentsPerPixel
;
931 sal_Int32 SAL_CALL
VclCanvasBitmap::getBitsPerPixel( )
933 SolarMutexGuard aGuard
;
934 return m_nBitsPerOutputPixel
;
937 uno::Sequence
< ::sal_Int32
> SAL_CALL
VclCanvasBitmap::getComponentBitCounts( )
939 SolarMutexGuard aGuard
;
940 return m_aComponentBitCounts
;
943 sal_Int8 SAL_CALL
VclCanvasBitmap::getEndianness( )
945 return util::Endianness::LITTLE
;
948 uno::Sequence
<double> SAL_CALL
VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
949 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
)
951 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
953 SolarMutexGuard aGuard
;
955 const std::size_t nLen( deviceColor
.getLength() );
956 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
957 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
958 "number of channels no multiple of pixel element count",
959 static_cast<rendering::XBitmapPalette
*>(this), 01);
961 uno::Sequence
<double> aRes(nLen
);
962 double* pOut( aRes
.getArray() );
966 OSL_ENSURE(m_nIndexIndex
!= -1,
967 "Invalid color channel indices");
968 ENSURE_OR_THROW(m_pBmpAcc
,
969 "Unable to get BitmapAccess");
971 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
973 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
974 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
976 // TODO(F3): Convert result to sRGB color space
977 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
978 *pOut
++ = toDoubleColor(aCol
.GetRed());
979 *pOut
++ = toDoubleColor(aCol
.GetGreen());
980 *pOut
++ = toDoubleColor(aCol
.GetBlue());
986 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
987 "Invalid color channel indices");
989 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
991 // TODO(F3): Convert result to sRGB color space
992 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
993 *pOut
++ = deviceColor
[i
+m_nRedIndex
];
994 *pOut
++ = deviceColor
[i
+m_nGreenIndex
];
995 *pOut
++ = deviceColor
[i
+m_nBlueIndex
];
1004 // TODO(P3): if we know anything about target
1005 // colorspace, this can be greatly sped up
1006 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1007 convertIntegerToARGB(deviceColor
));
1008 return targetColorSpace
->convertFromARGB(aIntermediate
);
1012 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1013 const uno::Reference
< ::rendering::XIntegerBitmapColorSpace
>& targetColorSpace
)
1015 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1017 // it's us, so simply pass-through the data
1022 // TODO(P3): if we know anything about target
1023 // colorspace, this can be greatly sped up
1024 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1025 convertIntegerToARGB(deviceColor
));
1026 return targetColorSpace
->convertIntegerFromARGB(aIntermediate
);
1030 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
)
1032 SolarMutexGuard aGuard
;
1034 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1035 const std::size_t nLen( deviceColor
.getLength() );
1036 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1038 uno::Sequence
< rendering::RGBColor
> aRes(nNumColors
);
1039 rendering::RGBColor
* pOut( aRes
.getArray() );
1041 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
1042 ENSURE_OR_THROW(pBmpAcc
,
1043 "Unable to get BitmapAccess");
1045 if( m_aBmpEx
.IsAlpha() )
1047 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1048 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1050 // if palette, index is guaranteed to be 8 bit
1051 const BitmapColor aCol
=
1053 pBmpAcc
->GetPaletteColor(*pIn
) :
1054 pBmpAcc
->GetPixelFromData(pIn
,0);
1056 // TODO(F3): Convert result to sRGB color space
1057 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1058 toDoubleColor(aCol
.GetGreen()),
1059 toDoubleColor(aCol
.GetBlue()));
1061 pIn
+= nBytesPerPixel
;
1066 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1068 const BitmapColor aCol
=
1070 pBmpAcc
->GetPaletteColor( pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex()) :
1071 pBmpAcc
->GetPixelFromData(pIn
, i
);
1073 // TODO(F3): Convert result to sRGB color space
1074 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1075 toDoubleColor(aCol
.GetGreen()),
1076 toDoubleColor(aCol
.GetBlue()));
1083 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
)
1085 SolarMutexGuard aGuard
;
1087 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1088 const std::size_t nLen( deviceColor
.getLength() );
1089 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1091 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1092 rendering::ARGBColor
* pOut( aRes
.getArray() );
1094 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
1095 ENSURE_OR_THROW(pBmpAcc
,
1096 "Unable to get BitmapAccess");
1098 if( m_aBmpEx
.IsAlpha() )
1100 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
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 pBmpAcc
->GetPaletteColor(*pIn
) :
1108 pBmpAcc
->GetPixelFromData(pIn
,0);
1110 // TODO(F3): Convert result to sRGB color space
1111 *pOut
++ = rendering::ARGBColor(1.0 - toDoubleColor(pIn
[nNonAlphaBytes
]),
1112 toDoubleColor(aCol
.GetRed()),
1113 toDoubleColor(aCol
.GetGreen()),
1114 toDoubleColor(aCol
.GetBlue()));
1115 pIn
+= nBytesPerPixel
;
1120 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1122 const BitmapColor aCol
=
1124 pBmpAcc
->GetPaletteColor( pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1125 pBmpAcc
->GetPixelFromData(pIn
, i
);
1127 // TODO(F3): Convert result to sRGB color space
1128 *pOut
++ = rendering::ARGBColor(1.0,
1129 toDoubleColor(aCol
.GetRed()),
1130 toDoubleColor(aCol
.GetGreen()),
1131 toDoubleColor(aCol
.GetBlue()));
1138 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
)
1140 SolarMutexGuard aGuard
;
1142 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1143 const std::size_t nLen( deviceColor
.getLength() );
1144 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1146 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1147 rendering::ARGBColor
* pOut( aRes
.getArray() );
1149 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
1150 ENSURE_OR_THROW(pBmpAcc
,
1151 "Unable to get BitmapAccess");
1153 if( m_aBmpEx
.IsAlpha() )
1155 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1156 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1157 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1159 // if palette, index is guaranteed to be 8 bit
1160 const BitmapColor aCol
=
1162 pBmpAcc
->GetPaletteColor(*pIn
) :
1163 pBmpAcc
->GetPixelFromData(pIn
,0);
1165 // TODO(F3): Convert result to sRGB color space
1166 const double nAlpha( 1.0 - toDoubleColor(pIn
[nNonAlphaBytes
]) );
1167 *pOut
++ = rendering::ARGBColor(nAlpha
,
1168 nAlpha
*toDoubleColor(aCol
.GetRed()),
1169 nAlpha
*toDoubleColor(aCol
.GetGreen()),
1170 nAlpha
*toDoubleColor(aCol
.GetBlue()));
1171 pIn
+= nBytesPerPixel
;
1176 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1178 const BitmapColor aCol
=
1180 pBmpAcc
->GetPaletteColor( pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1181 pBmpAcc
->GetPixelFromData(pIn
, i
);
1183 // TODO(F3): Convert result to sRGB color space
1184 *pOut
++ = rendering::ARGBColor(1.0,
1185 toDoubleColor(aCol
.GetRed()),
1186 toDoubleColor(aCol
.GetGreen()),
1187 toDoubleColor(aCol
.GetBlue()));
1194 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
)
1196 SolarMutexGuard aGuard
;
1198 const std::size_t nLen( rgbColor
.getLength() );
1199 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1201 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1202 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1203 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
1205 if( m_aBmpEx
.IsAlpha() )
1207 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1208 for( std::size_t i
=0; i
<nLen
; ++i
)
1210 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1211 toByteColor(rgbColor
[i
].Green
),
1212 toByteColor(rgbColor
[i
].Blue
));
1213 const BitmapColor aCol2
=
1216 sal::static_int_cast
<sal_uInt8
>(pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1219 pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1220 pColors
+= nNonAlphaBytes
;
1221 *pColors
++ = sal_uInt8(255);
1226 for( std::size_t i
=0; i
<nLen
; ++i
)
1228 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1229 toByteColor(rgbColor
[i
].Green
),
1230 toByteColor(rgbColor
[i
].Blue
));
1231 const BitmapColor aCol2
=
1234 sal::static_int_cast
<sal_uInt8
>(pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1237 pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1244 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
1246 SolarMutexGuard aGuard
;
1248 const std::size_t nLen( rgbColor
.getLength() );
1249 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1251 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1252 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1253 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
1255 if( m_aBmpEx
.IsAlpha() )
1257 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1258 for( std::size_t i
=0; i
<nLen
; ++i
)
1260 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1261 toByteColor(rgbColor
[i
].Green
),
1262 toByteColor(rgbColor
[i
].Blue
));
1263 const BitmapColor aCol2
=
1266 sal::static_int_cast
<sal_uInt8
>(pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1269 pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1270 pColors
+= nNonAlphaBytes
;
1271 *pColors
++ = 255 - toByteColor(rgbColor
[i
].Alpha
);
1276 for( std::size_t i
=0; i
<nLen
; ++i
)
1278 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1279 toByteColor(rgbColor
[i
].Green
),
1280 toByteColor(rgbColor
[i
].Blue
));
1281 const BitmapColor aCol2
=
1284 sal::static_int_cast
<sal_uInt8
>(pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1287 pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1294 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
1296 SolarMutexGuard aGuard
;
1298 const std::size_t 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());
1303 Bitmap::ScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
1305 if( m_aBmpEx
.IsAlpha() )
1307 const tools::Long
nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1308 for( std::size_t i
=0; i
<nLen
; ++i
)
1310 const double nAlpha( rgbColor
[i
].Alpha
);
1311 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1312 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1313 toByteColor(rgbColor
[i
].Blue
/ nAlpha
));
1314 const BitmapColor aCol2
=
1317 sal::static_int_cast
<sal_uInt8
>(pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1320 pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1321 pColors
+= nNonAlphaBytes
;
1322 *pColors
++ = 255 - toByteColor(nAlpha
);
1327 for( std::size_t i
=0; i
<nLen
; ++i
)
1329 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1330 toByteColor(rgbColor
[i
].Green
),
1331 toByteColor(rgbColor
[i
].Blue
));
1332 const BitmapColor aCol2
=
1335 sal::static_int_cast
<sal_uInt8
>(pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1338 pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */