office-gobmx/vcl/source/helper/canvasbitmap.cxx
Thomas Arnhold ba0a57702c remove OUString wrap for string literals
For some functions and all kinds of Exceptions.

CannotConvertException
CloseVetoException
DisposedException
EmptyUndoStackException
ErrorCodeIOException
Exception
GridInvalidDataException
GridInvalidModelException
IOException
IllegalAccessException
IllegalArgumentException
IllegalTypeException
IndexOutOfBoundsException
NoMasterException
NoSuchElementException
NoSupportException
PropertyVetoException
RuntimeException
SAXException
ScannerException
StorageWrappedTargetException
UnsupportedFlavorException
VetoException
WrappedTargetException
ZipIOException
throwGenericSQLException
throwIllegallArgumentException

createInstance
createInstanceWithContext
forName
getByName
getPackageManager
getPropertyValue
getUnpackedValueOrDefault
getValueByName
hasPropertyByName
openKey
setName
setPropertyValue
supportsService

bash command:

for i in `cat list`; do git grep "$i\s*(\s*OUString(\s*\"" -- '*.[hc]xx'
	| cut -d ':' -f1 | sort -u
	| xargs sed -i
		-e "s/\(\<$i\s*(\)\s*OUString(\s*\(\"[^\")\\]*\"\)\s*)\s*/\1\2/g"
		-e "s/\($i.*\)\"+ /\1\" + /g";
done

Change-Id: Iaf8e641b0abf28c082906014f87a183517630535
Reviewed-on: https://gerrit.libreoffice.org/4624
Tested-by: LibreOffice gerrit bot <gerrit@libreoffice.org>
Reviewed-by: Thomas Arnhold <thomas@arnhold.org>
Tested-by: Thomas Arnhold <thomas@arnhold.org>
2013-06-29 21:52:54 +00:00

1449 lines
54 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#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 <osl/mutex.hxx>
#include <tools/diagnose_ex.h>
#include <canvasbitmap.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/svapp.hxx>
#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( sal_uLong redShift, sal_uLong greenShift, sal_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_aBmpEx( rBitmap ),
m_aBitmap( rBitmap.GetBitmap() ),
m_aAlpha(),
m_pBmpAcc( m_aBitmap.AcquireReadAccess() ),
m_pAlphaAcc( NULL ),
m_aComponentTags(),
m_aComponentBitCounts(),
m_aLayout(),
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_bPalette(false)
{
if( m_aBmpEx.IsTransparent() )
{
m_aAlpha = m_aBmpEx.IsAlpha() ? m_aBmpEx.GetAlpha().GetBitmap() : m_aBmpEx.GetMask();
m_pAlphaAcc = m_aAlpha.AcquireReadAccess();
}
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 )
{
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;
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;
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:
OSL_FAIL( "unsupported bitmap format" );
break;
}
if( m_bPalette )
{
m_aComponentTags.realloc(1);
m_aComponentTags[0] = rendering::ColorComponentTag::INDEX;
m_aComponentBitCounts.realloc(1);
m_aComponentBitCounts[0] = m_nBitsPerInputPixel;
m_nIndexIndex = 0;
}
m_nBitsPerOutputPixel = m_nBitsPerInputPixel;
if( m_aBmpEx.IsTransparent() )
{
// 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 )
{
// 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;
}
// 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;
}
}
}
VclCanvasBitmap::~VclCanvasBitmap()
{
if( m_pAlphaAcc )
m_aAlpha.ReleaseAccess(m_pAlphaAcc);
if( m_pBmpAcc )
m_aBitmap.ReleaseAccess(m_pBmpAcc);
}
// XBitmap
geometry::IntegerSize2D SAL_CALL VclCanvasBitmap::getSize() throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
return integerSize2DFromSize( m_aBitmap.GetSizePixel() );
}
::sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
return m_aBmpEx.IsTransparent();
}
uno::Reference< rendering::XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D& newSize,
sal_Bool beFast ) throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
BitmapEx aNewBmp( m_aBitmap );
aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BMP_SCALE_DEFAULT : BMP_SCALE_BESTQUALITY );
return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) );
}
// XIntegerReadOnlyBitmap
uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerBitmapLayout& bitmapLayout,
const geometry::IntegerRectangle2D& rect ) throw( lang::IndexOutOfBoundsException,
rendering::VolatileContentDestroyedException,
uno::RuntimeException)
{
SolarMutexGuard aGuard;
bitmapLayout = getMemoryLayout();
const ::Rectangle aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect) );
if( aRequestedArea.IsEmpty() )
return uno::Sequence< sal_Int8 >();
// Invalid/empty bitmap: no data available
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();
sal_Int32 nScanlineStride=bitmapLayout.ScanLineStride;
if( !(m_pBmpAcc->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN) )
{
pOutBuf += bitmapLayout.ScanLineStride*(aRequestedBytes.getHeight()-1);
nScanlineStride *= -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 )
{
Scanline pScan = m_pBmpAcc->GetScanline(y);
memcpy(pOutBuf, pScan+aRequestedBytes.Left(), aRequestedBytes.getWidth());
pOutBuf += nScanlineStride;
}
}
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 )
{
sal_Int8* pOutScan = pOutBuf;
if( m_nBitsPerInputPixel < 8 )
{
// input less than a byte - copy via GetPixel()
for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
{
*pOutScan++ = m_pBmpAcc->GetPixelIndex(y,x);
*pOutScan++ = m_pAlphaAcc->GetPixelIndex(y,x);
}
}
else
{
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->GetPixelIndex( y, x );
}
}
pOutBuf += nScanlineStride;
}
}
return aRet;
}
uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout& bitmapLayout,
const geometry::IntegerPoint2D& pos ) throw (lang::IndexOutOfBoundsException,
rendering::VolatileContentDestroyedException,
uno::RuntimeException)
{
SolarMutexGuard aGuard;
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);
memcpy(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 )
{
// input less than a byte - copy via GetPixel()
*pOutBuf++ = m_pBmpAcc->GetPixelIndex(pos.Y,pos.X);
*pOutBuf = m_pAlphaAcc->GetPixelIndex(pos.Y,pos.X);
}
else
{
const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
// input integer multiple of byte - copy directly
memcpy(pOutBuf, pScan+nScanlineLeftOffset, nNonAlphaBytes );
pOutBuf += nNonAlphaBytes;
*pOutBuf++ = m_pAlphaAcc->GetPixelIndex(pos.Y,pos.X);
}
}
return aRet;
}
uno::Reference< rendering::XBitmapPalette > SAL_CALL VclCanvasBitmap::getPalette() throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
uno::Reference< XBitmapPalette > aRet;
if( m_bPalette )
aRet.set(this);
return aRet;
}
rendering::IntegerBitmapLayout SAL_CALL VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
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)
{
SolarMutexGuard aGuard;
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)
{
SolarMutexGuard aGuard;
const sal_uInt16 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("Palette index out of range",
static_cast<rendering::XBitmapPalette*>(this));
const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(sal::static_int_cast<sal_uInt16>(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)
{
SolarMutexGuard aGuard;
const sal_uInt16 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("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>
{
uno::Reference<rendering::XColorSpace> operator()()
{
return vcl::unotools::createStandardColorSpace();
}
};
}
uno::Reference< rendering::XColorSpace > SAL_CALL VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException)
{
// this is the method from XBitmapPalette. Return palette color
// space here
return PaletteColorSpaceHolder::get();
}
sal_Int8 SAL_CALL VclCanvasBitmap::getType( ) throw (uno::RuntimeException)
{
return rendering::ColorSpaceType::RGB;
}
uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
return m_aComponentTags;
}
sal_Int8 SAL_CALL VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException)
{
return rendering::RenderingIntent::PERCEPTUAL;
}
uno::Sequence< ::beans::PropertyValue > SAL_CALL VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException)
{
return uno::Sequence< ::beans::PropertyValue >();
}
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);
}
uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
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( 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<sal_uInt16>(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");
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)
{
SolarMutexGuard aGuard;
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 )
{
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<sal_uInt16>(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++ = rendering::ARGBColor(nAlpha,
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");
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++ = rendering::ARGBColor(
nAlpha,
deviceColor[i+m_nRedIndex],
deviceColor[i+m_nGreenIndex],
deviceColor[i+m_nBlueIndex]);
}
}
return aRes;
}
uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
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 )
{
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<sal_uInt16>(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++ = rendering::ARGBColor(nAlpha,
nAlpha*toDoubleColor(aCol.GetRed()),
nAlpha*toDoubleColor(aCol.GetGreen()),
nAlpha*toDoubleColor(aCol.GetBlue()));
}
}
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++ = rendering::ARGBColor(
nAlpha,
nAlpha*deviceColor[i+m_nRedIndex],
nAlpha*deviceColor[i+m_nGreenIndex],
nAlpha*deviceColor[i+m_nBlueIndex]);
}
}
return aRes;
}
uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
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 )
{
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;
pColors += nComponentsPerPixel;
}
}
else
{
for( sal_Size i=0; i<nLen; ++i )
{
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;
}
}
return aRes;
}
uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
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 )
{
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
{
for( sal_Size i=0; i<nLen; ++i )
{
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;
}
}
return aRes;
}
uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
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 )
{
const double nAlpha( rgbColor[i].Alpha );
pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
BitmapColor(toByteColor(rgbColor[i].Red / nAlpha),
toByteColor(rgbColor[i].Green / nAlpha),
toByteColor(rgbColor[i].Blue / nAlpha)));
if( m_nAlphaIndex != -1 )
pColors[m_nAlphaIndex] = nAlpha;
pColors += nComponentsPerPixel;
}
}
else
{
for( sal_Size i=0; i<nLen; ++i )
{
const double nAlpha( rgbColor[i].Alpha );
pColors[m_nRedIndex] = rgbColor[i].Red / nAlpha;
pColors[m_nGreenIndex] = rgbColor[i].Green / nAlpha;
pColors[m_nBlueIndex] = rgbColor[i].Blue / nAlpha;
if( m_nAlphaIndex != -1 )
pColors[m_nAlphaIndex] = nAlpha;
pColors += nComponentsPerPixel;
}
}
return aRes;
}
sal_Int32 SAL_CALL VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
return m_nBitsPerOutputPixel;
}
uno::Sequence< ::sal_Int32 > SAL_CALL VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
return m_aComponentBitCounts;
}
sal_Int8 SAL_CALL VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
return m_nEndianness;
}
uno::Sequence<double> SAL_CALL VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
{
SolarMutexGuard aGuard;
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<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<sal_uInt16>(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);
}
}
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)
{
SolarMutexGuard aGuard;
const sal_uInt8* pIn( reinterpret_cast<const sal_uInt8*>(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( m_pBmpAcc->GetPixelFromData( pIn, i ).GetIndex()) :
m_pBmpAcc->GetPixelFromData(pIn, i);
// TODO(F3): Convert result to sRGB color space
*pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
toDoubleColor(aCol.GetGreen()),
toDoubleColor(aCol.GetBlue()));
}
}
return aRes;
}
uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
const sal_uInt8* pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
const sal_Size nLen( deviceColor.getLength() );
const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
rendering::ARGBColor* pOut( aRes.getArray() );
ENSURE_OR_THROW(m_pBmpAcc,
"Unable to get BitmapAccess");
if( m_aBmpEx.IsTransparent() )
{
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
{
for( sal_Int32 i=0; i<nNumColors; ++i )
{
const BitmapColor aCol =
m_bPalette ?
m_pBmpAcc->GetPaletteColor( m_pBmpAcc->GetPixelFromData( pIn, i ).GetIndex() ) :
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()));
}
}
return aRes;
}
uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
const sal_uInt8* pIn( reinterpret_cast<const sal_uInt8*>(deviceColor.getConstArray()) );
const sal_Size nLen( deviceColor.getLength() );
const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
rendering::ARGBColor* pOut( aRes.getArray() );
ENSURE_OR_THROW(m_pBmpAcc,
"Unable to get BitmapAccess");
if( m_aBmpEx.IsTransparent() )
{
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
const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]) );
*pOut++ = rendering::ARGBColor(nAlpha,
nAlpha*toDoubleColor(aCol.GetRed()),
nAlpha*toDoubleColor(aCol.GetGreen()),
nAlpha*toDoubleColor(aCol.GetBlue()));
pIn += nBytesPerPixel;
}
}
else
{
for( sal_Int32 i=0; i<nNumColors; ++i )
{
const BitmapColor aCol =
m_bPalette ?
m_pBmpAcc->GetPaletteColor( m_pBmpAcc->GetPixelFromData( pIn, i ).GetIndex() ) :
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()));
}
}
return aRes;
}
uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
const sal_Size nLen( rgbColor.getLength() );
const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
uno::Sequence< sal_Int8 > aRes(nNumBytes);
sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(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<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
aCol;
m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
pColors += nNonAlphaBytes;
*pColors++ = sal_uInt8(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<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
aCol;
m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
}
}
return aRes;
}
uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
const sal_Size nLen( rgbColor.getLength() );
const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
uno::Sequence< sal_Int8 > aRes(nNumBytes);
sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(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<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
aCol;
m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
pColors += nNonAlphaBytes;
*pColors++ = 255 - toByteColor(rgbColor[i].Alpha);
}
}
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<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
aCol;
m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
}
}
return aRes;
}
uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
{
SolarMutexGuard aGuard;
const sal_Size nLen( rgbColor.getLength() );
const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
uno::Sequence< sal_Int8 > aRes(nNumBytes);
sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray());
if( m_aBmpEx.IsTransparent() )
{
const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
for( sal_Size i=0; i<nLen; ++i )
{
const double nAlpha( rgbColor[i].Alpha );
const BitmapColor aCol(toByteColor(rgbColor[i].Red / nAlpha),
toByteColor(rgbColor[i].Green / nAlpha),
toByteColor(rgbColor[i].Blue / nAlpha));
const BitmapColor aCol2 =
m_bPalette ?
BitmapColor(
sal::static_int_cast<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
aCol;
m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
pColors += nNonAlphaBytes;
*pColors++ = 255 - toByteColor(nAlpha);
}
}
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<sal_uInt8>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
aCol;
m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
}
}
return aRes;
}
BitmapEx VclCanvasBitmap::getBitmapEx() const
{
return m_aBmpEx;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */