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 BitmapScopedReadAccess
& 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 BitmapScopedReadAccess
& 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
= 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::N8BitPal
:
160 m_nBitsPerInputPixel
= 8;
161 m_aLayout
.IsMsbFirst
= false; // doesn't matter
164 case ScanlineFormat::N24BitTcBgr
:
166 m_nBitsPerInputPixel
= 24;
167 m_aLayout
.IsMsbFirst
= false; // doesn't matter
168 setComponentInfo( static_cast<sal_uInt32
>(0xff0000UL
),
169 static_cast<sal_uInt32
>(0x00ff00UL
),
170 static_cast<sal_uInt32
>(0x0000ffUL
) );
173 case ScanlineFormat::N24BitTcRgb
:
175 m_nBitsPerInputPixel
= 24;
176 m_aLayout
.IsMsbFirst
= false; // doesn't matter
177 setComponentInfo( static_cast<sal_uInt32
>(0x0000ffUL
),
178 static_cast<sal_uInt32
>(0x00ff00UL
),
179 static_cast<sal_uInt32
>(0xff0000UL
) );
182 case ScanlineFormat::N32BitTcAbgr
:
185 m_nBitsPerInputPixel
= 32;
186 m_aLayout
.IsMsbFirst
= false; // doesn't matter
188 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::ALPHA
,
189 /* 1 */ rendering::ColorComponentTag::RGB_BLUE
,
190 /* 2 */ rendering::ColorComponentTag::RGB_GREEN
,
191 /* 3 */ rendering::ColorComponentTag::RGB_RED
};
193 m_aComponentBitCounts
= { /* 0 */ 8,
205 case ScanlineFormat::N32BitTcArgb
:
208 m_nBitsPerInputPixel
= 32;
209 m_aLayout
.IsMsbFirst
= false; // doesn't matter
211 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::ALPHA
,
212 /* 1 */ rendering::ColorComponentTag::RGB_RED
,
213 /* 2 */ rendering::ColorComponentTag::RGB_GREEN
,
214 /* 3 */ rendering::ColorComponentTag::RGB_BLUE
};
216 m_aComponentBitCounts
= { /* 0 */ 8,
228 case ScanlineFormat::N32BitTcBgra
:
231 m_nBitsPerInputPixel
= 32;
232 m_aLayout
.IsMsbFirst
= false; // doesn't matter
234 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::RGB_BLUE
,
235 /* 1 */ rendering::ColorComponentTag::RGB_GREEN
,
236 /* 2 */ rendering::ColorComponentTag::RGB_RED
,
237 /* 3 */ rendering::ColorComponentTag::ALPHA
};
239 m_aComponentBitCounts
= { /* 0 */ 8,
251 case ScanlineFormat::N32BitTcRgba
:
254 m_nBitsPerInputPixel
= 32;
255 m_aLayout
.IsMsbFirst
= false; // doesn't matter
257 m_aComponentTags
= { /* 0 */ rendering::ColorComponentTag::RGB_RED
,
258 /* 1 */ rendering::ColorComponentTag::RGB_GREEN
,
259 /* 2 */ rendering::ColorComponentTag::RGB_BLUE
,
260 /* 3 */ rendering::ColorComponentTag::ALPHA
};
262 m_aComponentBitCounts
= { /* 0 */ 8,
274 case ScanlineFormat::N32BitTcMask
:
276 m_nBitsPerInputPixel
= 32;
277 m_aLayout
.IsMsbFirst
= false; // doesn't matter
278 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
279 m_pBmpAcc
->GetColorMask().GetGreenMask(),
280 m_pBmpAcc
->GetColorMask().GetBlueMask() );
284 OSL_FAIL( "unsupported bitmap format" );
290 m_aComponentTags
= { rendering::ColorComponentTag::INDEX
};
292 m_aComponentBitCounts
= { m_nBitsPerInputPixel
};
297 m_nBitsPerOutputPixel
= m_nBitsPerInputPixel
;
298 if( !m_aBmpEx
.IsAlpha() )
301 // TODO(P1): need to interleave alpha with bitmap data -
302 // won't fuss with less-than-8 bit for now
303 m_nBitsPerOutputPixel
= std::max(sal_Int32(8),m_nBitsPerInputPixel
);
305 // check whether alpha goes in front or behind the
306 // bitcount sequence. If pixel format is little endian,
307 // put it behind all the other channels. If it's big
308 // endian, put it in front (because later, the actual data
309 // always gets written after the pixel data)
311 // TODO(Q1): slight catch - in the case of the
312 // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
313 // channels might happen!
314 m_aComponentTags
.realloc(m_aComponentTags
.getLength()+1);
315 m_aComponentTags
.getArray()[m_aComponentTags
.getLength()-1] = rendering::ColorComponentTag::ALPHA
;
317 m_aComponentBitCounts
.realloc(m_aComponentBitCounts
.getLength()+1);
318 m_aComponentBitCounts
.getArray()[m_aComponentBitCounts
.getLength()-1] = m_aBmpEx
.IsAlpha() ? 8 : 1;
320 // always add a full byte to the pixel size, otherwise
321 // pixel packing hell breaks loose.
322 m_nBitsPerOutputPixel
+= 8;
324 // adapt scanline parameters
325 const Size aSize
= m_aBitmap
.GetSizePixel();
326 m_aLayout
.ScanLineBytes
=
327 m_aLayout
.ScanLineStride
= (aSize
.Width()*m_nBitsPerOutputPixel
+ 7)/8;
330 VclCanvasBitmap::~VclCanvasBitmap()
335 geometry::IntegerSize2D SAL_CALL
VclCanvasBitmap::getSize()
337 SolarMutexGuard aGuard
;
338 return integerSize2DFromSize( m_aBitmap
.GetSizePixel() );
341 sal_Bool SAL_CALL
VclCanvasBitmap::hasAlpha()
343 SolarMutexGuard aGuard
;
344 return m_aBmpEx
.IsAlpha();
347 uno::Reference
< rendering::XBitmap
> SAL_CALL
VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D
& newSize
,
350 SolarMutexGuard aGuard
;
352 BitmapEx
aNewBmp( m_aBitmap
);
353 aNewBmp
.Scale( sizeFromRealSize2D( newSize
), beFast
? BmpScaleFlag::Default
: BmpScaleFlag::BestQuality
);
354 return uno::Reference
<rendering::XBitmap
>( new VclCanvasBitmap( aNewBmp
) );
357 // XIntegerReadOnlyBitmap
358 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getData( rendering::IntegerBitmapLayout
& bitmapLayout
,
359 const geometry::IntegerRectangle2D
& rect
)
361 SolarMutexGuard aGuard
;
363 bitmapLayout
= getMemoryLayout();
365 const ::tools::Rectangle
aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect
) );
366 if( aRequestedArea
.IsEmpty() )
367 return uno::Sequence
< sal_Int8
>();
369 // Invalid/empty bitmap: no data available
371 throw lang::IndexOutOfBoundsException();
372 if( m_aBmpEx
.IsAlpha() && !m_pAlphaAcc
)
373 throw lang::IndexOutOfBoundsException();
375 if( aRequestedArea
.Left() < 0 || aRequestedArea
.Top() < 0 ||
376 aRequestedArea
.Right() > m_pBmpAcc
->Width() ||
377 aRequestedArea
.Bottom() > m_pBmpAcc
->Height() )
379 throw lang::IndexOutOfBoundsException();
382 uno::Sequence
< sal_Int8
> aRet
;
383 tools::Rectangle
aRequestedBytes( aRequestedArea
);
385 // adapt to byte boundaries
386 aRequestedBytes
.SetLeft( aRequestedArea
.Left()*m_nBitsPerOutputPixel
/8 );
387 aRequestedBytes
.SetRight( (aRequestedArea
.Right()*m_nBitsPerOutputPixel
+ 7)/8 );
389 // copy stuff to output sequence
390 aRet
.realloc(aRequestedBytes
.getOpenWidth()*aRequestedBytes
.getOpenHeight());
391 sal_Int8
* pOutBuf
= aRet
.getArray();
393 bitmapLayout
.ScanLines
= aRequestedBytes
.getOpenHeight();
394 bitmapLayout
.ScanLineBytes
=
395 bitmapLayout
.ScanLineStride
= aRequestedBytes
.getOpenWidth();
397 sal_Int32 nScanlineStride
=bitmapLayout
.ScanLineStride
;
398 if (m_pBmpAcc
->IsBottomUp())
400 pOutBuf
+= bitmapLayout
.ScanLineStride
*(aRequestedBytes
.getOpenHeight()-1);
401 nScanlineStride
*= -1;
404 if( !m_aBmpEx
.IsAlpha() )
406 BitmapScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
407 OSL_ENSURE(pBmpAcc
,"Invalid bmp read access");
409 // can return bitmap data as-is
410 for( tools::Long y
=aRequestedBytes
.Top(); y
<aRequestedBytes
.Bottom(); ++y
)
412 Scanline pScan
= pBmpAcc
->GetScanline(y
);
413 memcpy(pOutBuf
, pScan
+aRequestedBytes
.Left(), aRequestedBytes
.getOpenWidth());
414 pOutBuf
+= nScanlineStride
;
419 BitmapScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
420 BitmapScopedReadAccess
& pAlphaAcc
= getAlphaReadAccess();
421 OSL_ENSURE(pBmpAcc
,"Invalid bmp read access");
422 OSL_ENSURE(pAlphaAcc
,"Invalid alpha read access");
424 // interleave alpha with bitmap data - note, bitcount is
425 // always integer multiple of 8
426 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
427 "Transparent bitmap bitcount not integer multiple of 8" );
429 for( tools::Long y
=aRequestedArea
.Top(); y
<aRequestedArea
.Bottom(); ++y
)
431 sal_Int8
* pOutScan
= pOutBuf
;
433 if( m_nBitsPerInputPixel
< 8 )
435 // input less than a byte - copy via GetPixel()
436 for( tools::Long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
438 *pOutScan
++ = pBmpAcc
->GetPixelIndex(y
,x
);
439 // vcl used to store transparency. Now it stores alpha. But we need the UNO
440 // interface to still preserve the old interface.
441 *pOutScan
++ = 255 - pAlphaAcc
->GetPixelIndex(y
,x
);
446 const tools::Long
nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
447 const tools::Long
nScanlineOffsetLeft(aRequestedArea
.Left()*nNonAlphaBytes
);
448 Scanline pScan
= pBmpAcc
->GetScanline(y
) + nScanlineOffsetLeft
;
449 Scanline pScanlineAlpha
= pAlphaAcc
->GetScanline( y
);
451 // input integer multiple of byte - copy directly
452 for( tools::Long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
454 for( tools::Long i
=0; i
<nNonAlphaBytes
; ++i
)
455 *pOutScan
++ = *pScan
++;
456 // vcl used to store transparency. Now it stores alpha. But we need the UNO
457 // interface to still preserve the old interface.
458 *pOutScan
++ = 255 - pAlphaAcc
->GetIndexFromData( pScanlineAlpha
, x
);
462 pOutBuf
+= nScanlineStride
;
469 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout
& bitmapLayout
,
470 const geometry::IntegerPoint2D
& pos
)
472 SolarMutexGuard aGuard
;
474 bitmapLayout
= getMemoryLayout();
476 // Invalid/empty bitmap: no data available
478 throw lang::IndexOutOfBoundsException();
479 if( m_aBmpEx
.IsAlpha() && !m_pAlphaAcc
)
480 throw lang::IndexOutOfBoundsException();
482 if( pos
.X
< 0 || pos
.Y
< 0 ||
483 pos
.X
> m_pBmpAcc
->Width() || pos
.Y
> m_pBmpAcc
->Height() )
485 throw lang::IndexOutOfBoundsException();
488 uno::Sequence
< sal_Int8
> aRet((m_nBitsPerOutputPixel
+ 7)/8);
489 sal_Int8
* pOutBuf
= aRet
.getArray();
491 // copy stuff to output sequence
492 bitmapLayout
.ScanLines
= 1;
493 bitmapLayout
.ScanLineBytes
=
494 bitmapLayout
.ScanLineStride
= aRet
.getLength();
496 const tools::Long
nScanlineLeftOffset( pos
.X
*m_nBitsPerInputPixel
/8 );
497 if( !m_aBmpEx
.IsAlpha() )
499 BitmapScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
500 assert(pBmpAcc
&& "Invalid bmp read access");
502 // can return bitmap data as-is
503 Scanline pScan
= pBmpAcc
->GetScanline(pos
.Y
);
504 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, aRet
.getLength() );
508 BitmapScopedReadAccess
& pBmpAcc
= getBitmapReadAccess();
509 BitmapScopedReadAccess
& pAlphaAcc
= getAlphaReadAccess();
510 assert(pBmpAcc
&& "Invalid bmp read access");
511 assert(pAlphaAcc
&& "Invalid alpha read access");
513 // interleave alpha with bitmap data - note, bitcount is
514 // always integer multiple of 8
515 assert((m_nBitsPerOutputPixel
& 0x07) == 0 &&
516 "Transparent bitmap bitcount not integer multiple of 8" );
518 if( m_nBitsPerInputPixel
< 8 )
520 // input less than a byte - copy via GetPixel()
521 *pOutBuf
++ = pBmpAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
522 // vcl used to store transparency. Now it stores alpha. But we need the UNO
523 // interface to still preserve the old interface.
524 *pOutBuf
= 255 - 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 // vcl used to store transparency. Now it stores alpha. But we need the UNO
535 // interface to still preserve the old interface.
536 *pOutBuf
++ = 255 - pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
543 uno::Reference
< rendering::XBitmapPalette
> VclCanvasBitmap::getPalette()
545 SolarMutexGuard aGuard
;
547 uno::Reference
< XBitmapPalette
> aRet
;
554 rendering::IntegerBitmapLayout SAL_CALL
VclCanvasBitmap::getMemoryLayout()
556 SolarMutexGuard aGuard
;
558 rendering::IntegerBitmapLayout
aLayout( m_aLayout
);
560 // only set references to self on separate copy of
561 // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
562 // a circular reference!
564 aLayout
.Palette
.set( this );
566 aLayout
.ColorSpace
.set( this );
571 sal_Int32 SAL_CALL
VclCanvasBitmap::getNumberOfEntries()
573 SolarMutexGuard aGuard
;
578 return m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ;
581 sal_Bool SAL_CALL
VclCanvasBitmap::getIndex( uno::Sequence
< double >& o_entry
, sal_Int32 nIndex
)
583 SolarMutexGuard aGuard
;
585 const sal_uInt16
nCount( m_pBmpAcc
?
586 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
587 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
588 if( nIndex
< 0 || nIndex
>= nCount
)
589 throw lang::IndexOutOfBoundsException(u
"Palette index out of range"_ustr
,
590 static_cast<rendering::XBitmapPalette
*>(this));
592 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(sal::static_int_cast
<sal_uInt16
>(nIndex
));
594 double* pColor
=o_entry
.getArray();
595 pColor
[0] = aCol
.GetRed();
596 pColor
[1] = aCol
.GetGreen();
597 pColor
[2] = aCol
.GetBlue();
599 return true; // no palette transparency here.
602 sal_Bool SAL_CALL
VclCanvasBitmap::setIndex( const uno::Sequence
< double >&, sal_Bool
, sal_Int32 nIndex
)
604 SolarMutexGuard aGuard
;
606 const sal_uInt16
nCount( m_pBmpAcc
?
607 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
609 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
610 if( nIndex
< 0 || nIndex
>= nCount
)
611 throw lang::IndexOutOfBoundsException(u
"Palette index out of range"_ustr
,
612 static_cast<rendering::XBitmapPalette
*>(this));
614 return false; // read-only implementation
617 uno::Reference
< rendering::XColorSpace
> SAL_CALL
VclCanvasBitmap::getColorSpace( )
619 // this is the method from XBitmapPalette. Return palette color
621 static uno::Reference
<rendering::XColorSpace
> gColorSpace
= vcl::unotools::createStandardColorSpace();
625 sal_Int8 SAL_CALL
VclCanvasBitmap::getType( )
627 return rendering::ColorSpaceType::RGB
;
630 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::getComponentTags( )
632 SolarMutexGuard aGuard
;
633 return m_aComponentTags
;
636 sal_Int8 SAL_CALL
VclCanvasBitmap::getRenderingIntent( )
638 return rendering::RenderingIntent::PERCEPTUAL
;
641 uno::Sequence
< ::beans::PropertyValue
> SAL_CALL
VclCanvasBitmap::getProperties( )
643 return uno::Sequence
< ::beans::PropertyValue
>();
646 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertColorSpace( const uno::Sequence
< double >& deviceColor
,
647 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
)
649 // TODO(P3): if we know anything about target
650 // colorspace, this can be greatly sped up
651 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
652 convertToARGB(deviceColor
));
653 return targetColorSpace
->convertFromARGB(aIntermediate
);
656 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertToRGB( const uno::Sequence
< double >& deviceColor
)
658 SolarMutexGuard aGuard
;
660 const std::size_t nLen( deviceColor
.getLength() );
661 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
662 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
663 "number of channels no multiple of pixel element count",
664 static_cast<rendering::XBitmapPalette
*>(this), 01);
666 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/nComponentsPerPixel
);
667 rendering::RGBColor
* pOut( aRes
.getArray() );
671 OSL_ENSURE(m_nIndexIndex
!= -1,
672 "Invalid color channel indices");
673 ENSURE_OR_THROW(m_pBmpAcc
,
674 "Unable to get BitmapAccess");
676 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
678 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
679 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
681 // TODO(F3): Convert result to sRGB color space
682 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
683 toDoubleColor(aCol
.GetGreen()),
684 toDoubleColor(aCol
.GetBlue()));
689 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
690 "Invalid color channel indices");
692 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
694 // TODO(F3): Convert result to sRGB color space
695 *pOut
++ = rendering::RGBColor(
696 deviceColor
[i
+m_nRedIndex
],
697 deviceColor
[i
+m_nGreenIndex
],
698 deviceColor
[i
+m_nBlueIndex
]);
705 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToARGB( const uno::Sequence
< double >& deviceColor
)
707 SolarMutexGuard aGuard
;
709 const std::size_t nLen( deviceColor
.getLength() );
710 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
711 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
712 "number of channels no multiple of pixel element count",
713 static_cast<rendering::XBitmapPalette
*>(this), 01);
715 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
716 rendering::ARGBColor
* pOut( aRes
.getArray() );
720 OSL_ENSURE(m_nIndexIndex
!= -1,
721 "Invalid color channel indices");
722 ENSURE_OR_THROW(m_pBmpAcc
,
723 "Unable to get BitmapAccess");
725 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
727 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
728 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
730 // TODO(F3): Convert result to sRGB color space
731 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
732 *pOut
++ = rendering::ARGBColor(nAlpha
,
733 toDoubleColor(aCol
.GetRed()),
734 toDoubleColor(aCol
.GetGreen()),
735 toDoubleColor(aCol
.GetBlue()));
740 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
741 "Invalid color channel indices");
743 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
745 // TODO(F3): Convert result to sRGB color space
746 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
747 *pOut
++ = rendering::ARGBColor(
749 deviceColor
[i
+m_nRedIndex
],
750 deviceColor
[i
+m_nGreenIndex
],
751 deviceColor
[i
+m_nBlueIndex
]);
758 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToPARGB( const uno::Sequence
< double >& deviceColor
)
760 SolarMutexGuard aGuard
;
762 const std::size_t nLen( deviceColor
.getLength() );
763 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
764 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
765 "number of channels no multiple of pixel element count",
766 static_cast<rendering::XBitmapPalette
*>(this), 01);
768 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
769 rendering::ARGBColor
* pOut( aRes
.getArray() );
773 OSL_ENSURE(m_nIndexIndex
!= -1,
774 "Invalid color channel indices");
775 ENSURE_OR_THROW(m_pBmpAcc
,
776 "Unable to get BitmapAccess");
778 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
780 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
781 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
783 // TODO(F3): Convert result to sRGB color space
784 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
785 *pOut
++ = rendering::ARGBColor(nAlpha
,
786 nAlpha
*toDoubleColor(aCol
.GetRed()),
787 nAlpha
*toDoubleColor(aCol
.GetGreen()),
788 nAlpha
*toDoubleColor(aCol
.GetBlue()));
793 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
794 "Invalid color channel indices");
796 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
798 // TODO(F3): Convert result to sRGB color space
799 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
800 *pOut
++ = rendering::ARGBColor(
802 nAlpha
*deviceColor
[i
+m_nRedIndex
],
803 nAlpha
*deviceColor
[i
+m_nGreenIndex
],
804 nAlpha
*deviceColor
[i
+m_nBlueIndex
]);
811 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
)
813 SolarMutexGuard aGuard
;
815 const std::size_t nLen( rgbColor
.getLength() );
816 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
818 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
819 double* pColors
=aRes
.getArray();
823 for( const auto& rIn
: rgbColor
)
825 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
826 BitmapColor(toByteColor(rIn
.Red
),
827 toByteColor(rIn
.Green
),
828 toByteColor(rIn
.Blue
)));
829 if( m_nAlphaIndex
!= -1 )
830 pColors
[m_nAlphaIndex
] = 1.0;
832 pColors
+= nComponentsPerPixel
;
837 for( const auto& rIn
: rgbColor
)
839 pColors
[m_nRedIndex
] = rIn
.Red
;
840 pColors
[m_nGreenIndex
] = rIn
.Green
;
841 pColors
[m_nBlueIndex
] = rIn
.Blue
;
842 if( m_nAlphaIndex
!= -1 )
843 pColors
[m_nAlphaIndex
] = 1.0;
845 pColors
+= nComponentsPerPixel
;
851 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
853 SolarMutexGuard aGuard
;
855 const std::size_t nLen( rgbColor
.getLength() );
856 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
858 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
859 double* pColors
=aRes
.getArray();
863 for( const auto& rIn
: rgbColor
)
865 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
866 BitmapColor(toByteColor(rIn
.Red
),
867 toByteColor(rIn
.Green
),
868 toByteColor(rIn
.Blue
)));
869 if( m_nAlphaIndex
!= -1 )
870 pColors
[m_nAlphaIndex
] = rIn
.Alpha
;
872 pColors
+= nComponentsPerPixel
;
877 for( const auto& rIn
: rgbColor
)
879 pColors
[m_nRedIndex
] = rIn
.Red
;
880 pColors
[m_nGreenIndex
] = rIn
.Green
;
881 pColors
[m_nBlueIndex
] = rIn
.Blue
;
882 if( m_nAlphaIndex
!= -1 )
883 pColors
[m_nAlphaIndex
] = rIn
.Alpha
;
885 pColors
+= nComponentsPerPixel
;
891 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
)
893 SolarMutexGuard aGuard
;
895 const std::size_t nLen( rgbColor
.getLength() );
896 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
898 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
899 double* pColors
=aRes
.getArray();
903 for( const auto& rIn
: rgbColor
)
905 const double nAlpha( rIn
.Alpha
);
906 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
907 BitmapColor(toByteColor(rIn
.Red
/ nAlpha
),
908 toByteColor(rIn
.Green
/ nAlpha
),
909 toByteColor(rIn
.Blue
/ nAlpha
)));
910 if( m_nAlphaIndex
!= -1 )
911 pColors
[m_nAlphaIndex
] = nAlpha
;
913 pColors
+= nComponentsPerPixel
;
918 for( const auto& rIn
: rgbColor
)
920 const double nAlpha( rIn
.Alpha
);
921 pColors
[m_nRedIndex
] = rIn
.Red
/ nAlpha
;
922 pColors
[m_nGreenIndex
] = rIn
.Green
/ nAlpha
;
923 pColors
[m_nBlueIndex
] = rIn
.Blue
/ nAlpha
;
924 if( m_nAlphaIndex
!= -1 )
925 pColors
[m_nAlphaIndex
] = nAlpha
;
927 pColors
+= nComponentsPerPixel
;
933 sal_Int32 SAL_CALL
VclCanvasBitmap::getBitsPerPixel( )
935 return m_nBitsPerOutputPixel
;
938 uno::Sequence
< ::sal_Int32
> SAL_CALL
VclCanvasBitmap::getComponentBitCounts( )
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 BitmapScopedReadAccess
& 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 BitmapScopedReadAccess
& 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 BitmapScopedReadAccess
& 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 BitmapScopedReadAccess
& 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 BitmapScopedReadAccess
& 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 BitmapScopedReadAccess
& 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: */