include/vcl/BitmapBuffer.hxx     |    2 -
 vcl/headless/BitmapHelper.cxx    |    2 -
 vcl/headless/CairoCommon.cxx     |   12 +++----
 vcl/headless/svpbmp.cxx          |   63 ++++++++++++++++-----------------------
 vcl/inc/headless/CairoCommon.hxx |    3 -
 vcl/inc/headless/svpbmp.hxx      |    7 ++--
 vcl/source/gdi/salmisc.cxx       |   16 ++++-----
 vcl/win/gdi/salbmp.cxx           |   12 +++----
 8 files changed, 54 insertions(+), 63 deletions(-)

New commits:
commit c4228a798ef63ea6d3a2e822cd8d1cccf46837af
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Dec 1 10:34:20 2023 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Dec 2 09:07:15 2023 +0100

    pass BitmapBuffer around by std::optional
    
    instead of allocating on the heap, it is small
    
    Change-Id: I79eec6605a04c09d9a984cd1a719affb5b06dff3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160195
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/include/vcl/BitmapBuffer.hxx b/include/vcl/BitmapBuffer.hxx
index 54efeea5e1bc..a02a459489b5 100644
--- a/include/vcl/BitmapBuffer.hxx
+++ b/include/vcl/BitmapBuffer.hxx
@@ -45,7 +45,7 @@ struct VCL_DLLPUBLIC BitmapBuffer
     sal_uInt16      mnBitCount;
 };
 
-VCL_DLLPUBLIC std::unique_ptr<BitmapBuffer> StretchAndConvert(
+VCL_DLLPUBLIC std::optional<BitmapBuffer> StretchAndConvert(
     const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect,
     ScanlineFormat nDstBitmapFormat, std::optional<BitmapPalette> pDstPal = 
std::nullopt, const ColorMask* pDstMask = nullptr );
 
diff --git a/vcl/headless/BitmapHelper.cxx b/vcl/headless/BitmapHelper.cxx
index 8ed0cac09fcb..2cdf502fc9f2 100644
--- a/vcl/headless/BitmapHelper.cxx
+++ b/vcl/headless/BitmapHelper.cxx
@@ -38,7 +38,7 @@ BitmapHelper::BitmapHelper(const SalBitmap& rSourceBitmap, 
const bool bForceARGB
         const BitmapBuffer* pSrc = rSrcBmp.GetBuffer();
         const SalTwoRect aTwoRect
             = { 0, 0, pSrc->mnWidth, pSrc->mnHeight, 0, 0, pSrc->mnWidth, 
pSrc->mnHeight };
-        std::unique_ptr<BitmapBuffer> pTmp
+        std::optional<BitmapBuffer> pTmp
             = (pSrc->mnFormat == SVP_24BIT_FORMAT
                    ? FastConvert24BitRgbTo32BitCairo(pSrc)
                    : StretchAndConvert(*pSrc, aTwoRect, SVP_CAIRO_FORMAT));
diff --git a/vcl/headless/CairoCommon.cxx b/vcl/headless/CairoCommon.cxx
index 5e97de6aa5d6..2af8e0d892e2 100644
--- a/vcl/headless/CairoCommon.cxx
+++ b/vcl/headless/CairoCommon.cxx
@@ -1988,15 +1988,15 @@ bool CairoCommon::supportsOperation(OutDevSupportType 
eType)
     return false;
 }
 
-std::unique_ptr<BitmapBuffer> FastConvert24BitRgbTo32BitCairo(const 
BitmapBuffer* pSrc)
+std::optional<BitmapBuffer> FastConvert24BitRgbTo32BitCairo(const 
BitmapBuffer* pSrc)
 {
     if (pSrc == nullptr)
-        return nullptr;
+        return std::nullopt;
 
     assert(pSrc->mnFormat == SVP_24BIT_FORMAT);
     const tools::Long nWidth = pSrc->mnWidth;
     const tools::Long nHeight = pSrc->mnHeight;
-    std::unique_ptr<BitmapBuffer> pDst(new BitmapBuffer);
+    std::optional<BitmapBuffer> pDst(std::in_place);
     pDst->mnFormat = (ScanlineFormat::N32BitTcArgb | ScanlineFormat::TopDown);
     pDst->mnWidth = nWidth;
     pDst->mnHeight = nHeight;
@@ -2010,7 +2010,7 @@ std::unique_ptr<BitmapBuffer> 
FastConvert24BitRgbTo32BitCairo(const BitmapBuffer
     {
         SAL_WARN("vcl.gdi", "checked multiply failed");
         pDst->mpBits = nullptr;
-        return nullptr;
+        return std::nullopt;
     }
 
     pDst->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
@@ -2018,7 +2018,7 @@ std::unique_ptr<BitmapBuffer> 
FastConvert24BitRgbTo32BitCairo(const BitmapBuffer
     {
         SAL_WARN("vcl.gdi", "scanline calculation wraparound");
         pDst->mpBits = nullptr;
-        return nullptr;
+        return std::nullopt;
     }
 
     try
@@ -2029,7 +2029,7 @@ std::unique_ptr<BitmapBuffer> 
FastConvert24BitRgbTo32BitCairo(const BitmapBuffer
     {
         // memory exception, clean up
         pDst->mpBits = nullptr;
-        return nullptr;
+        return std::nullopt;
     }
 
     for (tools::Long y = 0; y < nHeight; ++y)
diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx
index bb8153fb87ef..178ea129c655 100644
--- a/vcl/headless/svpbmp.cxx
+++ b/vcl/headless/svpbmp.cxx
@@ -43,25 +43,16 @@ SvpSalBitmap::~SvpSalBitmap()
     Destroy();
 }
 
-static std::unique_ptr<BitmapBuffer> ImplCreateDIB(
+static std::optional<BitmapBuffer> ImplCreateDIB(
     const Size& rSize,
     vcl::PixelFormat ePixelFormat,
     const BitmapPalette& rPal,
     bool bClear)
 {
     if (!rSize.Width() || !rSize.Height())
-        return nullptr;
+        return std::nullopt;
 
-    std::unique_ptr<BitmapBuffer> pDIB;
-
-    try
-    {
-        pDIB.reset(new BitmapBuffer);
-    }
-    catch (const std::bad_alloc&)
-    {
-        return nullptr;
-    }
+    std::optional<BitmapBuffer> pDIB(std::in_place);
 
     switch (ePixelFormat)
     {
@@ -92,13 +83,13 @@ static std::unique_ptr<BitmapBuffer> ImplCreateDIB(
     if (bFail)
     {
         SAL_WARN("vcl.gdi", "checked multiply failed");
-        return nullptr;
+        return std::nullopt;
     }
     pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
     if (pDIB->mnScanlineSize < nScanlineBase/8)
     {
         SAL_WARN("vcl.gdi", "scanline calculation wraparound");
-        return nullptr;
+        return std::nullopt;
     }
     pDIB->mnBitCount = vcl::pixelFormatBitCount(ePixelFormat);
 
@@ -113,7 +104,7 @@ static std::unique_ptr<BitmapBuffer> ImplCreateDIB(
     SAL_WARN_IF(bFail, "vcl.gdi", "checked multiply failed");
     if (bFail || size > SAL_MAX_INT32/2)
     {
-        return nullptr;
+        return std::nullopt;
     }
 
     try
@@ -139,18 +130,18 @@ static std::unique_ptr<BitmapBuffer> ImplCreateDIB(
     return pDIB;
 }
 
-void SvpSalBitmap::Create(std::unique_ptr<BitmapBuffer> pBuf)
+void SvpSalBitmap::Create(const std::optional<BitmapBuffer>& pBuf)
 {
     Destroy();
-    mpDIB = std::move(pBuf);
+    moDIB = pBuf;
 }
 
 bool SvpSalBitmap::ImplCreate(const Size& rSize, vcl::PixelFormat ePixelFormat,
                               const BitmapPalette& rPal, bool bClear)
 {
     Destroy();
-    mpDIB = ImplCreateDIB(rSize, ePixelFormat, rPal, bClear);
-    return mpDIB != nullptr;
+    moDIB = ImplCreateDIB(rSize, ePixelFormat, rPal, bClear);
+    return moDIB.has_value();
 }
 
 bool SvpSalBitmap::Create(const Size& rSize, vcl::PixelFormat ePixelFormat, 
const BitmapPalette& rPal)
@@ -164,31 +155,31 @@ bool SvpSalBitmap::Create(const SalBitmap& rBmp)
 
     const SvpSalBitmap& rSalBmp = static_cast<const SvpSalBitmap&>(rBmp);
 
-    if (rSalBmp.mpDIB)
+    if (rSalBmp.moDIB)
     {
         // TODO: reference counting...
-        mpDIB.reset(new BitmapBuffer( *rSalBmp.mpDIB ));
+        moDIB.emplace( *rSalBmp.moDIB );
 
-        const size_t size = mpDIB->mnScanlineSize * mpDIB->mnHeight;
+        const size_t size = moDIB->mnScanlineSize * moDIB->mnHeight;
         if (size > SAL_MAX_INT32/2)
         {
-            mpDIB.reset();
+            moDIB.reset();
             return false;
         }
 
         // TODO: get rid of this when BitmapBuffer gets copy constructor
         try
         {
-            mpDIB->mpBits = new sal_uInt8[size];
-            std::memcpy(mpDIB->mpBits, rSalBmp.mpDIB->mpBits, size);
+            moDIB->mpBits = new sal_uInt8[size];
+            std::memcpy(moDIB->mpBits, rSalBmp.moDIB->mpBits, size);
         }
         catch (const std::bad_alloc&)
         {
-            mpDIB.reset();
+            moDIB.reset();
         }
     }
 
-    return !rSalBmp.mpDIB || (mpDIB != nullptr);
+    return !rSalBmp.moDIB.has_value() || moDIB.has_value();
 }
 
 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
@@ -210,10 +201,10 @@ bool SvpSalBitmap::Create( const css::uno::Reference< 
css::rendering::XBitmapCan
 
 void SvpSalBitmap::Destroy()
 {
-    if (mpDIB)
+    if (moDIB.has_value())
     {
-        delete[] mpDIB->mpBits;
-        mpDIB.reset();
+        delete[] moDIB->mpBits;
+        moDIB.reset();
     }
 }
 
@@ -221,10 +212,10 @@ Size SvpSalBitmap::GetSize() const
 {
     Size aSize;
 
-    if (mpDIB)
+    if (moDIB.has_value())
     {
-        aSize.setWidth( mpDIB->mnWidth );
-        aSize.setHeight( mpDIB->mnHeight );
+        aSize.setWidth( moDIB->mnWidth );
+        aSize.setHeight( moDIB->mnHeight );
     }
 
     return aSize;
@@ -234,8 +225,8 @@ sal_uInt16 SvpSalBitmap::GetBitCount() const
 {
     sal_uInt16 nBitCount;
 
-    if (mpDIB)
-        nBitCount = mpDIB->mnBitCount;
+    if (moDIB.has_value())
+        nBitCount = moDIB->mnBitCount;
     else
         nBitCount = 0;
 
@@ -244,7 +235,7 @@ sal_uInt16 SvpSalBitmap::GetBitCount() const
 
 BitmapBuffer* SvpSalBitmap::AcquireBuffer(BitmapAccessMode)
 {
-    return mpDIB.get();
+    return moDIB ? &*moDIB : nullptr;
 }
 
 void SvpSalBitmap::ReleaseBuffer(BitmapBuffer*, BitmapAccessMode nMode)
diff --git a/vcl/inc/headless/CairoCommon.hxx b/vcl/inc/headless/CairoCommon.hxx
index 1d5cff353c72..13e0398dd679 100644
--- a/vcl/inc/headless/CairoCommon.hxx
+++ b/vcl/inc/headless/CairoCommon.hxx
@@ -106,8 +106,7 @@ VCL_DLLPUBLIC void add_polygon_path(cairo_t* cr, const 
basegfx::B2DPolyPolygon&
 
 VCL_DLLPUBLIC cairo_format_t getCairoFormat(const BitmapBuffer& rBuffer);
 
-VCL_DLLPUBLIC std::unique_ptr<BitmapBuffer>
-FastConvert24BitRgbTo32BitCairo(const BitmapBuffer* pSrc);
+VCL_DLLPUBLIC std::optional<BitmapBuffer> 
FastConvert24BitRgbTo32BitCairo(const BitmapBuffer* pSrc);
 
 enum class PaintMode
 {
diff --git a/vcl/inc/headless/svpbmp.hxx b/vcl/inc/headless/svpbmp.hxx
index b7cfdd2e4f6b..b7fdb230f9cc 100644
--- a/vcl/inc/headless/svpbmp.hxx
+++ b/vcl/inc/headless/svpbmp.hxx
@@ -24,10 +24,11 @@
 
 #include <salbmp.hxx>
 #include <basegfx/utils/systemdependentdata.hxx>
+#include <optional>
 
 class VCL_DLLPUBLIC SvpSalBitmap final : public SalBitmap, public 
basegfx::SystemDependentDataHolder // MM02
 {
-    std::unique_ptr<BitmapBuffer> mpDIB;
+    std::optional<BitmapBuffer> moDIB;
 public:
              SvpSalBitmap();
     virtual ~SvpSalBitmap() override;
@@ -49,10 +50,10 @@ public:
     virtual bool            Create( const css::uno::Reference< 
css::rendering::XBitmapCanvas >& rBitmapCanvas,
                                     Size& rSize,
                                     bool bMask = false ) override;
-    void                    Create(std::unique_ptr<BitmapBuffer> pBuf);
+    void                    Create(const std::optional<BitmapBuffer> & pBuf);
     const BitmapBuffer*     GetBuffer() const
     {
-        return mpDIB.get();
+        return moDIB ? &*moDIB : nullptr;
     }
     virtual void            Destroy() final override;
     virtual Size            GetSize() const override;
diff --git a/vcl/source/gdi/salmisc.cxx b/vcl/source/gdi/salmisc.cxx
index 443718616e48..e8c09ab1d81d 100644
--- a/vcl/source/gdi/salmisc.cxx
+++ b/vcl/source/gdi/salmisc.cxx
@@ -226,13 +226,13 @@ static void ImplTCToPAL( const BitmapBuffer& rSrcBuffer, 
BitmapBuffer const & rD
     }
 }
 
-std::unique_ptr<BitmapBuffer> StretchAndConvert(
+std::optional<BitmapBuffer> StretchAndConvert(
     const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect,
     ScanlineFormat nDstBitmapFormat, std::optional<BitmapPalette> pDstPal, 
const ColorMask* pDstMask )
 {
     FncGetPixel     pFncGetPixel;
     FncSetPixel     pFncSetPixel;
-    std::unique_ptr<BitmapBuffer> pDstBuffer(new BitmapBuffer);
+    std::optional<BitmapBuffer> pDstBuffer(std::in_place);
 
     // set function for getting pixels
     pFncGetPixel = BitmapReadAccess::GetPixelFunction( rSrcBuffer.mnFormat );
@@ -279,14 +279,14 @@ std::unique_ptr<BitmapBuffer> StretchAndConvert(
     {
         SAL_WARN("vcl.gdi", "checked multiply failed");
         pDstBuffer->mpBits = nullptr;
-        return nullptr;
+        return std::nullopt;
     }
     pDstBuffer->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
     if (pDstBuffer->mnScanlineSize < nScanlineBase/8)
     {
         SAL_WARN("vcl.gdi", "scanline calculation wraparound");
         pDstBuffer->mpBits = nullptr;
-        return nullptr;
+        return std::nullopt;
     }
     try
     {
@@ -296,7 +296,7 @@ std::unique_ptr<BitmapBuffer> StretchAndConvert(
     {
         // memory exception, clean up
         pDstBuffer->mpBits = nullptr;
-        return nullptr;
+        return std::nullopt;
     }
 
     // do we need a destination palette or color mask?
@@ -306,7 +306,7 @@ std::unique_ptr<BitmapBuffer> StretchAndConvert(
         assert(pDstPal && "destination buffer requires palette");
         if (!pDstPal)
         {
-            return nullptr;
+            return std::nullopt;
         }
         pDstBuffer->maPalette = *pDstPal;
     }
@@ -315,7 +315,7 @@ std::unique_ptr<BitmapBuffer> StretchAndConvert(
         assert(pDstMask && "destination buffer requires color mask");
         if (!pDstMask)
         {
-            return nullptr;
+            return std::nullopt;
         }
         pDstBuffer->maColorMask = *pDstMask;
     }
@@ -342,7 +342,7 @@ std::unique_ptr<BitmapBuffer> StretchAndConvert(
         // memory exception, clean up
         // remark: the buffer ptr causing the exception
         // is still NULL here
-        return nullptr;
+        return std::nullopt;
     }
 
     // horizontal mapping table
diff --git a/vcl/win/gdi/salbmp.cxx b/vcl/win/gdi/salbmp.cxx
index 26e3537f09eb..71c099e952b6 100644
--- a/vcl/win/gdi/salbmp.cxx
+++ b/vcl/win/gdi/salbmp.cxx
@@ -220,7 +220,7 @@ std::shared_ptr<Gdiplus::Bitmap> 
WinSalBitmap::ImplCreateGdiPlusBitmap()
     }
 
     BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(BitmapAccessMode::Read);
-    std::unique_ptr<BitmapBuffer> pExtraRGB;
+    std::optional<BitmapBuffer> pExtraRGB;
 
     if(pRGB && ScanlineFormat::N24BitTcBgr != RemoveScanline(pRGB->mnFormat))
     {
@@ -232,7 +232,7 @@ std::shared_ptr<Gdiplus::Bitmap> 
WinSalBitmap::ImplCreateGdiPlusBitmap()
             ScanlineFormat::N24BitTcBgr);
 
         pSalRGB->ReleaseBuffer(pRGB, BitmapAccessMode::Write);
-        pRGB = pExtraRGB.get();
+        pRGB = pExtraRGB ? &*pExtraRGB : nullptr;
     }
 
     if(pRGB
@@ -302,7 +302,7 @@ std::shared_ptr<Gdiplus::Bitmap> 
WinSalBitmap::ImplCreateGdiPlusBitmap(const Win
     }
 
     BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(BitmapAccessMode::Read);
-    std::unique_ptr<BitmapBuffer> pExtraRGB;
+    std::optional<BitmapBuffer> pExtraRGB;
 
     if(pRGB && ScanlineFormat::N24BitTcBgr != RemoveScanline(pRGB->mnFormat))
     {
@@ -314,7 +314,7 @@ std::shared_ptr<Gdiplus::Bitmap> 
WinSalBitmap::ImplCreateGdiPlusBitmap(const Win
             ScanlineFormat::N24BitTcBgr);
 
         pSalRGB->ReleaseBuffer(pRGB, BitmapAccessMode::Read);
-        pRGB = pExtraRGB.get();
+        pRGB = pExtraRGB ? &*pExtraRGB : nullptr;
     }
 
     WinSalBitmap* pSalA = const_cast< WinSalBitmap* >(&rAlphaSource);
@@ -329,7 +329,7 @@ std::shared_ptr<Gdiplus::Bitmap> 
WinSalBitmap::ImplCreateGdiPlusBitmap(const Win
     }
 
     BitmapBuffer* pA = pSalA->AcquireBuffer(BitmapAccessMode::Read);
-    std::unique_ptr<BitmapBuffer> pExtraA;
+    std::optional<BitmapBuffer> pExtraA;
 
     if(pA && ScanlineFormat::N8BitPal != RemoveScanline(pA->mnFormat))
     {
@@ -344,7 +344,7 @@ std::shared_ptr<Gdiplus::Bitmap> 
WinSalBitmap::ImplCreateGdiPlusBitmap(const Win
             rTargetPalette);
 
         pSalA->ReleaseBuffer(pA, BitmapAccessMode::Read);
-        pA = pExtraA.get();
+        pA = pExtraA ? &*pExtraA : nullptr;
     }
 
     if(pRGB

Reply via email to