1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: canvasbitmap.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include <com/sun/star/util/Endianness.hpp>
35 #include <com/sun/star/rendering/ColorComponentTag.hpp>
36 #include <com/sun/star/rendering/ColorSpaceType.hpp>
37 #include <com/sun/star/rendering/RenderingIntent.hpp>
39 #include <rtl/instance.hxx>
40 #include <vos/mutex.hxx>
42 #include <tools/diagnose_ex.h>
43 #include <vcl/canvasbitmap.hxx>
44 #include <vcl/canvastools.hxx>
45 #include <vcl/bmpacc.hxx>
46 #include <vcl/svapp.hxx>
51 using namespace ::vcl::unotools
;
52 using namespace ::com::sun::star
;
56 // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
58 // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
59 // unrolled loop. See e.g. Hackers Delight, p. 66
60 inline sal_Int32
bitcount( sal_uInt32 val
)
62 val
= val
- ((val
>> 1) & 0x55555555);
63 val
= (val
& 0x33333333) + ((val
>> 2) & 0x33333333);
64 val
= (val
+ (val
>> 4)) & 0x0F0F0F0F;
65 val
= val
+ (val
>> 8);
66 val
= val
+ (val
>> 16);
67 return sal_Int32(val
& 0x0000003F);
71 void VclCanvasBitmap::setComponentInfo( ULONG redShift
, ULONG greenShift
, ULONG blueShift
)
73 // sort channels in increasing order of appearance in the pixel
74 // (starting with the least significant bits)
79 if( redShift
> greenShift
)
81 std::swap(redPos
,greenPos
);
82 if( redShift
> blueShift
)
84 std::swap(redPos
,bluePos
);
85 if( greenShift
> blueShift
)
86 std::swap(greenPos
,bluePos
);
91 if( greenShift
> blueShift
)
93 std::swap(greenPos
,bluePos
);
94 if( redShift
> blueShift
)
95 std::swap(redPos
,bluePos
);
99 m_aComponentTags
.realloc(3);
100 sal_Int8
* pTags
= m_aComponentTags
.getArray();
101 pTags
[redPos
] = rendering::ColorComponentTag::RGB_RED
;
102 pTags
[greenPos
] = rendering::ColorComponentTag::RGB_GREEN
;
103 pTags
[bluePos
] = rendering::ColorComponentTag::RGB_BLUE
;
105 m_aComponentBitCounts
.realloc(3);
106 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
107 pCounts
[redPos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(redShift
));
108 pCounts
[greenPos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(greenShift
));
109 pCounts
[bluePos
] = bitcount(sal::static_int_cast
<sal_uInt32
>(blueShift
));
112 VclCanvasBitmap::VclCanvasBitmap( const BitmapEx
& rBitmap
) :
114 m_aBitmap( rBitmap
.GetBitmap() ),
116 m_pBmpAcc( m_aBitmap
.AcquireReadAccess() ),
119 m_aComponentBitCounts(),
121 m_nBitsPerInputPixel(0),
122 m_nBitsPerOutputPixel(0),
132 if( m_aBmpEx
.IsTransparent() )
134 m_aAlpha
= m_aBmpEx
.IsAlpha() ? m_aBmpEx
.GetAlpha().GetBitmap() : m_aBmpEx
.GetMask();
135 m_pAlphaAcc
= m_aAlpha
.AcquireReadAccess();
138 m_aLayout
.ScanLines
= 0;
139 m_aLayout
.ScanLineBytes
= 0;
140 m_aLayout
.ScanLineStride
= 0;
141 m_aLayout
.PlaneStride
= 0;
142 m_aLayout
.ColorSpace
.clear();
143 m_aLayout
.Palette
.clear();
144 m_aLayout
.IsMsbFirst
= sal_False
;
148 m_aLayout
.ScanLines
= m_pBmpAcc
->Height();
149 m_aLayout
.ScanLineBytes
= (m_pBmpAcc
->GetBitCount()*m_pBmpAcc
->Width() + 7) / 8;
150 m_aLayout
.ScanLineStride
= m_pBmpAcc
->GetScanlineSize();
151 m_aLayout
.PlaneStride
= 0;
153 switch( m_pBmpAcc
->GetScanlineFormat() )
155 case BMP_FORMAT_1BIT_MSB_PAL
:
157 m_nBitsPerInputPixel
= 1;
158 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
159 m_aLayout
.IsMsbFirst
= sal_True
;
162 case BMP_FORMAT_1BIT_LSB_PAL
:
164 m_nBitsPerInputPixel
= 1;
165 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
166 m_aLayout
.IsMsbFirst
= sal_False
;
169 case BMP_FORMAT_4BIT_MSN_PAL
:
171 m_nBitsPerInputPixel
= 4;
172 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
173 m_aLayout
.IsMsbFirst
= sal_True
;
176 case BMP_FORMAT_4BIT_LSN_PAL
:
178 m_nBitsPerInputPixel
= 4;
179 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
180 m_aLayout
.IsMsbFirst
= sal_False
;
183 case BMP_FORMAT_8BIT_PAL
:
185 m_nBitsPerInputPixel
= 8;
186 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
187 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
190 case BMP_FORMAT_8BIT_TC_MASK
:
192 m_nBitsPerInputPixel
= 8;
193 m_nEndianness
= util::Endianness::LITTLE
; // doesn't matter
194 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
195 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
196 m_pBmpAcc
->GetColorMask().GetGreenMask(),
197 m_pBmpAcc
->GetColorMask().GetBlueMask() );
200 case BMP_FORMAT_16BIT_TC_MSB_MASK
:
202 m_nBitsPerInputPixel
= 16;
203 m_nEndianness
= util::Endianness::BIG
;
204 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
205 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
206 m_pBmpAcc
->GetColorMask().GetGreenMask(),
207 m_pBmpAcc
->GetColorMask().GetBlueMask() );
210 case BMP_FORMAT_16BIT_TC_LSB_MASK
:
212 m_nBitsPerInputPixel
= 16;
213 m_nEndianness
= util::Endianness::LITTLE
;
214 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
215 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
216 m_pBmpAcc
->GetColorMask().GetGreenMask(),
217 m_pBmpAcc
->GetColorMask().GetBlueMask() );
220 case BMP_FORMAT_24BIT_TC_BGR
:
222 m_nBitsPerInputPixel
= 24;
223 m_nEndianness
= util::Endianness::LITTLE
;
224 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
225 setComponentInfo( 0xff0000LL
,
230 case BMP_FORMAT_24BIT_TC_RGB
:
232 m_nBitsPerInputPixel
= 24;
233 m_nEndianness
= util::Endianness::LITTLE
;
234 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
235 setComponentInfo( 0x0000ffLL
,
240 case BMP_FORMAT_24BIT_TC_MASK
:
242 m_nBitsPerInputPixel
= 24;
243 m_nEndianness
= util::Endianness::LITTLE
;
244 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
245 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
246 m_pBmpAcc
->GetColorMask().GetGreenMask(),
247 m_pBmpAcc
->GetColorMask().GetBlueMask() );
250 case BMP_FORMAT_32BIT_TC_ABGR
:
253 m_nBitsPerInputPixel
= 32;
254 m_nEndianness
= util::Endianness::LITTLE
;
255 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
257 m_aComponentTags
.realloc(4);
258 sal_Int8
* pTags
= m_aComponentTags
.getArray();
259 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
260 pTags
[1] = rendering::ColorComponentTag::RGB_BLUE
;
261 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
262 pTags
[3] = rendering::ColorComponentTag::RGB_RED
;
264 m_aComponentBitCounts
.realloc(4);
265 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
278 case BMP_FORMAT_32BIT_TC_ARGB
:
281 m_nBitsPerInputPixel
= 32;
282 m_nEndianness
= util::Endianness::LITTLE
;
283 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
285 m_aComponentTags
.realloc(4);
286 sal_Int8
* pTags
= m_aComponentTags
.getArray();
287 pTags
[0] = rendering::ColorComponentTag::ALPHA
;
288 pTags
[1] = rendering::ColorComponentTag::RGB_RED
;
289 pTags
[2] = rendering::ColorComponentTag::RGB_GREEN
;
290 pTags
[3] = rendering::ColorComponentTag::RGB_BLUE
;
292 m_aComponentBitCounts
.realloc(4);
293 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
306 case BMP_FORMAT_32BIT_TC_BGRA
:
309 m_nBitsPerInputPixel
= 32;
310 m_nEndianness
= util::Endianness::LITTLE
;
311 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
313 m_aComponentTags
.realloc(4);
314 sal_Int8
* pTags
= m_aComponentTags
.getArray();
315 pTags
[0] = rendering::ColorComponentTag::RGB_BLUE
;
316 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
317 pTags
[2] = rendering::ColorComponentTag::RGB_RED
;
318 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
320 m_aComponentBitCounts
.realloc(4);
321 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
334 case BMP_FORMAT_32BIT_TC_RGBA
:
337 m_nBitsPerInputPixel
= 32;
338 m_nEndianness
= util::Endianness::LITTLE
;
339 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
341 m_aComponentTags
.realloc(4);
342 sal_Int8
* pTags
= m_aComponentTags
.getArray();
343 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
344 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
345 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
346 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
348 m_aComponentBitCounts
.realloc(4);
349 sal_Int32
* pCounts
= m_aComponentBitCounts
.getArray();
362 case BMP_FORMAT_32BIT_TC_MASK
:
364 m_nBitsPerInputPixel
= 32;
365 m_nEndianness
= util::Endianness::LITTLE
;
366 m_aLayout
.IsMsbFirst
= sal_False
; // doesn't matter
367 setComponentInfo( m_pBmpAcc
->GetColorMask().GetRedMask(),
368 m_pBmpAcc
->GetColorMask().GetGreenMask(),
369 m_pBmpAcc
->GetColorMask().GetBlueMask() );
373 DBG_ERROR( "unsupported bitmap format" );
379 m_aComponentTags
.realloc(1);
380 m_aComponentTags
[0] = rendering::ColorComponentTag::INDEX
;
382 m_aComponentBitCounts
.realloc(1);
383 m_aComponentBitCounts
[0] = m_nBitsPerInputPixel
;
388 m_nBitsPerOutputPixel
= m_nBitsPerInputPixel
;
389 if( m_aBmpEx
.IsTransparent() )
391 // TODO(P1): need to interleave alpha with bitmap data -
392 // won't fuss with less-than-8 bit for now
393 m_nBitsPerOutputPixel
= std::max(sal_Int32(8),m_nBitsPerInputPixel
);
395 // check whether alpha goes in front or behind the
396 // bitcount sequence. If pixel format is little endian,
397 // put it behind all the other channels. If it's big
398 // endian, put it in front (because later, the actual data
399 // always gets written after the pixel data)
401 // TODO(Q1): slight catch - in the case of the
402 // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
403 // channels might happen!
404 m_aComponentTags
.realloc(m_aComponentTags
.getLength()+1);
405 m_aComponentTags
[m_aComponentTags
.getLength()-1] = rendering::ColorComponentTag::ALPHA
;
407 m_aComponentBitCounts
.realloc(m_aComponentBitCounts
.getLength()+1);
408 m_aComponentBitCounts
[m_aComponentBitCounts
.getLength()-1] = m_aBmpEx
.IsAlpha() ? 8 : 1;
410 if( m_nEndianness
== util::Endianness::BIG
)
412 // put alpha in front of all the color channels
413 sal_Int8
* pTags
=m_aComponentTags
.getArray();
414 sal_Int32
* pCounts
=m_aComponentBitCounts
.getArray();
416 pTags
+m_aComponentTags
.getLength()-1,
417 pTags
+m_aComponentTags
.getLength());
419 pCounts
+m_aComponentBitCounts
.getLength()-1,
420 pCounts
+m_aComponentBitCounts
.getLength());
428 // always add a full byte to the pixel size, otherwise
429 // pixel packing hell breaks loose.
430 m_nBitsPerOutputPixel
+= 8;
432 // adapt scanline parameters
433 const Size aSize
= m_aBitmap
.GetSizePixel();
434 m_aLayout
.ScanLineBytes
=
435 m_aLayout
.ScanLineStride
= (aSize
.Width()*m_nBitsPerOutputPixel
+ 7)/8;
440 VclCanvasBitmap::~VclCanvasBitmap()
443 m_aAlpha
.ReleaseAccess(m_pAlphaAcc
);
445 m_aBitmap
.ReleaseAccess(m_pBmpAcc
);
449 geometry::IntegerSize2D SAL_CALL
VclCanvasBitmap::getSize() throw (uno::RuntimeException
)
451 vos::OGuard
aGuard( Application::GetSolarMutex() );
452 return integerSize2DFromSize( m_aBitmap
.GetSizePixel() );
455 ::sal_Bool SAL_CALL
VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException
)
457 vos::OGuard
aGuard( Application::GetSolarMutex() );
458 return m_aBmpEx
.IsTransparent();
461 uno::Reference
< rendering::XBitmap
> SAL_CALL
VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D
& newSize
,
462 sal_Bool beFast
) throw (uno::RuntimeException
)
464 vos::OGuard
aGuard( Application::GetSolarMutex() );
466 BitmapEx
aNewBmp( m_aBitmap
);
467 aNewBmp
.Scale( sizeFromRealSize2D( newSize
), beFast
? BMP_SCALE_FAST
: BMP_SCALE_INTERPOLATE
);
468 return uno::Reference
<rendering::XBitmap
>( new VclCanvasBitmap( aNewBmp
) );
471 // XIntegerReadOnlyBitmap
472 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getData( rendering::IntegerBitmapLayout
& bitmapLayout
,
473 const geometry::IntegerRectangle2D
& rect
) throw( lang::IndexOutOfBoundsException
,
474 rendering::VolatileContentDestroyedException
,
475 uno::RuntimeException
)
477 vos::OGuard
aGuard( Application::GetSolarMutex() );
479 bitmapLayout
= getMemoryLayout();
481 const ::Rectangle
aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect
) );
482 if( aRequestedArea
.IsEmpty() )
483 return uno::Sequence
< sal_Int8
>();
485 // Invalid/empty bitmap: no data available
487 throw lang::IndexOutOfBoundsException();
488 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
489 throw lang::IndexOutOfBoundsException();
491 if( aRequestedArea
.Left() < 0 || aRequestedArea
.Top() < 0 ||
492 aRequestedArea
.Right() > m_pBmpAcc
->Width() ||
493 aRequestedArea
.Bottom() > m_pBmpAcc
->Height() )
495 throw lang::IndexOutOfBoundsException();
498 uno::Sequence
< sal_Int8
> aRet
;
499 Rectangle
aRequestedBytes( aRequestedArea
);
501 // adapt to byte boundaries
502 aRequestedBytes
.Left() = aRequestedArea
.Left()*m_nBitsPerOutputPixel
/8;
503 aRequestedBytes
.Right() = (aRequestedArea
.Right()*m_nBitsPerOutputPixel
+ 7)/8;
505 // copy stuff to output sequence
506 aRet
.realloc(aRequestedBytes
.getWidth()*aRequestedBytes
.getHeight());
507 sal_Int8
* pOutBuf
= aRet
.getArray();
509 bitmapLayout
.ScanLines
= aRequestedBytes
.getHeight();
510 bitmapLayout
.ScanLineBytes
=
511 bitmapLayout
.ScanLineStride
= aRequestedBytes
.getWidth();
513 sal_Int32 nScanlineStride
=bitmapLayout
.ScanLineStride
;
514 if( !(m_pBmpAcc
->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN
) )
516 pOutBuf
+= bitmapLayout
.ScanLineStride
*(aRequestedBytes
.getHeight()-1);
517 nScanlineStride
*= -1;
520 if( !m_aBmpEx
.IsTransparent() )
522 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
524 // can return bitmap data as-is
525 for( long y
=aRequestedBytes
.Top(); y
<aRequestedBytes
.Bottom(); ++y
)
527 Scanline pScan
= m_pBmpAcc
->GetScanline(y
);
528 rtl_copyMemory(pOutBuf
, pScan
+aRequestedBytes
.Left(), aRequestedBytes
.getWidth());
529 pOutBuf
+= nScanlineStride
;
534 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
535 OSL_ENSURE(m_pAlphaAcc
,"Invalid alpha read access");
537 // interleave alpha with bitmap data - note, bitcount is
538 // always integer multiple of 8
539 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
540 "Transparent bitmap bitcount not integer multiple of 8" );
542 for( long y
=aRequestedArea
.Top(); y
<aRequestedArea
.Bottom(); ++y
)
544 sal_Int8
* pOutScan
= pOutBuf
;
546 if( m_nBitsPerInputPixel
< 8 )
548 // input less than a byte - copy via GetPixel()
549 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
551 *pOutScan
++ = m_pBmpAcc
->GetPixel(y
,x
);
552 *pOutScan
++ = m_pAlphaAcc
->GetPixel(y
,x
);
557 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
558 const long nScanlineOffsetLeft(aRequestedArea
.Left()*nNonAlphaBytes
);
559 Scanline pScan
= m_pBmpAcc
->GetScanline(y
) + nScanlineOffsetLeft
;
561 // input integer multiple of byte - copy directly
562 for( long x
=aRequestedArea
.Left(); x
<aRequestedArea
.Right(); ++x
)
564 for( long i
=0; i
<nNonAlphaBytes
; ++i
)
565 *pOutScan
++ = *pScan
++;
566 *pOutScan
++ = m_pAlphaAcc
->GetPixel(y
,x
);
570 pOutBuf
+= nScanlineStride
;
577 uno::Sequence
< sal_Int8
> SAL_CALL
VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout
& bitmapLayout
,
578 const geometry::IntegerPoint2D
& pos
) throw (lang::IndexOutOfBoundsException
,
579 rendering::VolatileContentDestroyedException
,
580 uno::RuntimeException
)
582 vos::OGuard
aGuard( Application::GetSolarMutex() );
584 bitmapLayout
= getMemoryLayout();
586 // Invalid/empty bitmap: no data available
588 throw lang::IndexOutOfBoundsException();
589 if( m_aBmpEx
.IsTransparent() && !m_pAlphaAcc
)
590 throw lang::IndexOutOfBoundsException();
592 if( pos
.X
< 0 || pos
.Y
< 0 ||
593 pos
.X
> m_pBmpAcc
->Width() || pos
.Y
> m_pBmpAcc
->Height() )
595 throw lang::IndexOutOfBoundsException();
598 uno::Sequence
< sal_Int8
> aRet((m_nBitsPerOutputPixel
+ 7)/8);
599 sal_Int8
* pOutBuf
= aRet
.getArray();
601 // copy stuff to output sequence
602 bitmapLayout
.ScanLines
= 1;
603 bitmapLayout
.ScanLineBytes
=
604 bitmapLayout
.ScanLineStride
= aRet
.getLength();
606 const long nScanlineLeftOffset( pos
.X
*m_nBitsPerInputPixel
/8 );
607 if( !m_aBmpEx
.IsTransparent() )
609 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
611 // can return bitmap data as-is
612 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
613 rtl_copyMemory(pOutBuf
, pScan
+nScanlineLeftOffset
, aRet
.getLength() );
617 OSL_ENSURE(m_pBmpAcc
,"Invalid bmp read access");
618 OSL_ENSURE(m_pAlphaAcc
,"Invalid alpha read access");
620 // interleave alpha with bitmap data - note, bitcount is
621 // always integer multiple of 8
622 OSL_ENSURE((m_nBitsPerOutputPixel
& 0x07) == 0,
623 "Transparent bitmap bitcount not integer multiple of 8" );
625 if( m_nBitsPerInputPixel
< 8 )
627 // input less than a byte - copy via GetPixel()
628 *pOutBuf
++ = m_pBmpAcc
->GetPixel(pos
.Y
,pos
.X
);
629 *pOutBuf
= m_pAlphaAcc
->GetPixel(pos
.Y
,pos
.X
);
633 const long nNonAlphaBytes( m_nBitsPerInputPixel
/8 );
634 Scanline pScan
= m_pBmpAcc
->GetScanline(pos
.Y
);
636 // input integer multiple of byte - copy directly
637 rtl_copyMemory(pOutBuf
, pScan
+nScanlineLeftOffset
, nNonAlphaBytes
);
638 pOutBuf
+= nNonAlphaBytes
;
639 *pOutBuf
++ = m_pAlphaAcc
->GetPixel(pos
.Y
,pos
.X
);
646 uno::Reference
< rendering::XBitmapPalette
> SAL_CALL
VclCanvasBitmap::getPalette() throw (uno::RuntimeException
)
648 vos::OGuard
aGuard( Application::GetSolarMutex() );
650 uno::Reference
< XBitmapPalette
> aRet
;
657 rendering::IntegerBitmapLayout SAL_CALL
VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException
)
659 vos::OGuard
aGuard( Application::GetSolarMutex() );
661 rendering::IntegerBitmapLayout
aLayout( m_aLayout
);
663 // only set references to self on separate copy of
664 // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
665 // a circular reference!
667 aLayout
.Palette
.set( this );
669 aLayout
.ColorSpace
.set( this );
674 sal_Int32 SAL_CALL
VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException
)
676 vos::OGuard
aGuard( Application::GetSolarMutex() );
681 return m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ;
684 sal_Bool SAL_CALL
VclCanvasBitmap::getIndex( uno::Sequence
< double >& o_entry
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
686 vos::OGuard
aGuard( Application::GetSolarMutex() );
688 const USHORT
nCount( m_pBmpAcc
?
689 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
690 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
691 if( nIndex
< 0 || nIndex
>= nCount
)
692 throw lang::IndexOutOfBoundsException(::rtl::OUString::createFromAscii("Palette index out of range"),
693 static_cast<rendering::XBitmapPalette
*>(this));
695 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(sal::static_int_cast
<USHORT
>(nIndex
));
697 double* pColor
=o_entry
.getArray();
698 pColor
[0] = aCol
.GetRed();
699 pColor
[1] = aCol
.GetGreen();
700 pColor
[2] = aCol
.GetBlue();
702 return sal_True
; // no palette transparency here.
705 sal_Bool SAL_CALL
VclCanvasBitmap::setIndex( const uno::Sequence
< double >&, sal_Bool
, sal_Int32 nIndex
) throw (lang::IndexOutOfBoundsException
, lang::IllegalArgumentException
, uno::RuntimeException
)
707 vos::OGuard
aGuard( Application::GetSolarMutex() );
709 const USHORT
nCount( m_pBmpAcc
?
710 (m_pBmpAcc
->HasPalette() ? m_pBmpAcc
->GetPaletteEntryCount() : 0 ) : 0 );
712 OSL_ENSURE(nIndex
>= 0 && nIndex
< nCount
,"Palette index out of range");
713 if( nIndex
< 0 || nIndex
>= nCount
)
714 throw lang::IndexOutOfBoundsException(::rtl::OUString::createFromAscii("Palette index out of range"),
715 static_cast<rendering::XBitmapPalette
*>(this));
717 return sal_False
; // read-only implementation
722 struct PaletteColorSpaceHolder
: public rtl::StaticWithInit
<uno::Reference
<rendering::XColorSpace
>,
723 PaletteColorSpaceHolder
>
725 uno::Reference
<rendering::XColorSpace
> operator()()
727 return vcl::unotools::createStandardColorSpace();
732 uno::Reference
< rendering::XColorSpace
> SAL_CALL
VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException
)
734 // this is the method from XBitmapPalette. Return palette color
736 return PaletteColorSpaceHolder::get();
739 sal_Int8 SAL_CALL
VclCanvasBitmap::getType( ) throw (uno::RuntimeException
)
741 return rendering::ColorSpaceType::RGB
;
744 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException
)
746 vos::OGuard
aGuard( Application::GetSolarMutex() );
747 return m_aComponentTags
;
750 sal_Int8 SAL_CALL
VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException
)
752 return rendering::RenderingIntent::PERCEPTUAL
;
755 uno::Sequence
< ::beans::PropertyValue
> SAL_CALL
VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException
)
757 return uno::Sequence
< ::beans::PropertyValue
>();
760 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertColorSpace( const uno::Sequence
< double >& deviceColor
,
761 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (uno::RuntimeException
)
763 // TODO(P3): if we know anything about target
764 // colorspace, this can be greatly sped up
765 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
766 convertToARGB(deviceColor
));
767 return targetColorSpace
->convertFromARGB(aIntermediate
);
770 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertToRGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
772 vos::OGuard
aGuard( Application::GetSolarMutex() );
774 const sal_Size
nLen( deviceColor
.getLength() );
775 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
776 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
777 "number of channels no multiple of pixel element count",
778 static_cast<rendering::XBitmapPalette
*>(this), 01);
780 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/nComponentsPerPixel
);
781 rendering::RGBColor
* pOut( aRes
.getArray() );
785 OSL_ENSURE(m_nIndexIndex
!= -1,
786 "Invalid color channel indices");
787 ENSURE_OR_THROW(m_pBmpAcc
,
788 "Unable to get BitmapAccess");
790 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
792 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
793 sal::static_int_cast
<USHORT
>(deviceColor
[i
+m_nIndexIndex
]));
795 // TODO(F3): Convert result to sRGB color space
796 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
797 toDoubleColor(aCol
.GetGreen()),
798 toDoubleColor(aCol
.GetBlue()));
803 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
804 "Invalid color channel indices");
806 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
808 // TODO(F3): Convert result to sRGB color space
809 *pOut
++ = rendering::RGBColor(
810 deviceColor
[i
+m_nRedIndex
],
811 deviceColor
[i
+m_nGreenIndex
],
812 deviceColor
[i
+m_nBlueIndex
]);
819 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
821 vos::OGuard
aGuard( Application::GetSolarMutex() );
823 const sal_Size
nLen( deviceColor
.getLength() );
824 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
825 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
826 "number of channels no multiple of pixel element count",
827 static_cast<rendering::XBitmapPalette
*>(this), 01);
829 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
830 rendering::ARGBColor
* pOut( aRes
.getArray() );
834 OSL_ENSURE(m_nIndexIndex
!= -1,
835 "Invalid color channel indices");
836 ENSURE_OR_THROW(m_pBmpAcc
,
837 "Unable to get BitmapAccess");
839 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
841 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
842 sal::static_int_cast
<USHORT
>(deviceColor
[i
+m_nIndexIndex
]));
844 // TODO(F3): Convert result to sRGB color space
845 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
846 *pOut
++ = rendering::ARGBColor(nAlpha
,
847 toDoubleColor(aCol
.GetRed()),
848 toDoubleColor(aCol
.GetGreen()),
849 toDoubleColor(aCol
.GetBlue()));
854 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
855 "Invalid color channel indices");
857 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
859 // TODO(F3): Convert result to sRGB color space
860 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
861 *pOut
++ = rendering::ARGBColor(
863 deviceColor
[i
+m_nRedIndex
],
864 deviceColor
[i
+m_nGreenIndex
],
865 deviceColor
[i
+m_nBlueIndex
]);
872 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertToPARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
874 vos::OGuard
aGuard( Application::GetSolarMutex() );
876 const sal_Size
nLen( deviceColor
.getLength() );
877 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
878 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
879 "number of channels no multiple of pixel element count",
880 static_cast<rendering::XBitmapPalette
*>(this), 01);
882 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/nComponentsPerPixel
);
883 rendering::ARGBColor
* pOut( aRes
.getArray() );
887 OSL_ENSURE(m_nIndexIndex
!= -1,
888 "Invalid color channel indices");
889 ENSURE_OR_THROW(m_pBmpAcc
,
890 "Unable to get BitmapAccess");
892 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
894 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
895 sal::static_int_cast
<USHORT
>(deviceColor
[i
+m_nIndexIndex
]));
897 // TODO(F3): Convert result to sRGB color space
898 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
899 *pOut
++ = rendering::ARGBColor(nAlpha
,
900 nAlpha
*toDoubleColor(aCol
.GetRed()),
901 nAlpha
*toDoubleColor(aCol
.GetGreen()),
902 nAlpha
*toDoubleColor(aCol
.GetBlue()));
907 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
908 "Invalid color channel indices");
910 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
912 // TODO(F3): Convert result to sRGB color space
913 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
914 *pOut
++ = rendering::ARGBColor(
916 nAlpha
*deviceColor
[i
+m_nRedIndex
],
917 nAlpha
*deviceColor
[i
+m_nGreenIndex
],
918 nAlpha
*deviceColor
[i
+m_nBlueIndex
]);
925 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
927 vos::OGuard
aGuard( Application::GetSolarMutex() );
929 const sal_Size
nLen( rgbColor
.getLength() );
930 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
932 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
933 double* pColors
=aRes
.getArray();
937 for( sal_Size i
=0; i
<nLen
; ++i
)
939 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
940 BitmapColor(toByteColor(rgbColor
[i
].Red
),
941 toByteColor(rgbColor
[i
].Green
),
942 toByteColor(rgbColor
[i
].Blue
)));
943 if( m_nAlphaIndex
!= -1 )
944 pColors
[m_nAlphaIndex
] = 1.0;
946 pColors
+= nComponentsPerPixel
;
951 for( sal_Size i
=0; i
<nLen
; ++i
)
953 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
954 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
955 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
956 if( m_nAlphaIndex
!= -1 )
957 pColors
[m_nAlphaIndex
] = 1.0;
959 pColors
+= nComponentsPerPixel
;
965 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
967 vos::OGuard
aGuard( Application::GetSolarMutex() );
969 const sal_Size
nLen( rgbColor
.getLength() );
970 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
972 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
973 double* pColors
=aRes
.getArray();
977 for( sal_Size i
=0; i
<nLen
; ++i
)
979 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
980 BitmapColor(toByteColor(rgbColor
[i
].Red
),
981 toByteColor(rgbColor
[i
].Green
),
982 toByteColor(rgbColor
[i
].Blue
)));
983 if( m_nAlphaIndex
!= -1 )
984 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
986 pColors
+= nComponentsPerPixel
;
991 for( sal_Size i
=0; i
<nLen
; ++i
)
993 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
;
994 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
;
995 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
;
996 if( m_nAlphaIndex
!= -1 )
997 pColors
[m_nAlphaIndex
] = rgbColor
[i
].Alpha
;
999 pColors
+= nComponentsPerPixel
;
1005 uno::Sequence
< double > SAL_CALL
VclCanvasBitmap::convertFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1007 vos::OGuard
aGuard( Application::GetSolarMutex() );
1009 const sal_Size
nLen( rgbColor
.getLength() );
1010 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
1012 uno::Sequence
< double > aRes(nLen
*nComponentsPerPixel
);
1013 double* pColors
=aRes
.getArray();
1017 for( sal_Size i
=0; i
<nLen
; ++i
)
1019 const double nAlpha( rgbColor
[i
].Alpha
);
1020 pColors
[m_nIndexIndex
] = m_pBmpAcc
->GetBestPaletteIndex(
1021 BitmapColor(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1022 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1023 toByteColor(rgbColor
[i
].Blue
/ nAlpha
)));
1024 if( m_nAlphaIndex
!= -1 )
1025 pColors
[m_nAlphaIndex
] = nAlpha
;
1027 pColors
+= nComponentsPerPixel
;
1032 for( sal_Size i
=0; i
<nLen
; ++i
)
1034 const double nAlpha( rgbColor
[i
].Alpha
);
1035 pColors
[m_nRedIndex
] = rgbColor
[i
].Red
/ nAlpha
;
1036 pColors
[m_nGreenIndex
] = rgbColor
[i
].Green
/ nAlpha
;
1037 pColors
[m_nBlueIndex
] = rgbColor
[i
].Blue
/ nAlpha
;
1038 if( m_nAlphaIndex
!= -1 )
1039 pColors
[m_nAlphaIndex
] = nAlpha
;
1041 pColors
+= nComponentsPerPixel
;
1047 sal_Int32 SAL_CALL
VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException
)
1049 vos::OGuard
aGuard( Application::GetSolarMutex() );
1050 return m_nBitsPerOutputPixel
;
1053 uno::Sequence
< ::sal_Int32
> SAL_CALL
VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException
)
1055 vos::OGuard
aGuard( Application::GetSolarMutex() );
1056 return m_aComponentBitCounts
;
1059 sal_Int8 SAL_CALL
VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException
)
1061 vos::OGuard
aGuard( Application::GetSolarMutex() );
1062 return m_nEndianness
;
1065 uno::Sequence
<double> SAL_CALL
VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1066 const uno::Reference
< ::rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1068 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1070 vos::OGuard
aGuard( Application::GetSolarMutex() );
1072 const sal_Size
nLen( deviceColor
.getLength() );
1073 const sal_Int32
nComponentsPerPixel(m_aComponentTags
.getLength());
1074 ENSURE_ARG_OR_THROW2(nLen
%nComponentsPerPixel
==0,
1075 "number of channels no multiple of pixel element count",
1076 static_cast<rendering::XBitmapPalette
*>(this), 01);
1078 uno::Sequence
<double> aRes(nLen
);
1079 double* pOut( aRes
.getArray() );
1083 OSL_ENSURE(m_nIndexIndex
!= -1,
1084 "Invalid color channel indices");
1085 ENSURE_OR_THROW(m_pBmpAcc
,
1086 "Unable to get BitmapAccess");
1088 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1090 const BitmapColor aCol
= m_pBmpAcc
->GetPaletteColor(
1091 sal::static_int_cast
<USHORT
>(deviceColor
[i
+m_nIndexIndex
]));
1093 // TODO(F3): Convert result to sRGB color space
1094 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1095 *pOut
++ = toDoubleColor(aCol
.GetRed());
1096 *pOut
++ = toDoubleColor(aCol
.GetGreen());
1097 *pOut
++ = toDoubleColor(aCol
.GetBlue());
1103 OSL_ENSURE(m_nRedIndex
!= -1 && m_nGreenIndex
!= -1 && m_nBlueIndex
!= -1,
1104 "Invalid color channel indices");
1106 for( sal_Size i
=0; i
<nLen
; i
+=nComponentsPerPixel
)
1108 // TODO(F3): Convert result to sRGB color space
1109 const double nAlpha( m_nAlphaIndex
!= -1 ? 1.0 - deviceColor
[i
+m_nAlphaIndex
] : 1.0 );
1110 *pOut
++ = deviceColor
[i
+m_nRedIndex
];
1111 *pOut
++ = deviceColor
[i
+m_nGreenIndex
];
1112 *pOut
++ = deviceColor
[i
+m_nBlueIndex
];
1121 // TODO(P3): if we know anything about target
1122 // colorspace, this can be greatly sped up
1123 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1124 convertIntegerToARGB(deviceColor
));
1125 return targetColorSpace
->convertFromARGB(aIntermediate
);
1129 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
1130 const uno::Reference
< ::rendering::XIntegerBitmapColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1132 if( dynamic_cast<VclCanvasBitmap
*>(targetColorSpace
.get()) )
1134 // it's us, so simply pass-through the data
1139 // TODO(P3): if we know anything about target
1140 // colorspace, this can be greatly sped up
1141 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
1142 convertIntegerToARGB(deviceColor
));
1143 return targetColorSpace
->convertIntegerFromARGB(aIntermediate
);
1147 uno::Sequence
<rendering::RGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1149 vos::OGuard
aGuard( Application::GetSolarMutex() );
1151 const BYTE
* pIn( reinterpret_cast<const BYTE
*>(deviceColor
.getConstArray()) );
1152 const sal_Size
nLen( deviceColor
.getLength() );
1153 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1155 uno::Sequence
< rendering::RGBColor
> aRes(nNumColors
);
1156 rendering::RGBColor
* pOut( aRes
.getArray() );
1158 ENSURE_OR_THROW(m_pBmpAcc
,
1159 "Unable to get BitmapAccess");
1161 if( m_aBmpEx
.IsTransparent() )
1163 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1164 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1166 // if palette, index is guaranteed to be 8 bit
1167 const BitmapColor aCol
=
1169 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1170 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1172 // TODO(F3): Convert result to sRGB color space
1173 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1174 toDoubleColor(aCol
.GetGreen()),
1175 toDoubleColor(aCol
.GetBlue()));
1177 pIn
+= nBytesPerPixel
;
1182 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1184 const BitmapColor aCol
=
1186 m_pBmpAcc
->GetPaletteColor(
1187 sal::static_int_cast
<USHORT
>(
1188 m_pBmpAcc
->GetPixelFromData(
1190 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1192 // TODO(F3): Convert result to sRGB color space
1193 *pOut
++ = rendering::RGBColor(toDoubleColor(aCol
.GetRed()),
1194 toDoubleColor(aCol
.GetGreen()),
1195 toDoubleColor(aCol
.GetBlue()));
1202 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1204 vos::OGuard
aGuard( Application::GetSolarMutex() );
1206 const BYTE
* pIn( reinterpret_cast<const BYTE
*>(deviceColor
.getConstArray()) );
1207 const sal_Size
nLen( deviceColor
.getLength() );
1208 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1210 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1211 rendering::ARGBColor
* pOut( aRes
.getArray() );
1213 ENSURE_OR_THROW(m_pBmpAcc
,
1214 "Unable to get BitmapAccess");
1216 if( m_aBmpEx
.IsTransparent() )
1218 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1219 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1220 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1221 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1223 // if palette, index is guaranteed to be 8 bit
1224 const BitmapColor aCol
=
1226 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1227 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1229 // TODO(F3): Convert result to sRGB color space
1230 *pOut
++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]),
1231 toDoubleColor(aCol
.GetRed()),
1232 toDoubleColor(aCol
.GetGreen()),
1233 toDoubleColor(aCol
.GetBlue()));
1234 pIn
+= nBytesPerPixel
;
1239 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1241 const BitmapColor aCol
=
1243 m_pBmpAcc
->GetPaletteColor(
1244 sal::static_int_cast
<USHORT
>(
1245 m_pBmpAcc
->GetPixelFromData(
1247 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1249 // TODO(F3): Convert result to sRGB color space
1250 *pOut
++ = rendering::ARGBColor(1.0,
1251 toDoubleColor(aCol
.GetRed()),
1252 toDoubleColor(aCol
.GetGreen()),
1253 toDoubleColor(aCol
.GetBlue()));
1260 uno::Sequence
<rendering::ARGBColor
> SAL_CALL
VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1262 vos::OGuard
aGuard( Application::GetSolarMutex() );
1264 const BYTE
* pIn( reinterpret_cast<const BYTE
*>(deviceColor
.getConstArray()) );
1265 const sal_Size
nLen( deviceColor
.getLength() );
1266 const sal_Int32
nNumColors((nLen
*8 + m_nBitsPerOutputPixel
-1)/m_nBitsPerOutputPixel
);
1268 uno::Sequence
< rendering::ARGBColor
> aRes(nNumColors
);
1269 rendering::ARGBColor
* pOut( aRes
.getArray() );
1271 ENSURE_OR_THROW(m_pBmpAcc
,
1272 "Unable to get BitmapAccess");
1274 if( m_aBmpEx
.IsTransparent() )
1276 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1277 const sal_Int32
nBytesPerPixel((m_nBitsPerOutputPixel
+7)/8);
1278 const sal_uInt8
nAlphaFactor( m_aBmpEx
.IsAlpha() ? 1 : 255 );
1279 for( sal_Size i
=0; i
<nLen
; i
+=nBytesPerPixel
)
1281 // if palette, index is guaranteed to be 8 bit
1282 const BitmapColor aCol
=
1284 m_pBmpAcc
->GetPaletteColor(*pIn
) :
1285 m_pBmpAcc
->GetPixelFromData(pIn
,0);
1287 // TODO(F3): Convert result to sRGB color space
1288 const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor
*pIn
[nNonAlphaBytes
]) );
1289 *pOut
++ = rendering::ARGBColor(nAlpha
,
1290 nAlpha
*toDoubleColor(aCol
.GetRed()),
1291 nAlpha
*toDoubleColor(aCol
.GetGreen()),
1292 nAlpha
*toDoubleColor(aCol
.GetBlue()));
1293 pIn
+= nBytesPerPixel
;
1298 for( sal_Int32 i
=0; i
<nNumColors
; ++i
)
1300 const BitmapColor aCol
=
1302 m_pBmpAcc
->GetPaletteColor(
1303 sal::static_int_cast
<USHORT
>(
1304 m_pBmpAcc
->GetPixelFromData(
1306 m_pBmpAcc
->GetPixelFromData(pIn
, i
);
1308 // TODO(F3): Convert result to sRGB color space
1309 *pOut
++ = rendering::ARGBColor(1.0,
1310 toDoubleColor(aCol
.GetRed()),
1311 toDoubleColor(aCol
.GetGreen()),
1312 toDoubleColor(aCol
.GetBlue()));
1319 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence
<rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1321 vos::OGuard
aGuard( Application::GetSolarMutex() );
1323 const sal_Size
nLen( rgbColor
.getLength() );
1324 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1326 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1327 BYTE
* pColors
=reinterpret_cast<BYTE
*>(aRes
.getArray());
1329 if( m_aBmpEx
.IsTransparent() )
1331 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1332 for( sal_Size i
=0; i
<nLen
; ++i
)
1334 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1335 toByteColor(rgbColor
[i
].Green
),
1336 toByteColor(rgbColor
[i
].Blue
));
1337 const BitmapColor aCol2
=
1340 sal::static_int_cast
<BYTE
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1343 m_pBmpAcc
->SetPixelOnData(pColors
,0,aCol2
);
1344 pColors
+= nNonAlphaBytes
;
1345 *pColors
++ = BYTE(255);
1350 for( sal_Size i
=0; i
<nLen
; ++i
)
1352 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1353 toByteColor(rgbColor
[i
].Green
),
1354 toByteColor(rgbColor
[i
].Blue
));
1355 const BitmapColor aCol2
=
1358 sal::static_int_cast
<BYTE
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1361 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1368 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1370 vos::OGuard
aGuard( Application::GetSolarMutex() );
1372 const sal_Size
nLen( rgbColor
.getLength() );
1373 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1375 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1376 BYTE
* pColors
=reinterpret_cast<BYTE
*>(aRes
.getArray());
1378 if( m_aBmpEx
.IsTransparent() )
1380 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1381 for( sal_Size i
=0; i
<nLen
; ++i
)
1383 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1384 toByteColor(rgbColor
[i
].Green
),
1385 toByteColor(rgbColor
[i
].Blue
));
1386 const BitmapColor aCol2
=
1389 sal::static_int_cast
<BYTE
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1392 m_pBmpAcc
->SetPixelOnData(pColors
,0,aCol2
);
1393 pColors
+= nNonAlphaBytes
;
1394 *pColors
++ = 255 - toByteColor(rgbColor
[i
].Alpha
);
1399 for( sal_Size i
=0; i
<nLen
; ++i
)
1401 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1402 toByteColor(rgbColor
[i
].Green
),
1403 toByteColor(rgbColor
[i
].Blue
));
1404 const BitmapColor aCol2
=
1407 sal::static_int_cast
<BYTE
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1410 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1417 uno::Sequence
< ::sal_Int8
> SAL_CALL
VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence
<rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
,uno::RuntimeException
)
1419 vos::OGuard
aGuard( Application::GetSolarMutex() );
1421 const sal_Size
nLen( rgbColor
.getLength() );
1422 const sal_Int32
nNumBytes((nLen
*m_nBitsPerOutputPixel
+7)/8);
1424 uno::Sequence
< sal_Int8
> aRes(nNumBytes
);
1425 BYTE
* pColors
=reinterpret_cast<BYTE
*>(aRes
.getArray());
1427 if( m_aBmpEx
.IsTransparent() )
1429 const long nNonAlphaBytes( (m_nBitsPerInputPixel
+7)/8 );
1430 for( sal_Size i
=0; i
<nLen
; ++i
)
1432 const double nAlpha( rgbColor
[i
].Alpha
);
1433 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
/ nAlpha
),
1434 toByteColor(rgbColor
[i
].Green
/ nAlpha
),
1435 toByteColor(rgbColor
[i
].Blue
/ nAlpha
));
1436 const BitmapColor aCol2
=
1439 sal::static_int_cast
<BYTE
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1442 m_pBmpAcc
->SetPixelOnData(pColors
,0,aCol2
);
1443 pColors
+= nNonAlphaBytes
;
1444 *pColors
++ = 255 - toByteColor(nAlpha
);
1449 for( sal_Size i
=0; i
<nLen
; ++i
)
1451 const BitmapColor
aCol(toByteColor(rgbColor
[i
].Red
),
1452 toByteColor(rgbColor
[i
].Green
),
1453 toByteColor(rgbColor
[i
].Blue
));
1454 const BitmapColor aCol2
=
1457 sal::static_int_cast
<BYTE
>(m_pBmpAcc
->GetBestPaletteIndex( aCol
))) :
1460 m_pBmpAcc
->SetPixelOnData(pColors
,i
,aCol2
);
1467 BitmapEx
VclCanvasBitmap::getBitmapEx() const