use RawBitmap and BitmapEx in icgm filter

Change-Id: Icaffda666c27f733c0d490905e91a68b72073bcb
Reviewed-on: https://gerrit.libreoffice.org/49502
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
This commit is contained in:
Noel Grandin
2018-02-09 16:27:35 +02:00
committed by Michael Meeks
parent fc763bd9b9
commit ac98ff5e86
5 changed files with 201 additions and 200 deletions

View File

@@ -545,7 +545,7 @@ void CGMImpressOutAct::DrawEllipticalArc( FloatPoint const & rCenter, FloatPoint
void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor* pBmpDesc ) void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor* pBmpDesc )
{ {
if ( pBmpDesc->mbStatus && pBmpDesc->mpBitmap ) if ( pBmpDesc->mbStatus && !!pBmpDesc->mxBitmap )
{ {
FloatPoint aOrigin = pBmpDesc->mnOrigin; FloatPoint aOrigin = pBmpDesc->mnOrigin;
double fdx = pBmpDesc->mndx; double fdx = pBmpDesc->mndx;
@@ -555,7 +555,7 @@ void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor* pBmpDesc )
if ( pBmpDesc->mbVMirror ) if ( pBmpDesc->mbVMirror )
nMirr |= BmpMirrorFlags::Vertical; nMirr |= BmpMirrorFlags::Vertical;
if ( nMirr != BmpMirrorFlags::NONE ) if ( nMirr != BmpMirrorFlags::NONE )
pBmpDesc->mpBitmap->Mirror( nMirr ); pBmpDesc->mxBitmap.Mirror( nMirr ); // FIXME
mpCGM->ImplMapPoint( aOrigin ); mpCGM->ImplMapPoint( aOrigin );
mpCGM->ImplMapX( fdx ); mpCGM->ImplMapX( fdx );
@@ -571,9 +571,8 @@ void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor* pBmpDesc )
ImplSetOrientation( aOrigin, pBmpDesc->mnOrientation ); ImplSetOrientation( aOrigin, pBmpDesc->mnOrientation );
} }
uno::Reference< awt::XBitmap > xBitmap( VCLUnoHelper::CreateBitmap( BitmapEx( *( pBmpDesc->mpBitmap ) ) ) ); uno::Reference< awt::XBitmap > xBitmap( VCLUnoHelper::CreateBitmap( pBmpDesc->mxBitmap ) );
maXPropSet->setPropertyValue( "GraphicObjectFillBitmap", uno::Any(xBitmap) ); maXPropSet->setPropertyValue( "GraphicObjectFillBitmap", uno::Any(xBitmap) );
} }
} }
} }

View File

@@ -19,11 +19,13 @@
#include "main.hxx" #include "main.hxx"
#include <vcl/BitmapTools.hxx>
#include <memory>
namespace { namespace {
constexpr BitmapColor BMCOL(sal_uInt32 _col) { Color BMCOL(sal_uInt32 _col) {
return BitmapColor( static_cast<sal_Int8>(_col >> 16 ), static_cast<sal_Int8>( _col >> 8 ), static_cast<sal_Int8>(_col) ); return Color( static_cast<sal_Int8>(_col >> 16 ), static_cast<sal_Int8>( _col >> 8 ), static_cast<sal_Int8>(_col) );
} }
} }
@@ -64,196 +66,153 @@ void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc )
{ {
rDesc.mbStatus = true; rDesc.mbStatus = true;
if (ImplGetDimensions(rDesc) && rDesc.mpBuf && isLegalBitsPerPixel(rDesc.mnDstBitsPerPixel)) if (!(ImplGetDimensions(rDesc) && rDesc.mpBuf && isLegalBitsPerPixel(rDesc.mnDstBitsPerPixel)))
{ return;
rDesc.mpBitmap = new Bitmap( Size( rDesc.mnX, rDesc.mnY ), static_cast<sal_uInt16>(rDesc.mnDstBitsPerPixel) );
if ( ( rDesc.mpAcc = rDesc.mpBitmap->AcquireWriteAccess() ) != nullptr )
{
// the picture may either be read from left to right or right to left, from top to bottom ... vcl::bitmap::RawBitmap aBitmap( Size( rDesc.mnX, rDesc.mnY ) );
long nxCount = rDesc.mnX + 1; // +1 because we are using prefix decreasing // the picture may either be read from left to right or right to left, from top to bottom ...
long nyCount = rDesc.mnY + 1;
long nx, ny, nxC;
switch ( rDesc.mnDstBitsPerPixel ) long nxCount = rDesc.mnX + 1; // +1 because we are using prefix decreasing
{ long nyCount = rDesc.mnY + 1;
case 1 : long nx, ny, nxC;
{
if ( rDesc.mnLocalColorPrecision == 1 )
ImplSetCurrentPalette( rDesc );
else
{
rDesc.mpAcc->SetPaletteEntryCount( 2 );
rDesc.mpAcc->SetPaletteColor( 0, BMCOL( mpCGM->pElement->nBackGroundColor ) );
rDesc.mpAcc->SetPaletteColor( 1,
( mpCGM->pElement->nAspectSourceFlags & ASF_FILLINTERIORSTYLE )
? BMCOL( mpCGM->pElement->pFillBundle->GetColor() )
: BMCOL( mpCGM->pElement->aFillBundle.GetColor() ) ) ;
}
for ( ny = 0; --nyCount ; ny++, rDesc.mpBuf += rDesc.mnScanSize )
{
nxC = nxCount;
Scanline pScanline = rDesc.mpAcc->GetScanline( ny );
for ( nx = 0; --nxC; nx++ )
{ // this is not fast, but a one bit/pixel format is rarely used
rDesc.mpAcc->SetPixelOnData(pScanline, nx, BitmapColor(static_cast<sal_uInt8>( (*( rDesc.mpBuf + (nx >> 3)) >> ((nx & 7)^7))) & 1));
}
}
}
break;
case 2 : switch ( rDesc.mnDstBitsPerPixel ) {
{ case 1 : {
ImplSetCurrentPalette( rDesc ); std::vector<Color> palette(2);
for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) if ( rDesc.mnLocalColorPrecision == 1 )
{ palette = ImplGeneratePalette( rDesc );
nxC = nxCount; else {
Scanline pScanline = rDesc.mpAcc->GetScanline( ny ); palette[0] = BMCOL( mpCGM->pElement->nBackGroundColor );
for ( nx = 0; --nxC; nx++ ) palette[1] = ( mpCGM->pElement->nAspectSourceFlags & ASF_FILLINTERIORSTYLE )
{ // this is not fast, but a two bits/pixel format is rarely used ? BMCOL( mpCGM->pElement->pFillBundle->GetColor() )
rDesc.mpAcc->SetPixelOnData(pScanline, nx, BitmapColor(static_cast<sal_uInt8>( (*(rDesc.mpBuf + (nx >> 2)) >> (((nx & 3)^3) << 1))) & 3)); : BMCOL( mpCGM->pElement->aFillBundle.GetColor() );
} };
} for ( ny = 0; --nyCount ; ny++, rDesc.mpBuf += rDesc.mnScanSize ) {
} nxC = nxCount;
break; for ( nx = 0; --nxC; nx++ ) {
// this is not fast, but a one bit/pixel format is rarely used
case 4 : sal_uInt8 colorIndex = static_cast<sal_uInt8>( (*( rDesc.mpBuf + (nx >> 3)) >> ((nx & 7)^7))) & 1;
{ aBitmap.SetPixel(ny, nx, palette[colorIndex]);
ImplSetCurrentPalette( rDesc );
for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
{
nxC = nxCount;
Scanline pScanline = rDesc.mpAcc->GetScanline( ny );
sal_Int8 nDat;
sal_uInt8* pTemp = rDesc.mpBuf;
for ( nx = 0; --nxC; nx++ )
{
nDat = *pTemp++;
rDesc.mpAcc->SetPixelOnData(pScanline, nx, BitmapColor(static_cast<sal_uInt8>(nDat >> 4)));
if ( --nxC )
{
++nx;
rDesc.mpAcc->SetPixelOnData(pScanline, nx, BitmapColor(static_cast<sal_uInt8>(nDat & 15)));
}
else
break;
}
}
}
break;
case 8 :
{
ImplSetCurrentPalette( rDesc );
for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
{
sal_uInt8* pTemp = rDesc.mpBuf;
Scanline pScanline = rDesc.mpAcc->GetScanline( ny );
nxC = nxCount;
for ( nx = 0; --nxC; nx++ )
{
rDesc.mpAcc->SetPixelOnData(pScanline, nx, BitmapColor(*(pTemp++)));
}
}
}
break;
case 24 :
{
BitmapColor aBitmapColor;
for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
{
sal_uInt8* pTemp = rDesc.mpBuf;
nxC = nxCount;
Scanline pScanline = rDesc.mpAcc->GetScanline( ny );
for ( nx = 0; --nxC; nx++ )
{
aBitmapColor.SetRed( *pTemp++ );
aBitmapColor.SetGreen( *pTemp++ );
aBitmapColor.SetBlue( *pTemp++ );
rDesc.mpAcc->SetPixelOnData(pScanline, nx, aBitmapColor);
}
}
}
break;
}
double nX = rDesc.mnR.X - rDesc.mnQ.X;
double nY = rDesc.mnR.Y - rDesc.mnQ.Y;
rDesc.mndy = sqrt( nX * nX + nY * nY );
nX = rDesc.mnR.X - rDesc.mnP.X;
nY = rDesc.mnR.Y - rDesc.mnP.Y;
rDesc.mndx = sqrt( nX * nX + nY * nY );
nX = rDesc.mnR.X - rDesc.mnP.X;
nY = rDesc.mnR.Y - rDesc.mnP.Y;
double fSqrt = sqrt(nX * nX + nY * nY);
rDesc.mnOrientation = fSqrt != 0.0 ? (acos(nX / fSqrt) * 57.29577951308) : 0.0;
if ( nY > 0 )
rDesc.mnOrientation = 360 - rDesc.mnOrientation;
nX = rDesc.mnQ.X - rDesc.mnR.X;
nY = rDesc.mnQ.Y - rDesc.mnR.Y;
double fAngle = 0.01745329251994 * ( 360 - rDesc.mnOrientation );
double fSin = sin(fAngle);
double fCos = cos(fAngle);
nX = fCos * nX + fSin * nY;
nY = -( fSin * nX - fCos * nY );
fSqrt = sqrt(nX * nX + nY * nY);
fAngle = fSqrt != 0.0 ? (acos(nX / fSqrt) * 57.29577951308) : 0.0;
if ( nY > 0 )
fAngle = 360 - fAngle;
if ( fAngle > 180 ) // is the picture build upwards or downwards ?
{
rDesc.mnOrigin = rDesc.mnP;
}
else
{
rDesc.mbVMirror = true;
rDesc.mnOrigin = rDesc.mnP;
rDesc.mnOrigin.X += rDesc.mnQ.X - rDesc.mnR.X;
rDesc.mnOrigin.Y += rDesc.mnQ.Y - rDesc.mnR.Y;
} }
} }
else
rDesc.mbStatus = false;
} }
else break;
rDesc.mbStatus = false;
if ( rDesc.mpAcc ) case 2 : {
{ auto palette = ImplGeneratePalette( rDesc );
Bitmap::ReleaseAccess( rDesc.mpAcc ); for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) {
rDesc.mpAcc = nullptr; nxC = nxCount;
} for ( nx = 0; --nxC; nx++ ) {
if ( !rDesc.mbStatus ) // this is not fast, but a two bits/pixel format is rarely used
{ aBitmap.SetPixel(ny, nx, palette[static_cast<sal_uInt8>( (*(rDesc.mpBuf + (nx >> 2)) >> (((nx & 3)^3) << 1))) & 3]);
if ( rDesc.mpBitmap ) }
{
delete rDesc.mpBitmap;
rDesc.mpBitmap = nullptr;
} }
} }
break;
case 4 : {
auto palette = ImplGeneratePalette( rDesc );
for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) {
nxC = nxCount;
sal_Int8 nDat;
sal_uInt8* pTemp = rDesc.mpBuf;
for ( nx = 0; --nxC; nx++ ) {
nDat = *pTemp++;
aBitmap.SetPixel(ny, nx, palette[static_cast<sal_uInt8>(nDat >> 4)]);
if ( --nxC ) {
++nx;
aBitmap.SetPixel(ny, nx, palette[static_cast<sal_uInt8>(nDat & 15)]);
} else
break;
}
}
}
break;
case 8 : {
auto palette = ImplGeneratePalette( rDesc );
for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) {
sal_uInt8* pTemp = rDesc.mpBuf;
nxC = nxCount;
for ( nx = 0; --nxC; nx++ ) {
aBitmap.SetPixel(ny, nx, palette[*(pTemp++)]);
}
}
}
break;
case 24 : {
Color aBitmapColor;
for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) {
sal_uInt8* pTemp = rDesc.mpBuf;
nxC = nxCount;
for ( nx = 0; --nxC; nx++ ) {
aBitmapColor.SetRed( *pTemp++ );
aBitmapColor.SetGreen( *pTemp++ );
aBitmapColor.SetBlue( *pTemp++ );
aBitmap.SetPixel(ny, nx, aBitmapColor);
}
}
}
break;
}
double nX = rDesc.mnR.X - rDesc.mnQ.X;
double nY = rDesc.mnR.Y - rDesc.mnQ.Y;
rDesc.mndy = sqrt( nX * nX + nY * nY );
nX = rDesc.mnR.X - rDesc.mnP.X;
nY = rDesc.mnR.Y - rDesc.mnP.Y;
rDesc.mndx = sqrt( nX * nX + nY * nY );
nX = rDesc.mnR.X - rDesc.mnP.X;
nY = rDesc.mnR.Y - rDesc.mnP.Y;
double fSqrt = sqrt(nX * nX + nY * nY);
rDesc.mnOrientation = fSqrt != 0.0 ? (acos(nX / fSqrt) * 57.29577951308) : 0.0;
if ( nY > 0 )
rDesc.mnOrientation = 360 - rDesc.mnOrientation;
nX = rDesc.mnQ.X - rDesc.mnR.X;
nY = rDesc.mnQ.Y - rDesc.mnR.Y;
double fAngle = 0.01745329251994 * ( 360 - rDesc.mnOrientation );
double fSin = sin(fAngle);
double fCos = cos(fAngle);
nX = fCos * nX + fSin * nY;
nY = -( fSin * nX - fCos * nY );
fSqrt = sqrt(nX * nX + nY * nY);
fAngle = fSqrt != 0.0 ? (acos(nX / fSqrt) * 57.29577951308) : 0.0;
if ( nY > 0 )
fAngle = 360 - fAngle;
if ( fAngle > 180 ) { // is the picture build upwards or downwards ?
rDesc.mnOrigin = rDesc.mnP;
} else {
rDesc.mbVMirror = true;
rDesc.mnOrigin = rDesc.mnP;
rDesc.mnOrigin.X += rDesc.mnQ.X - rDesc.mnR.X;
rDesc.mnOrigin.Y += rDesc.mnQ.Y - rDesc.mnR.Y;
}
if ( rDesc.mbStatus )
rDesc.mxBitmap = vcl::bitmap::CreateFromData(std::move(aBitmap));
} }
std::vector<Color> CGMBitmap::ImplGeneratePalette( CGMBitmapDescriptor& rDesc )
void CGMBitmap::ImplSetCurrentPalette( CGMBitmapDescriptor& rDesc )
{ {
sal_uInt16 nColors = sal::static_int_cast< sal_uInt16 >( sal_uInt16 nColors = sal::static_int_cast< sal_uInt16 >(
1 << rDesc.mnDstBitsPerPixel); 1 << rDesc.mnDstBitsPerPixel);
rDesc.mpAcc->SetPaletteEntryCount( nColors ); std::vector<Color> palette( nColors );
for ( sal_uInt16 i = 0; i < nColors; i++ ) for ( sal_uInt16 i = 0; i < nColors; i++ )
{ {
rDesc.mpAcc->SetPaletteColor( i, BMCOL( mpCGM->pElement->aLatestColorTable[ i ] ) ); palette[i] = BMCOL( mpCGM->pElement->aLatestColorTable[ i ] );
} }
return palette;
} }
@@ -354,9 +313,9 @@ void CGMBitmap::ImplInsert( CGMBitmapDescriptor const & rSource, CGMBitmapDescri
{ // Insert on Bottom { // Insert on Bottom
if ( mpCGM->mnVDCYmul == -1 ) if ( mpCGM->mnVDCYmul == -1 )
rDest.mnOrigin = rSource.mnOrigin; // new origin rDest.mnOrigin = rSource.mnOrigin; // new origin
rDest.mpBitmap->Expand( 0, rSource.mnY ); rDest.mxBitmap.Expand( 0, rSource.mnY );
rDest.mpBitmap->CopyPixel( tools::Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ), rDest.mxBitmap.CopyPixel( tools::Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
tools::Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap ); tools::Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), &rSource.mxBitmap );
FloatPoint aFloatPoint; FloatPoint aFloatPoint;
aFloatPoint.X = rSource.mnQ.X - rSource.mnR.X; aFloatPoint.X = rSource.mnQ.X - rSource.mnR.X;
aFloatPoint.Y = rSource.mnQ.Y - rSource.mnR.Y; aFloatPoint.Y = rSource.mnQ.Y - rSource.mnR.Y;
@@ -369,9 +328,9 @@ void CGMBitmap::ImplInsert( CGMBitmapDescriptor const & rSource, CGMBitmapDescri
{ // Insert on Top { // Insert on Top
if ( mpCGM->mnVDCYmul == 1 ) if ( mpCGM->mnVDCYmul == 1 )
rDest.mnOrigin = rSource.mnOrigin; // new origin rDest.mnOrigin = rSource.mnOrigin; // new origin
rDest.mpBitmap->Expand( 0, rSource.mnY ); rDest.mxBitmap.Expand( 0, rSource.mnY );
rDest.mpBitmap->CopyPixel( tools::Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ), rDest.mxBitmap.CopyPixel( tools::Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
tools::Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap ); tools::Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), &rSource.mxBitmap );
rDest.mnP = rSource.mnP; rDest.mnP = rSource.mnP;
rDest.mnR = rSource.mnR; rDest.mnR = rSource.mnR;
} }
@@ -382,7 +341,7 @@ void CGMBitmap::ImplInsert( CGMBitmapDescriptor const & rSource, CGMBitmapDescri
std::unique_ptr<CGMBitmap> CGMBitmap::GetNext() std::unique_ptr<CGMBitmap> CGMBitmap::GetNext()
{ {
std::unique_ptr<CGMBitmap> xCGMTempBitmap; std::unique_ptr<CGMBitmap> xCGMTempBitmap;
if (pCGMBitmapDescriptor->mpBitmap && pCGMBitmapDescriptor->mbStatus) if (!!pCGMBitmapDescriptor->mxBitmap && pCGMBitmapDescriptor->mbStatus)
{ {
xCGMTempBitmap.reset(new CGMBitmap(*mpCGM)); xCGMTempBitmap.reset(new CGMBitmap(*mpCGM));
if ( ( static_cast<long>(xCGMTempBitmap->pCGMBitmapDescriptor->mnOrientation) == static_cast<long>(pCGMBitmapDescriptor->mnOrientation) ) && if ( ( static_cast<long>(xCGMTempBitmap->pCGMBitmapDescriptor->mnOrientation) == static_cast<long>(pCGMBitmapDescriptor->mnOrientation) ) &&

View File

@@ -20,9 +20,9 @@
#ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ICGM_BITMAP_HXX #ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ICGM_BITMAP_HXX
#define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ICGM_BITMAP_HXX #define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ICGM_BITMAP_HXX
#include <memory>
#include "cgm.hxx" #include "cgm.hxx"
#include <vcl/bitmapaccess.hxx> #include <vcl/bitmapex.hxx>
#include <vector>
class CGM; class CGM;
@@ -30,8 +30,7 @@ class CGMBitmapDescriptor
{ {
public: public:
sal_uInt8* mpBuf; sal_uInt8* mpBuf;
Bitmap* mpBitmap; BitmapEx mxBitmap;
BitmapWriteAccess* mpAcc;
bool mbStatus; bool mbStatus;
bool mbVMirror; bool mbVMirror;
sal_uInt32 mnDstBitsPerPixel; sal_uInt32 mnDstBitsPerPixel;
@@ -48,8 +47,6 @@ class CGMBitmapDescriptor
CGMBitmapDescriptor() CGMBitmapDescriptor()
: mpBuf(nullptr) : mpBuf(nullptr)
, mpBitmap(nullptr)
, mpAcc(nullptr)
, mbStatus(false) , mbStatus(false)
, mbVMirror(false) , mbVMirror(false)
, mnDstBitsPerPixel(0) , mnDstBitsPerPixel(0)
@@ -62,12 +59,6 @@ class CGMBitmapDescriptor
, mnLocalColorPrecision(0) , mnLocalColorPrecision(0)
, mnCompressionMode(0) , mnCompressionMode(0)
{ }; { };
~CGMBitmapDescriptor()
{
if ( mpAcc )
::Bitmap::ReleaseAccess( mpAcc );
delete mpBitmap;
};
}; };
class CGMBitmap class CGMBitmap
@@ -76,7 +67,7 @@ class CGMBitmap
std::unique_ptr<CGMBitmapDescriptor> std::unique_ptr<CGMBitmapDescriptor>
pCGMBitmapDescriptor; pCGMBitmapDescriptor;
bool ImplGetDimensions( CGMBitmapDescriptor& ); bool ImplGetDimensions( CGMBitmapDescriptor& );
void ImplSetCurrentPalette( CGMBitmapDescriptor& ); std::vector<Color> ImplGeneratePalette( CGMBitmapDescriptor& );
void ImplGetBitmap( CGMBitmapDescriptor& ); void ImplGetBitmap( CGMBitmapDescriptor& );
void ImplInsert( CGMBitmapDescriptor const & rSource, CGMBitmapDescriptor& rDest ); void ImplInsert( CGMBitmapDescriptor const & rSource, CGMBitmapDescriptor& rDest );
public: public:

View File

@@ -11,13 +11,36 @@
#define INCLUDED_VCL_BITMAP_TOOLS_HXX #define INCLUDED_VCL_BITMAP_TOOLS_HXX
#include <vcl/bitmapex.hxx> #include <vcl/bitmapex.hxx>
#include <tools/stream.hxx>
#include <vcl/ImageTree.hxx> #include <vcl/ImageTree.hxx>
#include <vcl/salbtype.hxx>
#include <tools/stream.hxx>
namespace vcl { namespace vcl {
namespace bitmap { namespace bitmap {
/**
* intended to be used to feed into CreateFromData to create a BitmapEx
*/
class VCL_DLLPUBLIC RawBitmap
{
friend BitmapEx VCL_DLLPUBLIC CreateFromData( RawBitmap&& rawBitmap );
std::unique_ptr<sal_uInt8[]> mpData;
Size maSize;
public:
RawBitmap(Size const & rSize)
: mpData(new sal_uInt8[ rSize.getWidth() * 3 * rSize.getHeight()]),
maSize(rSize)
{
}
void SetPixel(long nY, long nX, BitmapColor nColor)
{
long p = nY * maSize.getWidth() + nX;
mpData[ p++ ] = nColor.GetRed();
mpData[ p++ ] = nColor.GetGreen();
mpData[ p ] = nColor.GetBlue();
}
};
BitmapEx VCL_DLLPUBLIC loadFromName(const OUString& rFileName, const ImageLoadFlags eFlags = ImageLoadFlags::NONE); BitmapEx VCL_DLLPUBLIC loadFromName(const OUString& rFileName, const ImageLoadFlags eFlags = ImageLoadFlags::NONE);
void loadFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, double fScaleFactor); void loadFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, double fScaleFactor);
@@ -32,6 +55,7 @@ void loadFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx,
*/ */
BitmapEx VCL_DLLPUBLIC CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, sal_uInt16 nBitCount ); BitmapEx VCL_DLLPUBLIC CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, sal_uInt16 nBitCount );
BitmapEx VCL_DLLPUBLIC CreateFromData( RawBitmap && data );
}} // end vcl::bitmap }} // end vcl::bitmap

View File

@@ -135,6 +135,34 @@ BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHe
return aBmp; return aBmp;
} }
/** Copy block of image data into the bitmap.
Assumes that the Bitmap has been constructed with the desired size.
*/
BitmapEx CreateFromData( RawBitmap&& rawBitmap )
{
Bitmap aBmp( rawBitmap.maSize, /*nBitCount*/24 );
Bitmap::ScopedWriteAccess pWrite(aBmp);
assert(pWrite.get());
if( !pWrite )
return BitmapEx();
auto nHeight = rawBitmap.maSize.getHeight();
auto nWidth = rawBitmap.maSize.getWidth();
for( long y = 0; y < nHeight; ++y )
{
sal_uInt8 const *p = rawBitmap.mpData.get() + y * nWidth;
Scanline pScanline = pWrite->GetScanline(y);
for (long x = 0; x < nWidth; ++x)
{
BitmapColor col(p[0], p[1], p[2]);
pWrite->SetPixelOnData(pScanline, x, col);
p += 3;
}
}
return aBmp;
}
}} // end vcl::bitmap }} // end vcl::bitmap
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */