[Libreoffice-commits] core.git: filter/source include/vcl vcl/source

Noel Grandin noel.grandin at collabora.co.uk
Sat Feb 10 16:57:29 UTC 2018


 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 <noel.grandin at collabora.co.uk>
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 <ci at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

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: */


More information about the Libreoffice-commits mailing list