include/vcl/bitmap.hxx       |    1 
 vcl/source/bitmap/bitmap.cxx |  110 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 109 insertions(+), 2 deletions(-)

New commits:
commit 7f33bccce7be3e71dbbad07a7c2c04abd0b1647c
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Sun May 4 23:18:39 2025 +0200
Commit:     Noel Grandin <noelgran...@gmail.com>
CommitDate: Mon May 5 08:00:17 2025 +0200

    improve the bitmap->alpha conversion
    
    we do not need to go via this complex luminance calculation, we
    just want the red channel of the RGB data.
    
    This is also what the skia backends do, ever since
        commit 2fcfbd73768b69ba58607a054e7f851be2942992
        Author: Luboš Luňák <l.lu...@collabora.com>
        Date:   Fri Apr 3 22:50:12 2020 +0200
        no gray conversion needed for VCL alpha hacks
    
    Change-Id: Ie4a7adcc7c488d241ec58e64a130da544c3d39d0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184944
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Jenkins

diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index ca13e2cc1a69..cfb2c1a95caa 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -580,6 +580,7 @@ public:
     SAL_DLLPRIVATE void     ImplSetSalBitmap( const 
std::shared_ptr<SalBitmap>& xImpBmp );
 
     SAL_DLLPRIVATE bool     ImplMakeGreyscales();
+    SAL_DLLPRIVATE bool     ImplMake8BitNoConversion();
 
 private:
     SAL_DLLPRIVATE bool ImplConvertUp(vcl::PixelFormat ePixelFormat, Color 
const* pExtColor = nullptr);
diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx
index 8d38e3b889c0..cca49e45b3ea 100644
--- a/vcl/source/bitmap/bitmap.cxx
+++ b/vcl/source/bitmap/bitmap.cxx
@@ -861,10 +861,13 @@ bool Bitmap::Convert( BmpConversion eConversion )
         break;
 
         case BmpConversion::N8BitGreys:
-        case BmpConversion::N8BitNoConversion:
             bRet = ImplMakeGreyscales();
         break;
 
+        case BmpConversion::N8BitNoConversion:
+            bRet = ImplMake8BitNoConversion();
+        break;
+
         case BmpConversion::N8BitColors:
         {
             if( nBitCount < 8 )
@@ -1016,7 +1019,110 @@ bool Bitmap::ImplMakeGreyscales()
     return true;
 }
 
-bool Bitmap::ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const * 
pExtColor)
+// Used for the bitmap->alpha layer conversion, just takes the red channel
+bool Bitmap::ImplMake8BitNoConversion()
+{
+    BitmapScopedReadAccess pReadAcc(*this);
+    if (!pReadAcc)
+        return false;
+
+    const BitmapPalette& rPal = GetGreyPalette(256);
+    bool bPalDiffers
+        = !pReadAcc->HasPalette() || (rPal.GetEntryCount() != 
pReadAcc->GetPaletteEntryCount());
+
+    if (!bPalDiffers)
+        bPalDiffers = (rPal != pReadAcc->GetPalette());
+    if (!bPalDiffers)
+        return true;
+
+    const auto ePixelFormat = vcl::PixelFormat::N8_BPP;
+    Bitmap aNewBmp(GetSizePixel(), ePixelFormat, &rPal);
+    BitmapScopedWriteAccess pWriteAcc(aNewBmp);
+    if (!pWriteAcc)
+        return false;
+
+    const tools::Long nWidth = pWriteAcc->Width();
+    const tools::Long nHeight = pWriteAcc->Height();
+
+    if (pReadAcc->HasPalette())
+    {
+        for (tools::Long nY = 0; nY < nHeight; nY++)
+        {
+            Scanline pScanline = pWriteAcc->GetScanline(nY);
+            Scanline pScanlineRead = pReadAcc->GetScanline(nY);
+            for (tools::Long nX = 0; nX < nWidth; nX++)
+            {
+                const sal_uInt8 cIndex = 
pReadAcc->GetIndexFromData(pScanlineRead, nX);
+                pWriteAcc->SetPixelOnData(
+                    pScanline, nX,
+                    BitmapColor(pReadAcc->GetPaletteColor(cIndex).GetRed()));
+            }
+        }
+    }
+    else if (pReadAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcBgr
+             && pWriteAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal)
+    {
+        for (tools::Long nY = 0; nY < nHeight; nY++)
+        {
+            Scanline pReadScan = pReadAcc->GetScanline(nY);
+            Scanline pWriteScan = pWriteAcc->GetScanline(nY);
+
+            for (tools::Long nX = 0; nX < nWidth; nX++)
+            {
+                pReadScan++;
+                pReadScan++;
+                const sal_uLong nR = *pReadScan++;
+
+                *pWriteScan++ = static_cast<sal_uInt8>(nR);
+            }
+        }
+    }
+    else if (pReadAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcRgb
+             && pWriteAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal)
+    {
+        for (tools::Long nY = 0; nY < nHeight; nY++)
+        {
+            Scanline pReadScan = pReadAcc->GetScanline(nY);
+            Scanline pWriteScan = pWriteAcc->GetScanline(nY);
+
+            for (tools::Long nX = 0; nX < nWidth; nX++)
+            {
+                const sal_uLong nR = *pReadScan++;
+                pReadScan++;
+                pReadScan++;
+
+                *pWriteScan++ = static_cast<sal_uInt8>(nR);
+            }
+        }
+    }
+    else
+    {
+        for (tools::Long nY = 0; nY < nHeight; nY++)
+        {
+            Scanline pScanline = pWriteAcc->GetScanline(nY);
+            Scanline pScanlineRead = pReadAcc->GetScanline(nY);
+            for (tools::Long nX = 0; nX < nWidth; nX++)
+                pWriteAcc->SetPixelOnData(
+                    pScanline, nX,
+                    BitmapColor(pReadAcc->GetPixelFromData(pScanlineRead, 
nX).GetRed()));
+        }
+    }
+
+    pWriteAcc.reset();
+    pReadAcc.reset();
+
+    const MapMode aMap(maPrefMapMode);
+    const Size aSize(maPrefSize);
+
+    *this = std::move(aNewBmp);
+
+    maPrefMapMode = aMap;
+    maPrefSize = aSize;
+
+    return true;
+}
+
+bool Bitmap::ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const* 
pExtColor)
 {
     SAL_WARN_IF(ePixelFormat <= getPixelFormat(), "vcl", "New pixel format 
must be greater!" );
 

Reply via email to