1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/util/Endianness.hpp>
21 #include <com/sun/star/rendering/ColorComponentTag.hpp>
22 #include <com/sun/star/rendering/ColorSpaceType.hpp>
23 #include <com/sun/star/rendering/RenderingIntent.hpp>
25 #include <rtl/instance.hxx>
26 #include <osl/mutex.hxx>
28 #include <tools/diagnose_ex.h>
29 #include <canvasbitmap.hxx>
30 #include <vcl/canvastools.hxx>
31 #include <vcl/bitmapaccess.hxx>
32 #include <vcl/svapp.hxx>
36 using namespace vcl::unotools
;
37 using namespace ::com::sun::star
;
41 // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
43 // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
44 // unrolled loop. See e.g. Hackers Delight, p. 66
45 inline sal_Int32
bitcount( sal_uInt32 val
)
47 val
= val
- ((val
>> 1) & 0x55555555);
48 val
= (val
& 0x33333333) + ((val
>> 2) & 0x33333333);
49 val
= (val
+ (val
>> 4)) & 0x0F0F0F0F;
50 val
= val
+ (val
>> 8);
51 val
= val
+ (val
>> 16);
52 return sal_Int32(val
& 0x0000003F);
56 void VclCanvasBitmap::setComponentInfo( sal_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 VclCanvasBitmap::VclCanvasBitmap( const BitmapEx
& rBitmap
) :
99 m_aBitmap( rBitmap
.GetBitmap() ),
101 m_pBmpAcc( m_aBitmap
),
103 m_aComponentBitCounts(),
105 m_nBitsPerInputPixel(0),
106 m_nBitsPerOutputPixel(0),
115 if( m_aBmpEx
.IsTransparent() )
117 m_aAlpha
= m_aBmpEx
.IsAlpha() ? m_aBmpEx
.GetAlpha().GetBitmap() : m_aBmpEx
.GetMask();
118 m_pAlphaAcc
= Bitmap::ScopedReadAccess(m_aAlpha
);
121 m_aLayout
.ScanLines
= 0;
122 m_aLayout
.ScanLineBytes
= 0;
123 m_aLayout
.ScanLineStride
= 0;
124 m_aLayout
.PlaneStride
= 0;
125 m_aLayout
.ColorSpace
.clear();
126 m_aLayout
.Palette
.clear();
127 m_aLayout
.IsMsbFirst
= false;
131 m_aLayout
.ScanLines
= m_pBmpAcc
->Height();
132 m_aLayout
.ScanLineBytes
= (m_pBmpAcc
->GetBitCount()*m_pBmpAcc
->Width() + 7) / 8;
133 m_aLayout
.ScanLineStride
= m_pBmpAcc
->GetScanlineSize();
134 m_aLayout
.PlaneStride
= 0;
136 switch( m_pBmpAcc
->GetScanlineFormat() )
138 case ScanlineFormat::N1BitMsbPal
:
140 m_nBitsPerInputPixel
= 1;
141 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
142 m_aLayout
.IsMsbFirst
= true;
145 case ScanlineFormat::N1BitLsbPal
:
147 m_nBitsPerInputPixel
= 1;
148 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
149 m_aLayout
.IsMsbFirst
= false;
152 case ScanlineFormat::N4BitMsnPal
:
154 m_nBitsPerInputPixel
= 4;
155 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
156 m_aLayout
.IsMsbFirst
= true;
159 case ScanlineFormat::N4BitLsnPal
:
161 m_nBitsPerInputPixel
= 4;
162 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
163 m_aLayout
.IsMsbFirst
= false;
166 case ScanlineFormat::N8BitPal
:
168 m_nBitsPerInputPixel
= 8;
169 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
170 m_aLayout
.IsMsbFirst
= false; // doesn't matter
173 case ScanlineFormat::N8BitTcMask
:
175 m_nBitsPerInputPixel
= 8;
176 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
177 m_aLayout
.IsMsbFirst
= false; // doesn't matter
178 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
179 m_pBmpAcc
->GetColorMask().GetGreenMask(),
180 m_pBmpAcc
->GetColorMask().GetBlueMask() );
183 case ScanlineFormat::N16BitTcMsbMask
:
185 m_nBitsPerInputPixel
= 16;
186 m_nEndianness
= util::Endianness::BIG
;
187 m_aLayout
.IsMsbFirst
= false; // doesn't matter
188 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
189 m_pBmpAcc
->GetColorMask().GetGreenMask(),
190 m_pBmpAcc
->GetColorMask().GetBlueMask() );
193 case ScanlineFormat::N16BitTcLsbMask
:
195 m_nBitsPerInputPixel
= 16;
196 m_nEndianness
= util::Endianness::LITTLE
;
197 m_aLayout
.IsMsbFirst
= false; // doesn't matter
198 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
199 m_pBmpAcc
->GetColorMask().GetGreenMask(),
200 m_pBmpAcc
->GetColorMask().GetBlueMask() );
203 case ScanlineFormat::N24BitTcBgr
:
205 m_nBitsPerInputPixel
= 24;
206 m_nEndianness
= util::Endianness::LITTLE
;
207 m_aLayout
.IsMsbFirst
= false; // doesn't matter
208 setComponentInfo( static_cast<sal_uInt32
>(0xff0000UL
),
209 static_cast<sal_uInt32
>(0x00ff00UL
),
210 static_cast<sal_uInt32
>(0x0000ffUL
) );
213 case ScanlineFormat::N24BitTcRgb
:
215 m_nBitsPerInputPixel
= 24;
216 m_nEndianness
= util::Endianness::LITTLE
;
217 m_aLayout
.IsMsbFirst
= false; // doesn't matter
218 setComponentInfo( static_cast<sal_uInt32
>(0x0000ffUL
),
219 static_cast<sal_uInt32
>(0x00ff00UL
),
220 static_cast<sal_uInt32
>(0xff0000UL
) );
223 case ScanlineFormat::N24BitTcMask
:
225 m_nBitsPerInputPixel
= 24;
226 m_nEndianness
= util::Endianness::LITTLE
;
227 m_aLayout
.IsMsbFirst
= false; // doesn't matter
228 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
229 m_pBmpAcc
->GetColorMask().GetGreenMask(),
230 m_pBmpAcc
->GetColorMask().GetBlueMask() );
233 case ScanlineFormat::N32BitTcAbgr
:
236 m_nBitsPerInputPixel
= 32;
237 m_nEndianness
= util::Endianness::LITTLE
;
238 m_aLayout
.IsMsbFirst
= false; // doesn't matter
240 m_aComponentTags
.realloc(4);
241 sal_Int8
* pTags
= m_aComponentTags
.getArray();
242 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
243 pTags
[1] = rendering::ColorComponentTag::RGB_BLUE
;
244 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
245 pTags
[3] = rendering::ColorComponentTag::RGB_RED
;
247 m_aComponentBitCounts
.realloc(4);
248 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
261 case ScanlineFormat::N32BitTcArgb
:
264 m_nBitsPerInputPixel
= 32;
265 m_nEndianness
= util::Endianness::LITTLE
;
266 m_aLayout
.IsMsbFirst
= false; // doesn't matter
268 m_aComponentTags
.realloc(4);
269 sal_Int8
* pTags
= m_aComponentTags
.getArray();
270 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
271 pTags
[1] = rendering::ColorComponentTag::RGB_RED
;
272 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
273 pTags
[3] = rendering::ColorComponentTag::RGB_BLUE
;
275 m_aComponentBitCounts
.realloc(4);
276 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
289 case ScanlineFormat::N32BitTcBgra
:
292 m_nBitsPerInputPixel
= 32;
293 m_nEndianness
= util::Endianness::LITTLE
;
294 m_aLayout
.IsMsbFirst
= false; // doesn't matter
296 m_aComponentTags
.realloc(4);
297 sal_Int8
* pTags
= m_aComponentTags
.getArray();
298 pTags
[0] = rendering::ColorComponentTag::RGB_BLUE
;
299 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
300 pTags
[2] = rendering::ColorComponentTag::RGB_RED
;
301 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
303 m_aComponentBitCounts
.realloc(4);
304 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
317 case ScanlineFormat::N32BitTcRgba
:
320 m_nBitsPerInputPixel
= 32;
321 m_nEndianness
= util::Endianness::LITTLE
;
322 m_aLayout
.IsMsbFirst
= false; // doesn't matter
324 m_aComponentTags
.realloc(4);
325 sal_Int8
* pTags
= m_aComponentTags
.getArray();
326 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
327 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
328 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
329 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
331 m_aComponentBitCounts
.realloc(4);
332 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
345 case ScanlineFormat::N32BitTcMask
:
347 m_nBitsPerInputPixel
= 32;
348 m_nEndianness
= util::Endianness::LITTLE
;
349 m_aLayout
.IsMsbFirst
= false; // doesn't matter
350 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
351 m_pBmpAcc
->GetColorMask().GetGreenMask(),
352 m_pBmpAcc
->GetColorMask().GetBlueMask() );
356 OSL_FAIL( "unsupported bitmap format" );
362 m_aComponentTags
.realloc(1);
363 m_aComponentTags
[0] = rendering::ColorComponentTag::INDEX
;
365 m_aComponentBitCounts
.realloc(1);
366 m_aComponentBitCounts
[0] = m_nBitsPerInputPixel
;
371 m_nBitsPerOutputPixel
= m_nBitsPerInputPixel
;
372 if( m_aBmpEx
.IsTransparent() )
374 // TODO(P1): need to interleave alpha with bitmap data -
375 // won't fuss with less-than-8 bit for now
376 m_nBitsPerOutputPixel
= std::max(sal_Int32(8),m_nBitsPerInputPixel
);
378 // check whether alpha goes in front or behind the
379 // bitcount sequence. If pixel format is little endian,
380 // put it behind all the other channels. If it's big
381 // endian, put it in front (because later, the actual data
382 // always gets written after the pixel data)
384 // TODO(Q1): slight catch - in the case of the
385 // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
386 // channels might happen!
387 m_aComponentTags
.realloc(m_aComponentTags
.getLength()+1);
388 m_aComponentTags
[m_aComponentTags
.getLength()-1] = rendering::ColorComponentTag::ALPHA
;
390 m_aComponentBitCounts
.realloc(m_aComponentBitCounts
.getLength()+1);
391 m_aComponentBitCounts
[m_aComponentBitCounts
.getLength()-1] = m_aBmpEx
.IsAlpha() ? 8 : 1;
393 if( m_nEndianness
== util::Endianness::BIG
)
395 // put alpha in front of all the color channels
396 sal_Int8
* pTags
=m_aComponentTags
.getArray();
397 sal_Int32
* pCounts
=m_aComponentBitCounts
.getArray();
399 pTags
+m_aComponentTags
.getLength()-1,
400 pTags
+m_aComponentTags
.getLength());
402 pCounts
+m_aComponentBitCounts
.getLength()-1,
403 pCounts
+m_aComponentBitCounts
.getLength());
411 // always add a full byte to the pixel size, otherwise
412 // pixel packing hell breaks loose.
413 m_nBitsPerOutputPixel
+= 8;
415 // adapt scanline parameters
416 const Size aSize
= m_aBitmap
.GetSizePixel();
417 m_aLayout
.ScanLineBytes
=
418 m_aLayout
.ScanLineStride
= (aSize
.Width()*m_nBitsPerOutputPixel
+ 7)/8;
423 VclCanvasBitmap::~VclCanvasBitmap()
428 geometry::IntegerSize2D SAL_CALL
VclCanvasBitmap::getSize() throw (uno::RuntimeException
, std::exception
)
430 SolarMutexGuard aGuard
;
431 return integerSize2DFromSize( m_aBitmap
.GetSizePixel() );
434 sal_Bool SAL_CALL
VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException
, std::exception
)
436 SolarMutexGuard aGuard
;
437 return m_aBmpEx
.IsTransparent();
440 uno::Reference
< rendering::XBitmap
> SAL_CALL
VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D
& newSize
,
441 sal_Bool beFast
) throw (uno::RuntimeException
, std::exception
)
443 SolarMutexGuard aGuard
;
445 BitmapEx
aNewBmp( m_aBitmap
);
446 aNewBmp
.Scale( sizeFromRealSize2D( newSize
), beFast
? BmpScaleFlag::Default
: BmpScaleFlag::BestQuality
);
447 return uno::Reference
<rendering::XBitmap
>( new VclCanvasBitmap( aNewBmp
) );
450 // XIntegerReadOnlyBitmap
451 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getData( rendering::IntegerBitmapLayout
& bitmapLayout
,
452 const geometry::IntegerRectangle2D
& rect
) throw( lang::IndexOutOfBoundsException
,
453 rendering::VolatileContentDestroyedException
,
454 uno::RuntimeException
, std::exception
)
456 SolarMutexGuard aGuard
;
458 bitmapLayout
= getMemoryLayout();
460 const ::Rectangle
aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect
) );
461 if( aRequestedArea
.IsEmpty() )
462 return uno::Sequence
< sal_Int8
>();
464 // Invalid/empty bitmap: no data available
466 throw lang::IndexOutOfBoundsException();
467 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
468 throw lang::IndexOutOfBoundsException();
470 if( aRequestedArea
.Left() < 0 || aRequestedArea
.Top() < 0 ||
471 aRequestedArea
.Right() > m_pBmpAcc
->Width() ||
472 aRequestedArea
.Bottom() > m_pBmpAcc
->Height() )
474 throw lang::IndexOutOfBoundsException();
477 uno::Sequence
< sal_Int8
> aRet
;
478 Rectangle
aRequestedBytes( aRequestedArea
);
480 // adapt to byte boundaries
481 aRequestedBytes
.Left() = aRequestedArea
.Left()*m_nBitsPerOutputPixel
/8;
482 aRequestedBytes
.Right() = (aRequestedArea
.Right()*m_nBitsPerOutputPixel
+ 7)/8;
484 // copy stuff to output sequence
485 aRet
.realloc(aRequestedBytes
.getWidth()*aRequestedBytes
.getHeight());
486 sal_Int8
* pOutBuf
= aRet
.getArray();
488 bitmapLayout
.ScanLines
= aRequestedBytes
.getHeight();
489 bitmapLayout
.ScanLineBytes
=
490 bitmapLayout
.ScanLineStride
= aRequestedBytes
.getWidth();
492 sal_Int32 nScanlineStride
=bitmapLayout
.ScanLineStride
;
493 if( !(m_pBmpAcc
->GetScanlineFormat() & ScanlineFormat::TopDown
) )
495 pOutBuf
+= bitmapLayout
.ScanLineStride
*(aRequestedBytes
.getHeight()-1);
496 nScanlineStride
*= -1;
499 if( !m_aBmpEx
.IsTransparent() )
501 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
503 // can return bitmap data as-is
504 for( long y
=aRequestedBytes
.Top(); y
<aRequestedBytes
.Bottom(); ++y
)
506 Scanline pScan
= m_pBmpAcc
->GetScanline(y
);
507 memcpy(pOutBuf
, pScan
+aRequestedBytes
.Left(), aRequestedBytes
.getWidth());
508 pOutBuf
+= nScanlineStride
;
513 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
514 OSL_ENSURE(m_pAlphaAcc
,"Invalid alpha read access");
516 // interleave alpha with bitmap data - note, bitcount is
517 // always integer multiple of 8
518 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
519 "Transparent bitmap bitcount not integer multiple of 8" );
521 for( long y
=aRequestedArea
.Top(); y
<aRequestedArea
.Bottom(); ++y
)
523 sal_Int8
* pOutScan
= pOutBuf
;
525 if( m_nBitsPerInputPixel
< 8 )
527 // input less than a byte - copy via GetPixel()
528 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
530 *pOutScan
++ = m_pBmpAcc
->GetPixelIndex(y
,x
);
531 *pOutScan
++ = m_pAlphaAcc
->GetPixelIndex(y
,x
);
536 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
537 const long nScanlineOffsetLeft(aRequestedArea
.Left()*nNonAlphaBytes
);
538 Scanline pScan
= m_pBmpAcc
->GetScanline(y
) + nScanlineOffsetLeft
;
540 // input integer multiple of byte - copy directly
541 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
543 for( long i
=0; i
<nNonAlphaBytes
; ++i
)
544 *pOutScan
++ = *pScan
++;
545 *pOutScan
++ = m_pAlphaAcc
->GetPixelIndex( y
, x
);
549 pOutBuf
+= nScanlineStride
;
556 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout
& bitmapLayout
,
557 const geometry::IntegerPoint2D
& pos
) throw (lang::IndexOutOfBoundsException
,
558 rendering::VolatileContentDestroyedException
,
559 uno::RuntimeException
, std::exception
)
561 SolarMutexGuard aGuard
;
563 bitmapLayout
= getMemoryLayout();
565 // Invalid/empty bitmap: no data available
567 throw lang::IndexOutOfBoundsException();
568 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
569 throw lang::IndexOutOfBoundsException();
571 if( pos
.X
< 0 || pos
.Y
< 0 ||
572 pos
.X
> m_pBmpAcc
->Width() || pos
.Y
> m_pBmpAcc
->Height() )
574 throw lang::IndexOutOfBoundsException();
577 uno::Sequence
< sal_Int8
> aRet((m_nBitsPerOutputPixel
+ 7)/8);
578 sal_Int8
* pOutBuf
= aRet
.getArray();
580 // copy stuff to output sequence
581 bitmapLayout
.ScanLines
= 1;
582 bitmapLayout
.ScanLineBytes
=
583 bitmapLayout
.ScanLineStride
= aRet
.getLength();
585 const long nScanlineLeftOffset( pos
.X
*m_nBitsPerInputPixel
/8 );
586 if( !m_aBmpEx
.IsTransparent() )
588 assert(m_pBmpAcc
&& "Invalid bmp read access");
590 // can return bitmap data as-is
591 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
592 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, aRet
.getLength() );
596 assert(m_pBmpAcc
&& "Invalid bmp read access");
597 assert(m_pAlphaAcc
&& "Invalid alpha read access");
599 // interleave alpha with bitmap data - note, bitcount is
600 // always integer multiple of 8
601 assert((m_nBitsPerOutputPixel
& 0x07) == 0 &&
602 "Transparent bitmap bitcount not integer multiple of 8" );
604 if( m_nBitsPerInputPixel
< 8 )
606 // input less than a byte - copy via GetPixel()
607 *pOutBuf
++ = m_pBmpAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
608 *pOutBuf
= m_pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
612 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
613 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
615 // input integer multiple of byte - copy directly
616 memcpy(pOutBuf
, pScan
+nScanlineLeftOffset
, nNonAlphaBytes
);
617 pOutBuf
+= nNonAlphaBytes
;
618 *pOutBuf
++ = m_pAlphaAcc
->GetPixelIndex(pos
.Y
,pos
.X
);
625 uno::Reference
< rendering::XBitmapPalette
> SAL_CALL
VclCanvasBitmap::getPalette() throw (uno::RuntimeException
)
627 SolarMutexGuard aGuard
;
629 uno::Reference
< XBitmapPalette
> aRet
;
636 rendering::IntegerBitmapLayout SAL_CALL
VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException
, std::exception
)
638 SolarMutexGuard aGuard
;
640 rendering::IntegerBitmapLayout
aLayout( m_aLayout
);
642 // only set references to self on separate copy of
643 // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
644 // a circular reference!
646 aLayout
.Palette
.set( this );
648 aLayout
.ColorSpace
.set( this );
653 sal_Int32 SAL_CALL
VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException
, std::exception
)
655 SolarMutexGuard aGuard
;
660 return m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ;
663 sal_Bool SAL_CALL
VclCanvasBitmap::getIndex( uno::Sequence
< double >& o_entry
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
665 SolarMutexGuard aGuard
;
667 const sal_uInt16
nCount( m_pBmpAcc
?
668 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
669 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
670 if( nIndex
< 0 || nIndex
>= nCount
)
671 throw lang::IndexOutOfBoundsException("Palette index out of range",
672 static_cast<rendering::XBitmapPalette
*>(this));
674 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(sal::static_int_cast
<sal_uInt16
>(nIndex
));
676 double* pColor
=o_entry
.getArray();
677 pColor
[0] = aCol
.GetRed();
678 pColor
[1] = aCol
.GetGreen();
679 pColor
[2] = aCol
.GetBlue();
681 return true; // no palette transparency here.
684 sal_Bool SAL_CALL
VclCanvasBitmap::setIndex( const uno::Sequence
< double >&, sal_Bool
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, lang::IllegalArgumentException
, uno::RuntimeException
, std::exception
)
686 SolarMutexGuard aGuard
;
688 const sal_uInt16
nCount( m_pBmpAcc
?
689 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
691 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
692 if( nIndex
< 0 || nIndex
>= nCount
)
693 throw lang::IndexOutOfBoundsException("Palette index out of range",
694 static_cast<rendering::XBitmapPalette
*>(this));
696 return false; // read-only implementation
701 struct PaletteColorSpaceHolder
: public rtl::StaticWithInit
<uno::Reference
<rendering::XColorSpace
>,
702 PaletteColorSpaceHolder
>
704 uno::Reference
<rendering::XColorSpace
> operator()()
706 return vcl::unotools::createStandardColorSpace();
711 uno::Reference
< rendering::XColorSpace
> SAL_CALL
VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException
, std::exception
)
713 // this is the method from XBitmapPalette. Return palette color
715 return PaletteColorSpaceHolder::get();
718 sal_Int8 SAL_CALL
VclCanvasBitmap::getType( ) throw (uno::RuntimeException
, std::exception
)
720 return rendering::ColorSpaceType::RGB
;
723 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException
, std::exception
)
725 SolarMutexGuard aGuard
;
726 return m_aComponentTags
;
729 sal_Int8 SAL_CALL
VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException
, std::exception
)
731 return rendering::RenderingIntent::PERCEPTUAL
;
734 uno::Sequence
< ::beans::PropertyValue
> SAL_CALL
VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException
, std::exception
)
736 return uno::Sequence
< ::beans::PropertyValue
>();
739 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertColorSpace( const uno::Sequence
< double >& deviceColor
,
740 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (uno::RuntimeException
, std::exception
)
742 // TODO(P3): if we know anything about target
743 // colorspace, this can be greatly sped up
744 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
745 convertToARGB(deviceColor
));
746 return targetColorSpace
->convertFromARGB(aIntermediate
);
749 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertToRGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
751 SolarMutexGuard aGuard
;
753 const std::size_t nLen( deviceColor
.getLength() );
754 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
755 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
756 "number of channels no multiple of pixel element count",
757 static_cast<rendering::XBitmapPalette
*>(this), 01);
759 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/nComponentsPerPixel
);
760 rendering::RGBColor
* pOut( aRes
.getArray() );
764 OSL_ENSURE(m_nIndexIndex
!= -1,
765 "Invalid color channel indices");
766 ENSURE_OR_THROW(m_pBmpAcc
,
767 "Unable to get BitmapAccess");
769 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
771 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
772 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
774 // TODO(F3): Convert result to sRGB color space
775 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
776 toDoubleColor(aCol
.GetGreen()),
777 toDoubleColor(aCol
.GetBlue()));
782 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
783 "Invalid color channel indices");
785 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
787 // TODO(F3): Convert result to sRGB color space
788 *pOut
++ = rendering::RGBColor(
789 deviceColor
[i
+m_nRedIndex
],
790 deviceColor
[i
+m_nGreenIndex
],
791 deviceColor
[i
+m_nBlueIndex
]);
798 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
800 SolarMutexGuard aGuard
;
802 const std::size_t nLen( deviceColor
.getLength() );
803 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
804 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
805 "number of channels no multiple of pixel element count",
806 static_cast<rendering::XBitmapPalette
*>(this), 01);
808 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
809 rendering::ARGBColor
* pOut( aRes
.getArray() );
813 OSL_ENSURE(m_nIndexIndex
!= -1,
814 "Invalid color channel indices");
815 ENSURE_OR_THROW(m_pBmpAcc
,
816 "Unable to get BitmapAccess");
818 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
820 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
821 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
823 // TODO(F3): Convert result to sRGB color space
824 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
825 *pOut
++ = rendering::ARGBColor(nAlpha
,
826 toDoubleColor(aCol
.GetRed()),
827 toDoubleColor(aCol
.GetGreen()),
828 toDoubleColor(aCol
.GetBlue()));
833 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
834 "Invalid color channel indices");
836 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
838 // TODO(F3): Convert result to sRGB color space
839 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
840 *pOut
++ = rendering::ARGBColor(
842 deviceColor
[i
+m_nRedIndex
],
843 deviceColor
[i
+m_nGreenIndex
],
844 deviceColor
[i
+m_nBlueIndex
]);
851 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToPARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
853 SolarMutexGuard aGuard
;
855 const std::size_t nLen( deviceColor
.getLength() );
856 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
857 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
858 "number of channels no multiple of pixel element count",
859 static_cast<rendering::XBitmapPalette
*>(this), 01);
861 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
862 rendering::ARGBColor
* pOut( aRes
.getArray() );
866 OSL_ENSURE(m_nIndexIndex
!= -1,
867 "Invalid color channel indices");
868 ENSURE_OR_THROW(m_pBmpAcc
,
869 "Unable to get BitmapAccess");
871 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
873 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
874 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
876 // TODO(F3): Convert result to sRGB color space
877 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
878 *pOut
++ = rendering::ARGBColor(nAlpha
,
879 nAlpha
*toDoubleColor(aCol
.GetRed()),
880 nAlpha
*toDoubleColor(aCol
.GetGreen()),
881 nAlpha
*toDoubleColor(aCol
.GetBlue()));
886 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
887 "Invalid color channel indices");
889 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
891 // TODO(F3): Convert result to sRGB color space
892 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
893 *pOut
++ = rendering::ARGBColor(
895 nAlpha
*deviceColor
[i
+m_nRedIndex
],
896 nAlpha
*deviceColor
[i
+m_nGreenIndex
],
897 nAlpha
*deviceColor
[i
+m_nBlueIndex
]);
904 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
906 SolarMutexGuard aGuard
;
908 const std::size_t nLen( rgbColor
.getLength() );
909 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
911 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
912 double* pColors
=aRes
.getArray();
916 for( std::size_t i
=0; i
<nLen
; ++i
)
918 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
919 BitmapColor(toByteColor(rgbColor
[i
].Red
),
920 toByteColor(rgbColor
[i
].Green
),
921 toByteColor(rgbColor
[i
].Blue
)));
922 if( m_nAlphaIndex
!= -1 )
923 pColors
[m_nAlphaIndex
] = 1.0;
925 pColors
+= nComponentsPerPixel
;
930 for( std::size_t i
=0; i
<nLen
; ++i
)
932 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
933 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
934 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
935 if( m_nAlphaIndex
!= -1 )
936 pColors
[m_nAlphaIndex
] = 1.0;
938 pColors
+= nComponentsPerPixel
;
944 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
946 SolarMutexGuard aGuard
;
948 const std::size_t nLen( rgbColor
.getLength() );
949 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
951 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
952 double* pColors
=aRes
.getArray();
956 for( std::size_t i
=0; i
<nLen
; ++i
)
958 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
959 BitmapColor(toByteColor(rgbColor
[i
].Red
),
960 toByteColor(rgbColor
[i
].Green
),
961 toByteColor(rgbColor
[i
].Blue
)));
962 if( m_nAlphaIndex
!= -1 )
963 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
965 pColors
+= nComponentsPerPixel
;
970 for( std::size_t i
=0; i
<nLen
; ++i
)
972 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
973 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
974 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
975 if( m_nAlphaIndex
!= -1 )
976 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
978 pColors
+= nComponentsPerPixel
;
984 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
986 SolarMutexGuard aGuard
;
988 const std::size_t nLen( rgbColor
.getLength() );
989 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
991 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
992 double* pColors
=aRes
.getArray();
996 for( std::size_t i
=0; i
<nLen
; ++i
)
998 const double nAlpha( rgbColor
[i
].Alpha
);
999 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
1000 BitmapColor(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1001 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1002 toByteColor(rgbColor
[i
].Blue
/ nAlpha
)));
1003 if( m_nAlphaIndex
!= -1 )
1004 pColors
[m_nAlphaIndex
] = nAlpha
;
1006 pColors
+= nComponentsPerPixel
;
1011 for( std::size_t i
=0; i
<nLen
; ++i
)
1013 const double nAlpha( rgbColor
[i
].Alpha
);
1014 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
/ nAlpha
;
1015 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
/ nAlpha
;
1016 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
/ nAlpha
;
1017 if( m_nAlphaIndex
!= -1 )
1018 pColors
[m_nAlphaIndex
] = nAlpha
;
1020 pColors
+= nComponentsPerPixel
;
1026 sal_Int32 SAL_CALL
VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException
, std::exception
)
1028 SolarMutexGuard aGuard
;
1029 return m_nBitsPerOutputPixel
;
1032 uno::Sequence
< ::sal_Int32
> SAL_CALL
VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException
, std::exception
)
1034 SolarMutexGuard aGuard
;
1035 return m_aComponentBitCounts
;
1038 sal_Int8 SAL_CALL
VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException
, std::exception
)
1040 SolarMutexGuard aGuard
;
1041 return m_nEndianness
;
1044 uno::Sequence
<double> SAL_CALL
VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1045 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1047 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1049 SolarMutexGuard aGuard
;
1051 const std::size_t nLen( deviceColor
.getLength() );
1052 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
1053 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
1054 "number of channels no multiple of pixel element count",
1055 static_cast<rendering::XBitmapPalette
*>(this), 01);
1057 uno::Sequence
<double> aRes(nLen
);
1058 double* pOut( aRes
.getArray() );
1062 OSL_ENSURE(m_nIndexIndex
!= -1,
1063 "Invalid color channel indices");
1064 ENSURE_OR_THROW(m_pBmpAcc
,
1065 "Unable to get BitmapAccess");
1067 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1069 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
1070 sal::static_int_cast
<sal_uInt16
>(deviceColor
[i
+m_nIndexIndex
]));
1072 // TODO(F3): Convert result to sRGB color space
1073 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1074 *pOut
++ = toDoubleColor(aCol
.GetRed());
1075 *pOut
++ = toDoubleColor(aCol
.GetGreen());
1076 *pOut
++ = toDoubleColor(aCol
.GetBlue());
1082 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
1083 "Invalid color channel indices");
1085 for( std::size_t i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1087 // TODO(F3): Convert result to sRGB color space
1088 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1089 *pOut
++ = deviceColor
[i
+m_nRedIndex
];
1090 *pOut
++ = deviceColor
[i
+m_nGreenIndex
];
1091 *pOut
++ = deviceColor
[i
+m_nBlueIndex
];
1100 // TODO(P3): if we know anything about target
1101 // colorspace, this can be greatly sped up
1102 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1103 convertIntegerToARGB(deviceColor
));
1104 return targetColorSpace
->convertFromARGB(aIntermediate
);
1108 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1109 const uno::Reference
< ::rendering::XIntegerBitmapColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1111 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1113 // it's us, so simply pass-through the data
1118 // TODO(P3): if we know anything about target
1119 // colorspace, this can be greatly sped up
1120 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1121 convertIntegerToARGB(deviceColor
));
1122 return targetColorSpace
->convertIntegerFromARGB(aIntermediate
);
1126 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1128 SolarMutexGuard aGuard
;
1130 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1131 const std::size_t nLen( deviceColor
.getLength() );
1132 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1134 uno::Sequence
< rendering::RGBColor
> aRes(nNumColors
);
1135 rendering::RGBColor
* pOut( aRes
.getArray() );
1137 ENSURE_OR_THROW(m_pBmpAcc
,
1138 "Unable to get BitmapAccess");
1140 if( m_aBmpEx
.IsTransparent() )
1142 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1143 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1145 // if palette, index is guaranteed to be 8 bit
1146 const BitmapColor aCol
=
1148 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1149 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1151 // TODO(F3): Convert result to sRGB color space
1152 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1153 toDoubleColor(aCol
.GetGreen()),
1154 toDoubleColor(aCol
.GetBlue()));
1156 pIn
+= nBytesPerPixel
;
1161 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1163 const BitmapColor aCol
=
1165 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex()) :
1166 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1168 // TODO(F3): Convert result to sRGB color space
1169 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1170 toDoubleColor(aCol
.GetGreen()),
1171 toDoubleColor(aCol
.GetBlue()));
1178 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1180 SolarMutexGuard aGuard
;
1182 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1183 const std::size_t nLen( deviceColor
.getLength() );
1184 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1186 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1187 rendering::ARGBColor
* pOut( aRes
.getArray() );
1189 ENSURE_OR_THROW(m_pBmpAcc
,
1190 "Unable to get BitmapAccess");
1192 if( m_aBmpEx
.IsTransparent() )
1194 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1195 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1196 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1197 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1199 // if palette, index is guaranteed to be 8 bit
1200 const BitmapColor aCol
=
1202 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1203 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1205 // TODO(F3): Convert result to sRGB color space
1206 *pOut
++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]),
1207 toDoubleColor(aCol
.GetRed()),
1208 toDoubleColor(aCol
.GetGreen()),
1209 toDoubleColor(aCol
.GetBlue()));
1210 pIn
+= nBytesPerPixel
;
1215 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1217 const BitmapColor aCol
=
1219 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1220 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1222 // TODO(F3): Convert result to sRGB color space
1223 *pOut
++ = rendering::ARGBColor(1.0,
1224 toDoubleColor(aCol
.GetRed()),
1225 toDoubleColor(aCol
.GetGreen()),
1226 toDoubleColor(aCol
.GetBlue()));
1233 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1235 SolarMutexGuard aGuard
;
1237 const sal_uInt8
* pIn( reinterpret_cast<const sal_uInt8
*>(deviceColor
.getConstArray()) );
1238 const std::size_t nLen( deviceColor
.getLength() );
1239 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1241 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1242 rendering::ARGBColor
* pOut( aRes
.getArray() );
1244 ENSURE_OR_THROW(m_pBmpAcc
,
1245 "Unable to get BitmapAccess");
1247 if( m_aBmpEx
.IsTransparent() )
1249 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1250 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1251 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1252 for( std::size_t i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1254 // if palette, index is guaranteed to be 8 bit
1255 const BitmapColor aCol
=
1257 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1258 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1260 // TODO(F3): Convert result to sRGB color space
1261 const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]) );
1262 *pOut
++ = rendering::ARGBColor(nAlpha
,
1263 nAlpha
*toDoubleColor(aCol
.GetRed()),
1264 nAlpha
*toDoubleColor(aCol
.GetGreen()),
1265 nAlpha
*toDoubleColor(aCol
.GetBlue()));
1266 pIn
+= nBytesPerPixel
;
1271 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1273 const BitmapColor aCol
=
1275 m_pBmpAcc
->GetPaletteColor( m_pBmpAcc
->GetPixelFromData( pIn
, i
).GetIndex() ) :
1276 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1278 // TODO(F3): Convert result to sRGB color space
1279 *pOut
++ = rendering::ARGBColor(1.0,
1280 toDoubleColor(aCol
.GetRed()),
1281 toDoubleColor(aCol
.GetGreen()),
1282 toDoubleColor(aCol
.GetBlue()));
1289 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1291 SolarMutexGuard aGuard
;
1293 const std::size_t nLen( rgbColor
.getLength() );
1294 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1296 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1297 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1299 if( m_aBmpEx
.IsTransparent() )
1301 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1302 for( std::size_t i
=0; i
<nLen
; ++i
)
1304 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1305 toByteColor(rgbColor
[i
].Green
),
1306 toByteColor(rgbColor
[i
].Blue
));
1307 const BitmapColor aCol2
=
1310 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1313 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1314 pColors
+= nNonAlphaBytes
;
1315 *pColors
++ = sal_uInt8(255);
1320 for( std::size_t i
=0; i
<nLen
; ++i
)
1322 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1323 toByteColor(rgbColor
[i
].Green
),
1324 toByteColor(rgbColor
[i
].Blue
));
1325 const BitmapColor aCol2
=
1328 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1331 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1338 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1340 SolarMutexGuard aGuard
;
1342 const std::size_t nLen( rgbColor
.getLength() );
1343 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1345 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1346 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1348 if( m_aBmpEx
.IsTransparent() )
1350 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1351 for( std::size_t i
=0; i
<nLen
; ++i
)
1353 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1354 toByteColor(rgbColor
[i
].Green
),
1355 toByteColor(rgbColor
[i
].Blue
));
1356 const BitmapColor aCol2
=
1359 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1362 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1363 pColors
+= nNonAlphaBytes
;
1364 *pColors
++ = 255 - toByteColor(rgbColor
[i
].Alpha
);
1369 for( std::size_t i
=0; i
<nLen
; ++i
)
1371 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1372 toByteColor(rgbColor
[i
].Green
),
1373 toByteColor(rgbColor
[i
].Blue
));
1374 const BitmapColor aCol2
=
1377 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1380 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1387 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
, std::exception
)
1389 SolarMutexGuard aGuard
;
1391 const std::size_t nLen( rgbColor
.getLength() );
1392 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1394 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1395 sal_uInt8
* pColors
=reinterpret_cast<sal_uInt8
*>(aRes
.getArray());
1397 if( m_aBmpEx
.IsTransparent() )
1399 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1400 for( std::size_t i
=0; i
<nLen
; ++i
)
1402 const double nAlpha( rgbColor
[i
].Alpha
);
1403 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1404 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1405 toByteColor(rgbColor
[i
].Blue
/ nAlpha
));
1406 const BitmapColor aCol2
=
1409 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1412 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1413 pColors
+= nNonAlphaBytes
;
1414 *pColors
++ = 255 - toByteColor(nAlpha
);
1419 for( std::size_t i
=0; i
<nLen
; ++i
)
1421 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1422 toByteColor(rgbColor
[i
].Green
),
1423 toByteColor(rgbColor
[i
].Blue
));
1424 const BitmapColor aCol2
=
1427 sal::static_int_cast
<sal_uInt8
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1430 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */