summaryrefslogtreecommitdiff
path: root/vcl/source/helper
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2008-06-24 10:41:19 +0000
committerKurt Zenker <kz@openoffice.org>2008-06-24 10:41:19 +0000
commit7f6e151b25ca63e4eee637324bc2aeeae1b032c8 (patch)
tree1b374178e22769d0e34395e6c8eb697a4bdbb33c /vcl/source/helper
parent58dd47072a31e373ab9e8e1eb0aace889243dcca (diff)
INTEGRATION: CWS canvas05 (1.9.64); FILE MERGED
2008/04/21 07:47:33 thb 1.9.64.5: RESYNC: (1.9-1.10); FILE MERGED 2008/03/13 16:55:21 thb 1.9.64.4: Adapting VCL ColorSpace impls to API change; implementing some cheap paths for color space conversions 2007/10/02 11:03:25 thb 1.9.64.3: #i10000# WaE fix for Solaris 2007/10/02 10:32:51 thb 1.9.64.2: #i79437# Beefed up CanvasBitmap 2007/10/01 13:40:13 thb 1.9.64.1: #i78888# #i78925# #i79258# #i79437# #i79846# Merge from CWS picom
Diffstat (limited to 'vcl/source/helper')
-rw-r--r--vcl/source/helper/canvasbitmap.cxx1536
1 files changed, 1089 insertions, 447 deletions
diff --git a/vcl/source/helper/canvasbitmap.cxx b/vcl/source/helper/canvasbitmap.cxx
index e0348b334f6a..7b450f6c0fa9 100644
--- a/vcl/source/helper/canvasbitmap.cxx
+++ b/vcl/source/helper/canvasbitmap.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: canvasbitmap.cxx,v $
- * $Revision: 1.10 $
+ * $Revision: 1.11 $
*
* This file is part of OpenOffice.org.
*
@@ -30,596 +30,1238 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
-#include <com/sun/star/rendering/Endianness.hpp>
-#include <com/sun/star/rendering/IntegerBitmapFormat.hpp>
-#ifndef _VOS_MUTEX_HXX
+#include <com/sun/star/util/Endianness.hpp>
+#include <com/sun/star/rendering/ColorComponentTag.hpp>
+#include <com/sun/star/rendering/ColorSpaceType.hpp>
+#include <com/sun/star/rendering/RenderingIntent.hpp>
+
+#include <rtl/instance.hxx>
#include <vos/mutex.hxx>
-#endif
+#include <tools/diagnose_ex.h>
#include <vcl/canvasbitmap.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/svapp.hxx>
-using namespace vcl::unotools;
-using namespace com::sun::star::uno;
-using namespace ::com::sun::star::rendering;
-using namespace com::sun::star::lang;
-using namespace ::com::sun::star::geometry;
+#include <algorithm>
+
+
+using namespace ::vcl::unotools;
+using namespace ::com::sun::star;
+
+namespace
+{
+ // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
+
+ // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
+ // unrolled loop. See e.g. Hackers Delight, p. 66
+ inline sal_Int32 bitcount( sal_uInt32 val )
+ {
+ val = val - ((val >> 1) & 0x55555555);
+ val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
+ val = (val + (val >> 4)) & 0x0F0F0F0F;
+ val = val + (val >> 8);
+ val = val + (val >> 16);
+ return sal_Int32(val & 0x0000003F);
+ }
+}
+
+void VclCanvasBitmap::setComponentInfo( ULONG redShift, ULONG greenShift, ULONG blueShift )
+{
+ // sort channels in increasing order of appearance in the pixel
+ // (starting with the least significant bits)
+ sal_Int8 redPos(0);
+ sal_Int8 greenPos(1);
+ sal_Int8 bluePos(2);
+
+ if( redShift > greenShift )
+ {
+ std::swap(redPos,greenPos);
+ if( redShift > blueShift )
+ {
+ std::swap(redPos,bluePos);
+ if( greenShift > blueShift )
+ std::swap(greenPos,bluePos);
+ }
+ }
+ else
+ {
+ if( greenShift > blueShift )
+ {
+ std::swap(greenPos,bluePos);
+ if( redShift > blueShift )
+ std::swap(redPos,bluePos);
+ }
+ }
+
+ m_aComponentTags.realloc(3);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[redPos] = rendering::ColorComponentTag::RGB_RED;
+ pTags[greenPos] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[bluePos] = rendering::ColorComponentTag::RGB_BLUE;
+
+ m_aComponentBitCounts.realloc(3);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[redPos] = bitcount(sal::static_int_cast<sal_uInt32>(redShift));
+ pCounts[greenPos] = bitcount(sal::static_int_cast<sal_uInt32>(greenShift));
+ pCounts[bluePos] = bitcount(sal::static_int_cast<sal_uInt32>(blueShift));
+}
VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) :
- m_pBitmap( new BitmapEx(rBitmap) ),
+ m_aBmpEx( rBitmap ),
+ m_aBitmap( rBitmap.GetBitmap() ),
+ m_aAlpha(),
+ m_pBmpAcc( m_aBitmap.AcquireReadAccess() ),
+ m_pAlphaAcc( NULL ),
+ m_aComponentTags(),
+ m_aComponentBitCounts(),
m_aLayout(),
- m_bHavePalette( false )
+ m_nBitsPerInputPixel(0),
+ m_nBitsPerOutputPixel(0),
+ m_nRedIndex(-1),
+ m_nGreenIndex(-1),
+ m_nBlueIndex(-1),
+ m_nAlphaIndex(-1),
+ m_nIndexIndex(-1),
+ m_nEndianness(0),
+ m_bSwap(false),
+ m_bPalette(false)
{
- vos::OGuard aGuard( Application::GetSolarMutex() );
- Size aSz = m_pBitmap->GetSizePixel();
- m_aLayout.Palette.clear();
- m_bHavePalette = false;
- if( m_pBitmap->IsTransparent() )
- {
- m_aLayout.ScanLines = aSz.Height();
- m_aLayout.ScanLineBytes = aSz.Width()*4;
- m_aLayout.ScanLineStride = aSz.Width()*4;
- m_aLayout.PlaneStride = 0;
- m_aLayout.ColorSpace.clear(); // TODO(F2): Provide VCL-wide
- // default XGraphicDevice
- m_aLayout.NumComponents = 4;
- m_aLayout.ComponentMasks.realloc( 4 );
- sal_Int64* pMasks = m_aLayout.ComponentMasks.getArray();
- pMasks[0] = 0xff000000LL;
- pMasks[1] = 0x00ff0000LL;
- pMasks[2] = 0x0000ff00LL;
- pMasks[3] = 0x000000ffLL;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_32BIT;
- m_aLayout.IsMsbFirst = sal_False;
+ if( m_aBmpEx.IsTransparent() )
+ {
+ m_aAlpha = m_aBmpEx.IsAlpha() ? m_aBmpEx.GetAlpha().GetBitmap() : m_aBmpEx.GetMask();
+ m_pAlphaAcc = m_aAlpha.AcquireReadAccess();
}
- else
+
+ m_aLayout.ScanLines = 0;
+ m_aLayout.ScanLineBytes = 0;
+ m_aLayout.ScanLineStride = 0;
+ m_aLayout.PlaneStride = 0;
+ m_aLayout.ColorSpace.clear();
+ m_aLayout.Palette.clear();
+ m_aLayout.IsMsbFirst = sal_False;
+
+ if( m_pBmpAcc )
{
- Bitmap aBmp = m_pBitmap->GetBitmap();
- BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ m_aLayout.ScanLines = m_pBmpAcc->Height();
+ m_aLayout.ScanLineBytes = (m_pBmpAcc->GetBitCount()*m_pBmpAcc->Width() + 7) / 8;
+ m_aLayout.ScanLineStride = m_pBmpAcc->GetScanlineSize();
+ m_aLayout.PlaneStride = 0;
+
+ if( !(m_pBmpAcc->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN) )
+ m_aLayout.ScanLineStride *= -1;
+
+ switch( m_pBmpAcc->GetScanlineFormat() )
+ {
+ case BMP_FORMAT_1BIT_MSB_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 1;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_True;
+ break;
+
+ case BMP_FORMAT_1BIT_LSB_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 1;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False;
+ break;
+
+ case BMP_FORMAT_4BIT_MSN_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 4;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_True;
+ break;
+
+ case BMP_FORMAT_4BIT_LSN_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 4;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False;
+ break;
+
+ case BMP_FORMAT_8BIT_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 8;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ break;
+
+ case BMP_FORMAT_8BIT_TC_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 8;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_16BIT_TC_MSB_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 16;
+ m_nEndianness = util::Endianness::BIG;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_16BIT_TC_LSB_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 16;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_24BIT_TC_BGR:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 24;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( 0xff0000LL,
+ 0x00ff00LL,
+ 0x0000ffLL );
+ break;
+
+ case BMP_FORMAT_24BIT_TC_RGB:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 24;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( 0x0000ffLL,
+ 0x00ff00LL,
+ 0xff0000LL );
+ break;
- if( !pAcc )
+ case BMP_FORMAT_24BIT_TC_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 24;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_32BIT_TC_ABGR:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::ALPHA;
+ pTags[1] = rendering::ColorComponentTag::RGB_BLUE;
+ pTags[2] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[3] = rendering::ColorComponentTag::RGB_RED;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 3;
+ m_nGreenIndex = 2;
+ m_nBlueIndex = 1;
+ m_nAlphaIndex = 0;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_ARGB:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::ALPHA;
+ pTags[1] = rendering::ColorComponentTag::RGB_RED;
+ pTags[2] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[3] = rendering::ColorComponentTag::RGB_BLUE;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 1;
+ m_nGreenIndex = 2;
+ m_nBlueIndex = 3;
+ m_nAlphaIndex = 0;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_BGRA:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::RGB_BLUE;
+ pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[2] = rendering::ColorComponentTag::RGB_RED;
+ pTags[3] = rendering::ColorComponentTag::ALPHA;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 2;
+ m_nGreenIndex = 1;
+ m_nBlueIndex = 0;
+ m_nAlphaIndex = 3;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_RGBA:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::RGB_RED;
+ pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
+ pTags[3] = rendering::ColorComponentTag::ALPHA;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 0;
+ m_nGreenIndex = 1;
+ m_nBlueIndex = 2;
+ m_nAlphaIndex = 3;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ default:
+ DBG_ERROR( "unsupported bitmap format" );
+ break;
+ }
+
+ if( m_bPalette )
{
- // bitmap is dysfunctional, fill out dummy MemLayout
- m_aLayout.ScanLines = 0;
- m_aLayout.ScanLineBytes = 0;
- m_aLayout.ScanLineStride = 0;
- m_aLayout.PlaneStride = 0;
- m_aLayout.ColorSpace.clear(); // TODO(F2): Provide VCL-wide
- // default XGraphicDevice
- m_aLayout.NumComponents = 0;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_32BIT;
- m_aLayout.IsMsbFirst = sal_False;
+ m_aComponentTags.realloc(1);
+ m_aComponentTags[0] = rendering::ColorComponentTag::INDEX;
+
+ m_aComponentBitCounts.realloc(1);
+ m_aComponentBitCounts[0] = m_nBitsPerInputPixel;
+
+ m_nIndexIndex = 0;
}
- else
+
+ m_nBitsPerOutputPixel = m_nBitsPerInputPixel;
+ if( m_aBmpEx.IsTransparent() )
{
- m_aLayout.ScanLines = pAcc->Height();
- m_aLayout.ScanLineBytes =
- m_aLayout.ScanLineStride = pAcc->GetScanlineSize();
- m_aLayout.PlaneStride = 0;
- m_aLayout.ColorSpace.clear(); // TODO(F2): Provide VCL-wide
- // default XGraphicDevice
- switch( pAcc->GetScanlineFormat() )
+ // TODO(P1): need to interleave alpha with bitmap data -
+ // won't fuss with less-than-8 bit for now
+ m_nBitsPerOutputPixel = std::max(sal_Int32(8),m_nBitsPerInputPixel);
+
+ // check whether alpha goes in front or behind the
+ // bitcount sequence. If pixel format is little endian,
+ // put it behind all the other channels. If it's big
+ // endian, put it in front (because later, the actual data
+ // always gets written after the pixel data)
+
+ // TODO(Q1): slight catch - in the case of the
+ // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
+ // channels might happen!
+ m_aComponentTags.realloc(m_aComponentTags.getLength()+1);
+ m_aComponentTags[m_aComponentTags.getLength()-1] = rendering::ColorComponentTag::ALPHA;
+
+ m_aComponentBitCounts.realloc(m_aComponentBitCounts.getLength()+1);
+ m_aComponentBitCounts[m_aComponentBitCounts.getLength()-1] = m_aBmpEx.IsAlpha() ? 8 : 1;
+
+ if( m_nEndianness == util::Endianness::BIG )
{
- case BMP_FORMAT_1BIT_MSB_PAL:
- m_aLayout.NumComponents = 1;
- m_aLayout.ComponentMasks.realloc( 1 );
- m_aLayout.ComponentMasks.getArray()[0] = 0x1LL;
- m_bHavePalette = true;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_1BIT;
- m_aLayout.IsMsbFirst = sal_True;
- break;
- case BMP_FORMAT_1BIT_LSB_PAL:
- m_aLayout.NumComponents = 1;
- m_aLayout.ComponentMasks.realloc( 1 );
- m_aLayout.ComponentMasks.getArray()[0] = 1LL;
- m_bHavePalette = true;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_1BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_4BIT_MSN_PAL:
- m_aLayout.NumComponents = 1;
- m_aLayout.ComponentMasks.realloc( 1 );
- m_aLayout.ComponentMasks.getArray()[0] = 0x0fLL;
- m_bHavePalette = true;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_4BIT;
- m_aLayout.IsMsbFirst = sal_True;
- break;
- case BMP_FORMAT_4BIT_LSN_PAL:
- m_aLayout.NumComponents = 1;
- m_aLayout.ComponentMasks.realloc( 1 );
- m_aLayout.ComponentMasks.getArray()[0] = 0x0fLL;
- m_bHavePalette = true;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_4BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_8BIT_PAL:
- m_aLayout.NumComponents = 1;
- m_aLayout.ComponentMasks.realloc( 1 );
- m_aLayout.ComponentMasks.getArray()[0] = 0xffLL;
- m_bHavePalette = true;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_8BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
-
- case BMP_FORMAT_8BIT_TC_MASK:
- m_aLayout.NumComponents = 3;
- m_aLayout.ComponentMasks.realloc( 3 );
- m_aLayout.ComponentMasks.getArray()[0] = pAcc->GetColorMask().GetRedMask();
- m_aLayout.ComponentMasks.getArray()[1] = pAcc->GetColorMask().GetGreenMask();
- m_aLayout.ComponentMasks.getArray()[2] = pAcc->GetColorMask().GetBlueMask();
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_8BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_16BIT_TC_MSB_MASK:
- m_aLayout.NumComponents = 3;
- m_aLayout.ComponentMasks.realloc( 3 );
- m_aLayout.ComponentMasks.getArray()[0] = pAcc->GetColorMask().GetRedMask();
- m_aLayout.ComponentMasks.getArray()[1] = pAcc->GetColorMask().GetGreenMask();
- m_aLayout.ComponentMasks.getArray()[2] = pAcc->GetColorMask().GetBlueMask();
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_16BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_16BIT_TC_LSB_MASK:
- m_aLayout.NumComponents = 3;
- m_aLayout.ComponentMasks.realloc( 3 );
- m_aLayout.ComponentMasks.getArray()[0] = pAcc->GetColorMask().GetRedMask();
- m_aLayout.ComponentMasks.getArray()[1] = pAcc->GetColorMask().GetGreenMask();
- m_aLayout.ComponentMasks.getArray()[2] = pAcc->GetColorMask().GetBlueMask();
- m_aLayout.Endianness = Endianness::LITTLE;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_16BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_24BIT_TC_BGR:
- m_aLayout.NumComponents = 3;
- m_aLayout.ComponentMasks.realloc( 3 );
- m_aLayout.ComponentMasks.getArray()[0] = 0x0000ffLL;
- m_aLayout.ComponentMasks.getArray()[1] = 0x00ff00LL;
- m_aLayout.ComponentMasks.getArray()[2] = 0xff0000LL;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_24BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_24BIT_TC_RGB:
- m_aLayout.NumComponents = 3;
- m_aLayout.ComponentMasks.realloc( 3 );
- m_aLayout.ComponentMasks.getArray()[0] = 0xff0000LL;
- m_aLayout.ComponentMasks.getArray()[1] = 0x00ff00LL;
- m_aLayout.ComponentMasks.getArray()[2] = 0x0000ffLL;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_24BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_24BIT_TC_MASK:
- m_aLayout.NumComponents = 3;
- m_aLayout.ComponentMasks.realloc( 3 );
- m_aLayout.ComponentMasks.getArray()[0] = pAcc->GetColorMask().GetRedMask();
- m_aLayout.ComponentMasks.getArray()[1] = pAcc->GetColorMask().GetGreenMask();
- m_aLayout.ComponentMasks.getArray()[2] = pAcc->GetColorMask().GetBlueMask();
- m_aLayout.Endianness = Endianness::LITTLE;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_24BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_32BIT_TC_ABGR:
- m_aLayout.NumComponents = 4;
- m_aLayout.ComponentMasks.realloc( 4 );
- m_aLayout.ComponentMasks.getArray()[0] = 0x000000ffLL;
- m_aLayout.ComponentMasks.getArray()[1] = 0x0000ff00LL;
- m_aLayout.ComponentMasks.getArray()[2] = 0x00ff0000LL;
- m_aLayout.ComponentMasks.getArray()[3] = 0xff000000LL;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_32BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_32BIT_TC_ARGB:
- m_aLayout.NumComponents = 4;
- m_aLayout.ComponentMasks.realloc( 4 );
- m_aLayout.ComponentMasks.getArray()[0] = 0x00ff0000LL;
- m_aLayout.ComponentMasks.getArray()[1] = 0x0000ff00LL;
- m_aLayout.ComponentMasks.getArray()[2] = 0x000000ffLL;
- m_aLayout.ComponentMasks.getArray()[3] = 0xff000000LL;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_32BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_32BIT_TC_BGRA:
- m_aLayout.NumComponents = 4;
- m_aLayout.ComponentMasks.realloc( 4 );
- m_aLayout.ComponentMasks.getArray()[0] = 0x0000ff00LL;
- m_aLayout.ComponentMasks.getArray()[1] = 0x00ff0000LL;
- m_aLayout.ComponentMasks.getArray()[2] = 0xff000000LL;
- m_aLayout.ComponentMasks.getArray()[3] = 0x000000ffLL;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_32BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_32BIT_TC_RGBA:
- m_aLayout.NumComponents = 4;
- m_aLayout.ComponentMasks.realloc( 4 );
- m_aLayout.ComponentMasks.getArray()[0] = 0xff000000LL;
- m_aLayout.ComponentMasks.getArray()[1] = 0x00ff0000LL;
- m_aLayout.ComponentMasks.getArray()[2] = 0x0000ff00LL;
- m_aLayout.ComponentMasks.getArray()[3] = 0x000000ffLL;
- m_aLayout.Endianness = Endianness::BIG;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_32BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- case BMP_FORMAT_32BIT_TC_MASK:
- m_aLayout.NumComponents = 3;
- m_aLayout.ComponentMasks.realloc( 3 );
- m_aLayout.ComponentMasks.getArray()[0] = pAcc->GetColorMask().GetRedMask();
- m_aLayout.ComponentMasks.getArray()[1] = pAcc->GetColorMask().GetGreenMask();
- m_aLayout.ComponentMasks.getArray()[2] = pAcc->GetColorMask().GetBlueMask();
- m_aLayout.Endianness = Endianness::LITTLE;
- m_aLayout.Format = IntegerBitmapFormat::CHUNKY_32BIT;
- m_aLayout.IsMsbFirst = sal_False;
- break;
- default:
- DBG_ERROR( "unsupported bitmap format" );
- break;
+ // put alpha in front of all the color channels
+ sal_Int8* pTags =m_aComponentTags.getArray();
+ sal_Int32* pCounts=m_aComponentBitCounts.getArray();
+ std::rotate(pTags,
+ pTags+m_aComponentTags.getLength()-1,
+ pTags+m_aComponentTags.getLength());
+ std::rotate(pCounts,
+ pCounts+m_aComponentBitCounts.getLength()-1,
+ pCounts+m_aComponentBitCounts.getLength());
+ ++m_nRedIndex;
+ ++m_nGreenIndex;
+ ++m_nBlueIndex;
+ ++m_nIndexIndex;
+ m_nAlphaIndex=0;
}
- }
- aBmp.ReleaseAccess( pAcc );
+ // always add a full byte to the pixel size, otherwise
+ // pixel packing hell breaks loose.
+ m_nBitsPerOutputPixel += 8;
+
+ // adapt scanline parameters
+ const Size aSize = m_aBitmap.GetSizePixel();
+ m_aLayout.ScanLineBytes =
+ m_aLayout.ScanLineStride = (aSize.Width()*m_nBitsPerOutputPixel + 7)/8;
+ if( !(m_pBmpAcc->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN) )
+ m_aLayout.ScanLineStride *= -1;
+ }
}
}
VclCanvasBitmap::~VclCanvasBitmap()
{
- vos::OGuard aGuard( Application::GetSolarMutex() );
- delete m_pBitmap;
+ if( m_pAlphaAcc )
+ m_aAlpha.ReleaseAccess(m_pAlphaAcc);
+ if( m_pBmpAcc )
+ m_aBitmap.ReleaseAccess(m_pBmpAcc);
}
// XBitmap
-IntegerSize2D SAL_CALL VclCanvasBitmap::getSize() throw (RuntimeException)
+geometry::IntegerSize2D SAL_CALL VclCanvasBitmap::getSize() throw (uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
-
- return integerSize2DFromSize( m_pBitmap->GetSizePixel() );
+ return integerSize2DFromSize( m_aBitmap.GetSizePixel() );
}
-::sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() throw (RuntimeException)
+::sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
-
- return m_pBitmap->IsTransparent();
-}
-
-Reference< XBitmapCanvas > SAL_CALL VclCanvasBitmap::queryBitmapCanvas() throw (RuntimeException)
-{
- return Reference< XBitmapCanvas >();
+ return m_aBmpEx.IsTransparent();
}
-Reference< XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( const RealSize2D& newSize, sal_Bool beFast ) throw (RuntimeException)
+uno::Reference< rendering::XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D& newSize,
+ sal_Bool beFast ) throw (uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
- BitmapEx aNewBmp( *m_pBitmap );
+ BitmapEx aNewBmp( m_aBitmap );
aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BMP_SCALE_FAST : BMP_SCALE_INTERPOLATE );
- return Reference<XBitmap>( new VclCanvasBitmap( aNewBmp ) );
+ return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) );
}
-// XIntegerBitmap
-Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( IntegerBitmapLayout& bitmapLayout,
- const IntegerRectangle2D& /*rect*/ ) throw (IndexOutOfBoundsException,
- VolatileContentDestroyedException,
- RuntimeException)
+// XIntegerReadOnlyBitmap
+uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerBitmapLayout& bitmapLayout,
+ const geometry::IntegerRectangle2D& rect ) throw( lang::IndexOutOfBoundsException,
+ rendering::VolatileContentDestroyedException,
+ uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
bitmapLayout = getMemoryLayout();
- Bitmap aBmp = m_pBitmap->GetBitmap();
- BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ const ::Rectangle aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect) );
+ if( aRequestedArea.IsEmpty() )
+ return uno::Sequence< sal_Int8 >();
// Invalid/empty bitmap: no data available
- if( !pAcc )
- return Sequence< sal_Int8 >();
-
- Sequence< sal_Int8 > aRet;
- if( m_pBitmap->IsTransparent() )
- {
- int w = pAcc->Width();
- int h = pAcc->Height();
- aRet.realloc( 4 * w * h );
- sal_Int8* pContent = aRet.getArray();
- for( int y = 0; y < h; y++ )
- for( int x = 0; x < w; x++ )
+ if( !m_pBmpAcc )
+ throw lang::IndexOutOfBoundsException();
+ if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
+ throw lang::IndexOutOfBoundsException();
+
+ if( aRequestedArea.Left() < 0 || aRequestedArea.Top() < 0 ||
+ aRequestedArea.Right() > m_pBmpAcc->Width() ||
+ aRequestedArea.Bottom() > m_pBmpAcc->Height() )
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ uno::Sequence< sal_Int8 > aRet;
+ Rectangle aRequestedBytes( aRequestedArea );
+
+ // adapt to byte boundaries
+ aRequestedBytes.Left() = aRequestedArea.Left()*m_nBitsPerOutputPixel/8;
+ aRequestedBytes.Right() = (aRequestedArea.Right()*m_nBitsPerOutputPixel + 7)/8;
+
+ // copy stuff to output sequence
+ aRet.realloc(aRequestedBytes.getWidth()*aRequestedBytes.getHeight());
+ sal_Int8* pOutBuf = aRet.getArray();
+
+ bitmapLayout.ScanLines = aRequestedBytes.getHeight();
+ bitmapLayout.ScanLineBytes =
+ bitmapLayout.ScanLineStride= aRequestedBytes.getWidth();
+
+ if( !(m_pBmpAcc->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN) )
+ bitmapLayout.ScanLineStride *= -1;
+
+ if( !m_aBmpEx.IsTransparent() )
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+
+ // can return bitmap data as-is
+ for( long y=aRequestedBytes.Top(); y<aRequestedBytes.Bottom(); ++y )
{
- BitmapColor aCol = pAcc->GetColor( x, y );
- *pContent++ = aCol.GetRed();
- *pContent++ = aCol.GetGreen();
- *pContent++ = aCol.GetBlue();
- pContent++;
+ Scanline pScan = m_pBmpAcc->GetScanline(y);
+ rtl_copyMemory(pOutBuf, pScan+aRequestedBytes.Left(), aRequestedBytes.getWidth());
+ pOutBuf += bitmapLayout.ScanLineStride;
}
- pContent = aRet.getArray()+3;
- if( m_pBitmap->IsAlpha() )
+ }
+ else
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+ OSL_ENSURE(m_pAlphaAcc,"Invalid alpha read access");
+
+ // interleave alpha with bitmap data - note, bitcount is
+ // always integer multiple of 8
+ OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0,
+ "Transparent bitmap bitcount not integer multiple of 8" );
+
+ for( long y=aRequestedArea.Top(); y<aRequestedArea.Bottom(); ++y )
{
- AlphaMask aAlpha = m_pBitmap->GetAlpha();
- BitmapReadAccess* pAlphaAcc = aAlpha.AcquireReadAccess();
+ sal_Int8* pOutScan = pOutBuf;
- // Invalid/empty alpha mask: keep alpha bytes to 0
- if( pAlphaAcc )
+ if( m_nBitsPerInputPixel < 8 )
{
- for( int y = 0; y < h; y++ )
+ // input less than a byte - copy via GetPixel()
+ for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
{
- Scanline pLine = pAlphaAcc->GetScanline( y );
- for( int x = 0; x < w; x++ )
- {
- *pContent = *pLine++;
- pContent += 4;
- }
+ *pOutScan++ = m_pBmpAcc->GetPixel(y,x);
+ *pOutScan++ = m_pAlphaAcc->GetPixel(y,x);
}
}
- aAlpha.ReleaseAccess( pAlphaAcc );
- }
- else if( m_pBitmap->GetTransparentType() == TRANSPARENT_BITMAP )
- {
- Bitmap aMask = m_pBitmap->GetMask();
- BitmapReadAccess* pMaskAcc = aMask.AcquireReadAccess();
-
- // Invalid/empty mask: keep alpha bytes to 0
- if( pMaskAcc )
+ else
{
- BitmapColor aZeroCol = pMaskAcc->GetPaletteColor( 0 );
- sal_uInt8 nIndexZeroAlpha = 0xff;
- if( !aZeroCol.GetRed() && ! aZeroCol.GetGreen() && ! aZeroCol.GetBlue() )
- nIndexZeroAlpha = 0;
- sal_uInt8 nIndexOneAlpha = ~nIndexZeroAlpha;
- for( int y = 0; y < h; y++ )
- for( int x = 0; x < w; x++ )
- {
- *pContent = pMaskAcc->GetPixel(x,y).GetIndex() ? nIndexOneAlpha : nIndexZeroAlpha;
- pContent += 4;
- }
+ const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
+ const long nScanlineOffsetLeft(aRequestedArea.Left()*nNonAlphaBytes);
+ Scanline pScan = m_pBmpAcc->GetScanline(y) + nScanlineOffsetLeft;
+
+ // input integer multiple of byte - copy directly
+ for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
+ {
+ for( long i=0; i<nNonAlphaBytes; ++i )
+ *pOutScan++ = *pScan++;
+ *pOutScan++ = m_pAlphaAcc->GetPixel(y,x);
+ }
}
- aMask.ReleaseAccess( pMaskAcc );
+
+ pOutBuf += bitmapLayout.ScanLineStride;
}
- else if( m_pBitmap->GetTransparentType() == TRANSPARENT_COLOR )
+ }
+
+ return aRet;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout& bitmapLayout,
+ const geometry::IntegerPoint2D& pos ) throw (lang::IndexOutOfBoundsException,
+ rendering::VolatileContentDestroyedException,
+ uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ bitmapLayout = getMemoryLayout();
+
+ // Invalid/empty bitmap: no data available
+ if( !m_pBmpAcc )
+ throw lang::IndexOutOfBoundsException();
+ if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
+ throw lang::IndexOutOfBoundsException();
+
+ if( pos.X < 0 || pos.Y < 0 ||
+ pos.X > m_pBmpAcc->Width() || pos.Y > m_pBmpAcc->Height() )
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ uno::Sequence< sal_Int8 > aRet((m_nBitsPerOutputPixel + 7)/8);
+ sal_Int8* pOutBuf = aRet.getArray();
+
+ // copy stuff to output sequence
+ bitmapLayout.ScanLines = 1;
+ bitmapLayout.ScanLineBytes =
+ bitmapLayout.ScanLineStride= aRet.getLength();
+
+ const long nScanlineLeftOffset( pos.X*m_nBitsPerInputPixel/8 );
+ if( !m_aBmpEx.IsTransparent() )
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+
+ // can return bitmap data as-is
+ Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
+ rtl_copyMemory(pOutBuf, pScan+nScanlineLeftOffset, aRet.getLength() );
+ }
+ else
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+ OSL_ENSURE(m_pAlphaAcc,"Invalid alpha read access");
+
+ // interleave alpha with bitmap data - note, bitcount is
+ // always integer multiple of 8
+ OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0,
+ "Transparent bitmap bitcount not integer multiple of 8" );
+
+ if( m_nBitsPerInputPixel < 8 )
{
- sal_Int8 nR = m_pBitmap->GetTransparentColor().GetRed();
- sal_Int8 nG = m_pBitmap->GetTransparentColor().GetGreen();
- sal_Int8 nB = m_pBitmap->GetTransparentColor().GetBlue();
- for( int y = 0; y < h; y++ )
- for( int x = 0; x < w; x++ )
- {
- *pContent = (pContent[-3] == nR && pContent[-2] == nG && pContent[-1] == nB) ? 0xff : 0;
- pContent += 4;
- }
+ // input less than a byte - copy via GetPixel()
+ *pOutBuf++ = m_pBmpAcc->GetPixel(pos.Y,pos.X);
+ *pOutBuf = m_pAlphaAcc->GetPixel(pos.Y,pos.X);
}
else
{
- aBmp.ReleaseAccess( pAcc );
- DBG_ERROR( "unsupported transparency type" );
- throw RuntimeException();
+ const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
+ Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
+
+ // input integer multiple of byte - copy directly
+ rtl_copyMemory(pOutBuf, pScan+nScanlineLeftOffset, nNonAlphaBytes );
+ pOutBuf += nNonAlphaBytes;
+ *pOutBuf++ = m_pAlphaAcc->GetPixel(pos.Y,pos.X);
}
}
- else
+
+ return aRet;
+}
+
+uno::Reference< rendering::XBitmapPalette > SAL_CALL VclCanvasBitmap::getPalette() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference< XBitmapPalette > aRet;
+ if( m_bPalette )
+ aRet.set(this);
+
+ return aRet;
+}
+
+rendering::IntegerBitmapLayout SAL_CALL VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ rendering::IntegerBitmapLayout aLayout( m_aLayout );
+
+ // only set references to self on separate copy of
+ // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
+ // a circular reference!
+ if( m_bPalette )
+ aLayout.Palette.set( this );
+
+ aLayout.ColorSpace.set( this );
+
+ return aLayout;
+}
+
+sal_Int32 SAL_CALL VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( !m_pBmpAcc )
+ return 0;
+
+ return m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ;
+}
+
+sal_Bool SAL_CALL VclCanvasBitmap::getIndex( uno::Sequence< double >& o_entry, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const USHORT nCount( m_pBmpAcc ?
+ (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
+ OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
+ if( nIndex < 0 || nIndex >= nCount )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString::createFromAscii("Palette index out of range"),
+ static_cast<rendering::XBitmapPalette*>(this));
+
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(sal::static_int_cast<USHORT>(nIndex));
+ o_entry.realloc(3);
+ double* pColor=o_entry.getArray();
+ pColor[0] = aCol.GetRed();
+ pColor[1] = aCol.GetGreen();
+ pColor[2] = aCol.GetBlue();
+
+ return sal_True; // no palette transparency here.
+}
+
+sal_Bool SAL_CALL VclCanvasBitmap::setIndex( const uno::Sequence< double >&, sal_Bool, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const USHORT nCount( m_pBmpAcc ?
+ (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
+
+ OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
+ if( nIndex < 0 || nIndex >= nCount )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString::createFromAscii("Palette index out of range"),
+ static_cast<rendering::XBitmapPalette*>(this));
+
+ return sal_False; // read-only implementation
+}
+
+namespace
+{
+ struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
+ PaletteColorSpaceHolder>
{
- int nH = pAcc->Height();
- int nScS = pAcc->GetScanlineSize();
- aRet.realloc( nScS * nH );
- sal_Int8* pContent = aRet.getArray();
- for( int i = 0; i < nH; i++ )
+ uno::Reference<rendering::XColorSpace> operator()()
{
- Scanline pLine = pAcc->GetScanline( i );
- rtl_copyMemory( pContent, pLine, nScS );
- pContent += nScS;
+ return vcl::unotools::createStandardColorSpace();
}
- }
- aBmp.ReleaseAccess( pAcc );
- return aRet;
+ };
}
-void SAL_CALL VclCanvasBitmap::setData( const Sequence< sal_Int8 >& /*data*/, const IntegerBitmapLayout& /*bitmapLayout*/, const IntegerRectangle2D& /*rect*/ ) throw (IllegalArgumentException, IndexOutOfBoundsException, RuntimeException)
+uno::Reference< rendering::XColorSpace > SAL_CALL VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException)
{
- DBG_ERROR( "this XBitmap implementation is readonly" );
- throw IllegalArgumentException();
+ // this is the method from XBitmapPalette. Return palette color
+ // space here
+ return PaletteColorSpaceHolder::get();
}
-void SAL_CALL VclCanvasBitmap::setPixel( const Sequence< sal_Int8 >& /*color*/, const IntegerBitmapLayout& /*bitmapLayout*/, const IntegerPoint2D& /*pos*/ ) throw (IllegalArgumentException, IndexOutOfBoundsException, RuntimeException)
+sal_Int8 SAL_CALL VclCanvasBitmap::getType( ) throw (uno::RuntimeException)
{
- DBG_ERROR( "this XBitmap implementation is readonly" );
- throw IllegalArgumentException();
+ return rendering::ColorSpaceType::RGB;
}
-Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( IntegerBitmapLayout& bitmapLayout,
- const IntegerPoint2D& pos ) throw (IndexOutOfBoundsException,
- VolatileContentDestroyedException,
- RuntimeException)
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_aComponentTags;
+}
- bitmapLayout = getMemoryLayout();
+sal_Int8 SAL_CALL VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException)
+{
+ return rendering::RenderingIntent::PERCEPTUAL;
+}
- Point aPos = pointFromIntegerPoint2D( pos );
- if( aPos.X() < 0 || aPos.Y() < 0 )
- throw IndexOutOfBoundsException();
+uno::Sequence< ::beans::PropertyValue > SAL_CALL VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException)
+{
+ return uno::Sequence< ::beans::PropertyValue >();
+}
- Bitmap aBmp = m_pBitmap->GetBitmap();
- BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertColorSpace( const uno::Sequence< double >& deviceColor,
+ const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (uno::RuntimeException)
+{
+ // TODO(P3): if we know anything about target
+ // colorspace, this can be greatly sped up
+ uno::Sequence<rendering::ARGBColor> aIntermediate(
+ convertToARGB(deviceColor));
+ return targetColorSpace->convertFromARGB(aIntermediate);
+}
- // Invalid/empty bitmap: no data available
- if( !pAcc )
- return Sequence< sal_Int8 >();
+uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+ ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
+ "number of channels no multiple of pixel element count",
+ static_cast<rendering::XBitmapPalette*>(this), 01);
+
+ uno::Sequence< rendering::RGBColor > aRes(nLen/nComponentsPerPixel);
+ rendering::RGBColor* pOut( aRes.getArray() );
- if( aPos.X() >= pAcc->Width() || aPos.Y() >= pAcc->Height() )
+ if( m_bPalette )
{
- aBmp.ReleaseAccess( pAcc );
- throw IndexOutOfBoundsException();
+ OSL_ENSURE(m_nIndexIndex != -1,
+ "Invalid color channel indices");
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(deviceColor[i+m_nIndexIndex]));
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
}
+ else
+ {
+ OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
+ "Invalid color channel indices");
- Sequence< sal_Int8 > aRet;
- if( m_pBitmap->IsTransparent() )
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(
+ deviceColor[i+m_nRedIndex],
+ deviceColor[i+m_nGreenIndex],
+ deviceColor[i+m_nBlueIndex]);
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+ ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
+ "number of channels no multiple of pixel element count",
+ static_cast<rendering::XBitmapPalette*>(this), 01);
+
+ uno::Sequence< rendering::ARGBColor > aRes(nLen/nComponentsPerPixel);
+ rendering::ARGBColor* pOut( aRes.getArray() );
+
+ if( m_bPalette )
{
- BitmapColor aCol = pAcc->GetColor( aPos.X(), aPos.Y() );
- sal_uInt8 nAlpha = 0;
- if( m_pBitmap->IsAlpha() )
+ OSL_ENSURE(m_nIndexIndex != -1,
+ "Invalid color channel indices");
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
{
- AlphaMask aMask = m_pBitmap->GetAlpha();
- BitmapReadAccess* pAlphaAcc = aMask.AcquireReadAccess();
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(deviceColor[i+m_nIndexIndex]));
- // Invalid/empty alpha mask: keep alpha value to 0
- if( pAlphaAcc )
- {
- BitmapColor aAlphaCol = pAlphaAcc->GetPixel( aPos.X(), aPos.Y() );
- nAlpha = aAlphaCol.GetIndex();
- }
- aMask.ReleaseAccess( pAlphaAcc );
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = rendering::ARGBColor(nAlpha,
+ toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
}
- else if( m_pBitmap->GetTransparentType() == TRANSPARENT_COLOR )
+ }
+ else
+ {
+ OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
+ "Invalid color channel indices");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
{
- Color aTranspCol = m_pBitmap->GetTransparentColor();
- if( aCol.GetRed() == aTranspCol.GetRed() &&
- aCol.GetGreen() == aTranspCol.GetGreen() &&
- aCol.GetBlue() == aTranspCol.GetBlue() )
- nAlpha = 0xff;
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = rendering::ARGBColor(
+ nAlpha,
+ deviceColor[i+m_nRedIndex],
+ deviceColor[i+m_nGreenIndex],
+ deviceColor[i+m_nBlueIndex]);
}
- else if( m_pBitmap->GetTransparentType() == TRANSPARENT_BITMAP )
+ }
+
+ return aRes;
+}
+
+uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+
+ uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
+ double* pColors=aRes.getArray();
+
+ if( m_bPalette )
+ {
+ for( sal_Size i=0; i<nLen; ++i )
{
- Bitmap aMask = m_pBitmap->GetMask();
- BitmapReadAccess* pMaskAcc = aMask.AcquireReadAccess();
+ pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
+ BitmapColor(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue)));
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = 1.0;
- // Invalid/empty mask: keep alpha value to 0
- if( pMaskAcc )
- {
- BitmapColor aMaskColor = pMaskAcc->GetColor( aPos.X(), aPos.Y() );
- if( aMaskColor.GetRed() || aMaskColor.GetGreen() || aMaskColor.GetBlue() )
- nAlpha = 0xff;
- }
- aMask.ReleaseAccess( pMaskAcc );
+ pColors += nComponentsPerPixel;
}
- else
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
{
- aBmp.ReleaseAccess( pAcc );
- DBG_ERROR( "unsupported transparency type" );
- throw RuntimeException();
+ pColors[m_nRedIndex] = rgbColor[i].Red;
+ pColors[m_nGreenIndex] = rgbColor[i].Green;
+ pColors[m_nBlueIndex] = rgbColor[i].Blue;
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = 1.0;
+
+ pColors += nComponentsPerPixel;
}
- aRet.realloc( 4 );
- sal_Int8* pContent = aRet.getArray();
- *pContent++ = aCol.GetRed();
- *pContent++ = aCol.GetGreen();
- *pContent++ = aCol.GetBlue();
- *pContent = nAlpha;
}
- else
+ return aRes;
+}
+
+uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+
+ uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
+ double* pColors=aRes.getArray();
+
+ if( m_bPalette )
{
- if( pAcc->GetBitCount() < 8 )
+ for( sal_Size i=0; i<nLen; ++i )
{
- aRet.realloc( 1 );
- *aRet.getArray() = pAcc->GetPixel( aPos.X(), aPos.Y() ).GetIndex();
+ pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
+ BitmapColor(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue)));
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
+
+ pColors += nComponentsPerPixel;
}
- else
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
{
- int nByteSize = pAcc->GetBitCount()/4;
- aRet.realloc( nByteSize );
- Scanline pLine = pAcc->GetScanline( aPos.Y() );
- rtl_copyMemory( aRet.getArray(), pLine + aPos.X() * nByteSize, nByteSize );
+ pColors[m_nRedIndex] = rgbColor[i].Red;
+ pColors[m_nGreenIndex] = rgbColor[i].Green;
+ pColors[m_nBlueIndex] = rgbColor[i].Blue;
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
+
+ pColors += nComponentsPerPixel;
}
}
- aBmp.ReleaseAccess( pAcc );
+ return aRes;
+}
- return aRet;
+sal_Int32 SAL_CALL VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_nBitsPerOutputPixel;
+}
+
+uno::Sequence< ::sal_Int32 > SAL_CALL VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_aComponentBitCounts;
}
-Reference< XBitmapPalette > SAL_CALL VclCanvasBitmap::getPalette() throw (RuntimeException)
+sal_Int8 SAL_CALL VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException)
{
- return m_bHavePalette ?
- Reference< XBitmapPalette >( this ) :
- Reference< XBitmapPalette >();
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_nEndianness;
}
-IntegerBitmapLayout SAL_CALL VclCanvasBitmap::getMemoryLayout() throw (RuntimeException)
+uno::Sequence<double> SAL_CALL VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
+ const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
- IntegerBitmapLayout aLayout( m_aLayout );
+ if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
+ {
+ vos::OGuard aGuard( Application::GetSolarMutex() );
- // only set bitmap palette on separate copy of IntegerBitmapLayout
- // - if we'd set that on m_aLayout, we'd have a circular reference!
- if( m_bHavePalette )
- aLayout.Palette.set( this );
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+ ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
+ "number of channels no multiple of pixel element count",
+ static_cast<rendering::XBitmapPalette*>(this), 01);
- return aLayout;
+ uno::Sequence<double> aRes(nLen);
+ double* pOut( aRes.getArray() );
+
+ if( m_bPalette )
+ {
+ OSL_ENSURE(m_nIndexIndex != -1,
+ "Invalid color channel indices");
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(deviceColor[i+m_nIndexIndex]));
+
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = toDoubleColor(aCol.GetRed());
+ *pOut++ = toDoubleColor(aCol.GetGreen());
+ *pOut++ = toDoubleColor(aCol.GetBlue());
+ *pOut++ = nAlpha;
+ }
+ }
+ else
+ {
+ OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
+ "Invalid color channel indices");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = deviceColor[i+m_nRedIndex];
+ *pOut++ = deviceColor[i+m_nGreenIndex];
+ *pOut++ = deviceColor[i+m_nBlueIndex];
+ *pOut++ = nAlpha;
+ }
+ }
+
+ return aRes;
+ }
+ else
+ {
+ // TODO(P3): if we know anything about target
+ // colorspace, this can be greatly sped up
+ uno::Sequence<rendering::ARGBColor> aIntermediate(
+ convertIntegerToARGB(deviceColor));
+ return targetColorSpace->convertFromARGB(aIntermediate);
+ }
}
-sal_Int32 SAL_CALL VclCanvasBitmap::getNumberOfEntries() throw (RuntimeException)
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
+ const uno::Reference< ::rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
+ {
+ // it's us, so simply pass-through the data
+ return deviceColor;
+ }
+ else
+ {
+ // TODO(P3): if we know anything about target
+ // colorspace, this can be greatly sped up
+ uno::Sequence<rendering::ARGBColor> aIntermediate(
+ convertIntegerToARGB(deviceColor));
+ return targetColorSpace->convertIntegerFromARGB(aIntermediate);
+ }
+}
+
+uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
- Bitmap aBmp = m_pBitmap->GetBitmap();
- BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
- if( !pAcc )
- return 0;
+ const BYTE* pIn( reinterpret_cast<const BYTE*>(deviceColor.getConstArray()) );
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
+
+ uno::Sequence< rendering::RGBColor > aRes(nNumColors);
+ rendering::RGBColor* pOut( aRes.getArray() );
+
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
+ for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
+ {
+ // if palette, index is guaranteed to be 8 bit
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(*pIn) :
+ m_pBmpAcc->GetPixelFromData(pIn,0);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ // skips alpha
+ pIn += nBytesPerPixel;
+ }
+ }
+ else
+ {
+ for( sal_Int32 i=0; i<nNumColors; ++i )
+ {
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(
+ m_pBmpAcc->GetPixelFromData(
+ pIn, i ))) :
+ m_pBmpAcc->GetPixelFromData(pIn, i);
- sal_Int32 nEntries = pAcc->HasPalette() ? pAcc->GetPaletteEntryCount() : 0 ;
- aBmp.ReleaseAccess( pAcc );
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
+ }
- return nEntries;
+ return aRes;
}
-Sequence< double > SAL_CALL VclCanvasBitmap::getPaletteIndex( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
- Sequence< double > aRet( 3 );
- double* pContents = aRet.getArray();
- Bitmap aBmp = m_pBitmap->GetBitmap();
- BitmapReadAccess* pAcc = aBmp.AcquireReadAccess();
+ const BYTE* pIn( reinterpret_cast<const BYTE*>(deviceColor.getConstArray()) );
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
- if( !pAcc )
- return Sequence< double >();
+ uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
+ rendering::ARGBColor* pOut( aRes.getArray() );
- if( nIndex >= 0 && nIndex < pAcc->GetPaletteEntryCount() )
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ if( m_aBmpEx.IsTransparent() )
{
- // range already checked above
- const BitmapColor& rColor = pAcc->GetPaletteColor(
- static_cast<USHORT>(nIndex) );
- *pContents++ = double(rColor.GetRed()) / 255.0;
- *pContents++ = double(rColor.GetGreen()) / 255.0;
- *pContents++ = double(rColor.GetBlue()) / 255.0;
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
+ const sal_uInt8 nAlphaFactor( m_aBmpEx.IsAlpha() ? 1 : 255 );
+ for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
+ {
+ // if palette, index is guaranteed to be 8 bit
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(*pIn) :
+ m_pBmpAcc->GetPixelFromData(pIn,0);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]),
+ toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ pIn += nBytesPerPixel;
+ }
}
else
{
- aBmp.ReleaseAccess( pAcc );
- throw IndexOutOfBoundsException();
+ for( sal_Int32 i=0; i<nNumColors; ++i )
+ {
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(
+ m_pBmpAcc->GetPixelFromData(
+ pIn, i ))) :
+ m_pBmpAcc->GetPixelFromData(pIn, i);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::ARGBColor(1.0,
+ toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
}
- aBmp.ReleaseAccess( pAcc );
- return aRet;
+ return aRes;
}
-sal_Bool SAL_CALL VclCanvasBitmap::setPaletteIndex( const Sequence< double >& /*color*/, sal_Int32 /*nIndex*/ ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
- return sal_False; // read only implementation
-}
+ vos::OGuard aGuard( Application::GetSolarMutex() );
-Reference< XColorSpace > SAL_CALL VclCanvasBitmap::getColorSpace( ) throw (RuntimeException)
-{
- return Reference< XColorSpace >(); // TODO(F2): Provide VCL-wide
- // default XGraphicDevice
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
+
+ uno::Sequence< sal_Int8 > aRes(nNumBytes);
+ BYTE* pColors=reinterpret_cast<BYTE*>(aRes.getArray());
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
+ pColors += nNonAlphaBytes;
+ *pColors++ = BYTE(255);
+ }
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
+ }
+ }
+
+ return aRes;
}
-sal_Int64 SAL_CALL VclCanvasBitmap::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw (RuntimeException)
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
vos::OGuard aGuard( Application::GetSolarMutex() );
- sal_Int64 nRet = 0;
- const Sequence< sal_Int8 >& rTest = getTunnelIdentifier( Id_BitmapEx );
- if( aIdentifier.getLength() == rTest.getLength() &&
- rtl_compareMemory( rTest.getConstArray(), aIdentifier.getConstArray(), rTest.getLength() ) == 0
- )
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
+
+ uno::Sequence< sal_Int8 > aRes(nNumBytes);
+ BYTE* pColors=reinterpret_cast<BYTE*>(aRes.getArray());
+
+ if( m_aBmpEx.IsTransparent() )
{
- nRet = (sal_Int64)sal_IntPtr(m_pBitmap);
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
+ pColors += nNonAlphaBytes;
+ *pColors++ = 255 - toByteColor(rgbColor[i].Alpha);
+ }
}
- return nRet;
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
+ }
+ }
+
+ return aRes;
+}
+
+BitmapEx VclCanvasBitmap::getBitmapEx() const
+{
+ return m_aBmpEx;
}