filter/source/graphicfilter/icgm/actimpr.cxx | 7 filter/source/graphicfilter/icgm/bitmap.cxx | 317 +++++++++++---------------- filter/source/graphicfilter/icgm/bitmap.hxx | 17 - include/vcl/BitmapTools.hxx | 28 ++ vcl/source/bitmap/BitmapTools.cxx | 28 ++ 5 files changed, 199 insertions(+), 198 deletions(-)
New commits: commit ac98ff5e869ca23dfa6174704f0eb56fbb1ae734 Author: Noel Grandin <[email protected]> Date: Fri Feb 9 16:27:35 2018 +0200 use RawBitmap and BitmapEx in icgm filter Change-Id: Icaffda666c27f733c0d490905e91a68b72073bcb Reviewed-on: https://gerrit.libreoffice.org/49502 Tested-by: Jenkins <[email protected]> Reviewed-by: Michael Meeks <[email protected]> diff --git a/filter/source/graphicfilter/icgm/actimpr.cxx b/filter/source/graphicfilter/icgm/actimpr.cxx index 8c38babec87e..5ec28efb1a89 100644 --- a/filter/source/graphicfilter/icgm/actimpr.cxx +++ b/filter/source/graphicfilter/icgm/actimpr.cxx @@ -545,7 +545,7 @@ void CGMImpressOutAct::DrawEllipticalArc( FloatPoint const & rCenter, FloatPoint void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor* pBmpDesc ) { - if ( pBmpDesc->mbStatus && pBmpDesc->mpBitmap ) + if ( pBmpDesc->mbStatus && !!pBmpDesc->mxBitmap ) { FloatPoint aOrigin = pBmpDesc->mnOrigin; double fdx = pBmpDesc->mndx; @@ -555,7 +555,7 @@ void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor* pBmpDesc ) if ( pBmpDesc->mbVMirror ) nMirr |= BmpMirrorFlags::Vertical; if ( nMirr != BmpMirrorFlags::NONE ) - pBmpDesc->mpBitmap->Mirror( nMirr ); + pBmpDesc->mxBitmap.Mirror( nMirr ); // FIXME mpCGM->ImplMapPoint( aOrigin ); mpCGM->ImplMapX( fdx ); @@ -571,9 +571,8 @@ void CGMImpressOutAct::DrawBitmap( CGMBitmapDescriptor* pBmpDesc ) 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) ); - } } } diff --git a/filter/source/graphicfilter/icgm/bitmap.cxx b/filter/source/graphicfilter/icgm/bitmap.cxx index 5125c9957c7a..5caa5a7515b7 100644 --- a/filter/source/graphicfilter/icgm/bitmap.cxx +++ b/filter/source/graphicfilter/icgm/bitmap.cxx @@ -19,11 +19,13 @@ #include "main.hxx" +#include <vcl/BitmapTools.hxx> +#include <memory> namespace { -constexpr BitmapColor BMCOL(sal_uInt32 _col) { - return BitmapColor( static_cast<sal_Int8>(_col >> 16 ), static_cast<sal_Int8>( _col >> 8 ), static_cast<sal_Int8>(_col) ); +Color BMCOL(sal_uInt32 _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; - if (ImplGetDimensions(rDesc) && rDesc.mpBuf && isLegalBitsPerPixel(rDesc.mnDstBitsPerPixel)) - { - 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 ... - - long nxCount = rDesc.mnX + 1; // +1 because we are using prefix decreasing - long nyCount = rDesc.mnY + 1; - long nx, ny, nxC; - - switch ( rDesc.mnDstBitsPerPixel ) - { - case 1 : - { - 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 : - { - ImplSetCurrentPalette( rDesc ); - 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 two bits/pixel format is rarely used - rDesc.mpAcc->SetPixelOnData(pScanline, nx, BitmapColor(static_cast<sal_uInt8>( (*(rDesc.mpBuf + (nx >> 2)) >> (((nx & 3)^3) << 1))) & 3)); - } - } - } - break; - - case 4 : - { - 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; + if (!(ImplGetDimensions(rDesc) && rDesc.mpBuf && isLegalBitsPerPixel(rDesc.mnDstBitsPerPixel))) + return; + + vcl::bitmap::RawBitmap aBitmap( Size( rDesc.mnX, rDesc.mnY ) ); + + // the picture may either be read from left to right or right to left, from top to bottom ... + + long nxCount = rDesc.mnX + 1; // +1 because we are using prefix decreasing + long nyCount = rDesc.mnY + 1; + long nx, ny, nxC; + + switch ( rDesc.mnDstBitsPerPixel ) { + case 1 : { + std::vector<Color> palette(2); + if ( rDesc.mnLocalColorPrecision == 1 ) + palette = ImplGeneratePalette( rDesc ); + else { + palette[0] = BMCOL( mpCGM->pElement->nBackGroundColor ); + palette[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; + for ( nx = 0; --nxC; nx++ ) { + // this is not fast, but a one bit/pixel format is rarely used + sal_uInt8 colorIndex = static_cast<sal_uInt8>( (*( rDesc.mpBuf + (nx >> 3)) >> ((nx & 7)^7))) & 1; + aBitmap.SetPixel(ny, nx, palette[colorIndex]); + } + } + } + break; + + case 2 : { + auto palette = ImplGeneratePalette( rDesc ); + for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize ) { + nxC = nxCount; + for ( nx = 0; --nxC; nx++ ) { + // 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]); + } + } + } + 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; } - double nX = rDesc.mnR.X - rDesc.mnQ.X; - double nY = rDesc.mnR.Y - rDesc.mnQ.Y; + } + } + 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 ); + rDesc.mndy = sqrt( nX * nX + nY * nY ); - nX = rDesc.mnR.X - rDesc.mnP.X; - nY = rDesc.mnR.Y - rDesc.mnP.Y; + nX = rDesc.mnR.X - rDesc.mnP.X; + nY = rDesc.mnR.Y - rDesc.mnP.Y; - rDesc.mndx = sqrt( nX * nX + nY * nY ); + rDesc.mndx = sqrt( nX * nX + nY * nY ); - nX = rDesc.mnR.X - rDesc.mnP.X; - nY = rDesc.mnR.Y - rDesc.mnP.Y; + 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; + 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; + 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 ); + 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; + 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; + 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; - if ( rDesc.mpAcc ) - { - Bitmap::ReleaseAccess( rDesc.mpAcc ); - rDesc.mpAcc = nullptr; - } - if ( !rDesc.mbStatus ) - { - if ( rDesc.mpBitmap ) - { - delete rDesc.mpBitmap; - rDesc.mpBitmap = nullptr; - } - } + if ( rDesc.mbStatus ) + rDesc.mxBitmap = vcl::bitmap::CreateFromData(std::move(aBitmap)); } - -void CGMBitmap::ImplSetCurrentPalette( CGMBitmapDescriptor& rDesc ) +std::vector<Color> CGMBitmap::ImplGeneratePalette( CGMBitmapDescriptor& rDesc ) { sal_uInt16 nColors = sal::static_int_cast< sal_uInt16 >( 1 << rDesc.mnDstBitsPerPixel); - rDesc.mpAcc->SetPaletteEntryCount( nColors ); + std::vector<Color> palette( nColors ); 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 if ( mpCGM->mnVDCYmul == -1 ) rDest.mnOrigin = rSource.mnOrigin; // new origin - rDest.mpBitmap->Expand( 0, rSource.mnY ); - rDest.mpBitmap->CopyPixel( tools::Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ), - tools::Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap ); + rDest.mxBitmap.Expand( 0, 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.mxBitmap ); FloatPoint aFloatPoint; aFloatPoint.X = rSource.mnQ.X - rSource.mnR.X; aFloatPoint.Y = rSource.mnQ.Y - rSource.mnR.Y; @@ -369,9 +328,9 @@ void CGMBitmap::ImplInsert( CGMBitmapDescriptor const & rSource, CGMBitmapDescri { // Insert on Top if ( mpCGM->mnVDCYmul == 1 ) rDest.mnOrigin = rSource.mnOrigin; // new origin - rDest.mpBitmap->Expand( 0, rSource.mnY ); - rDest.mpBitmap->CopyPixel( tools::Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ), - tools::Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap ); + rDest.mxBitmap.Expand( 0, 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.mxBitmap ); rDest.mnP = rSource.mnP; 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> xCGMTempBitmap; - if (pCGMBitmapDescriptor->mpBitmap && pCGMBitmapDescriptor->mbStatus) + if (!!pCGMBitmapDescriptor->mxBitmap && pCGMBitmapDescriptor->mbStatus) { xCGMTempBitmap.reset(new CGMBitmap(*mpCGM)); if ( ( static_cast<long>(xCGMTempBitmap->pCGMBitmapDescriptor->mnOrientation) == static_cast<long>(pCGMBitmapDescriptor->mnOrientation) ) && diff --git a/filter/source/graphicfilter/icgm/bitmap.hxx b/filter/source/graphicfilter/icgm/bitmap.hxx index e05ef169a676..6b5d9986ad73 100644 --- a/filter/source/graphicfilter/icgm/bitmap.hxx +++ b/filter/source/graphicfilter/icgm/bitmap.hxx @@ -20,9 +20,9 @@ #ifndef INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ICGM_BITMAP_HXX #define INCLUDED_FILTER_SOURCE_GRAPHICFILTER_ICGM_BITMAP_HXX -#include <memory> #include "cgm.hxx" -#include <vcl/bitmapaccess.hxx> +#include <vcl/bitmapex.hxx> +#include <vector> class CGM; @@ -30,8 +30,7 @@ class CGMBitmapDescriptor { public: sal_uInt8* mpBuf; - Bitmap* mpBitmap; - BitmapWriteAccess* mpAcc; + BitmapEx mxBitmap; bool mbStatus; bool mbVMirror; sal_uInt32 mnDstBitsPerPixel; @@ -48,8 +47,6 @@ class CGMBitmapDescriptor CGMBitmapDescriptor() : mpBuf(nullptr) - , mpBitmap(nullptr) - , mpAcc(nullptr) , mbStatus(false) , mbVMirror(false) , mnDstBitsPerPixel(0) @@ -62,12 +59,6 @@ class CGMBitmapDescriptor , mnLocalColorPrecision(0) , mnCompressionMode(0) { }; - ~CGMBitmapDescriptor() - { - if ( mpAcc ) - ::Bitmap::ReleaseAccess( mpAcc ); - delete mpBitmap; - }; }; class CGMBitmap @@ -76,7 +67,7 @@ class CGMBitmap std::unique_ptr<CGMBitmapDescriptor> pCGMBitmapDescriptor; bool ImplGetDimensions( CGMBitmapDescriptor& ); - void ImplSetCurrentPalette( CGMBitmapDescriptor& ); + std::vector<Color> ImplGeneratePalette( CGMBitmapDescriptor& ); void ImplGetBitmap( CGMBitmapDescriptor& ); void ImplInsert( CGMBitmapDescriptor const & rSource, CGMBitmapDescriptor& rDest ); public: diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx index ed448dfa0e1c..6339994a285d 100644 --- a/include/vcl/BitmapTools.hxx +++ b/include/vcl/BitmapTools.hxx @@ -11,13 +11,36 @@ #define INCLUDED_VCL_BITMAP_TOOLS_HXX #include <vcl/bitmapex.hxx> -#include <tools/stream.hxx> - #include <vcl/ImageTree.hxx> +#include <vcl/salbtype.hxx> +#include <tools/stream.hxx> namespace vcl { 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); 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( RawBitmap && data ); }} // end vcl::bitmap diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx index 94974f57746d..767b4de7e25a 100644 --- a/vcl/source/bitmap/BitmapTools.cxx +++ b/vcl/source/bitmap/BitmapTools.cxx @@ -135,6 +135,34 @@ BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHe 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 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
