vcl/source/filter/png/PngImageReader.cxx |   36 ++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

New commits:
commit 2fe18c214be06065a2966ffa3d4af5db6606b7ae
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Sat May 14 11:42:28 2022 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Mon May 16 08:08:09 2022 +0200

    optimise common case of reading a single-pass PNG
    
    Change-Id: I5408f9d9b7c3e0d08c1bc6bafaca97f18898387f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134342
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/vcl/source/filter/png/PngImageReader.cxx 
b/vcl/source/filter/png/PngImageReader.cxx
index 70ae63240227..6a3053a72e12 100644
--- a/vcl/source/filter/png/PngImageReader.cxx
+++ b/vcl/source/filter/png/PngImageReader.cxx
@@ -100,7 +100,6 @@ bool reader(SvStream& rStream, BitmapEx& rBitmapEx,
     Size prefSize;
     BitmapScopedWriteAccess pWriteAccessInstance;
     AlphaScopedWriteAccess pWriteAccessAlphaInstance;
-    std::vector<std::vector<png_byte>> aRows;
     const bool bFuzzing = utl::ConfigManager::IsFuzzing();
     const bool bSupportsBitmap32 = bFuzzing || 
ImplGetSVData()->mpDefInst->supportsBitmap32();
     const bool bOnlyCreateBitmap
@@ -342,17 +341,15 @@ bool reader(SvStream& rStream, BitmapEx& rBitmapEx,
             if (eFormat == ScanlineFormat::N24BitTcBgr)
                 png_set_bgr(pPng);
 
-            aRows = std::vector<std::vector<png_byte>>(height);
-            for (auto& rRow : aRows)
-                rRow.resize(aRowSizeBytes, 0);
-
-            for (int pass = 0; pass < nNumberOfPasses; pass++)
+            if (nNumberOfPasses == 1)
             {
+                // optimise the common case, where we can use a buffer of only 
a single row
+                std::vector<png_byte> aRow(aRowSizeBytes, 0);
                 for (png_uint_32 y = 0; y < height; y++)
                 {
                     Scanline pScanline = pWriteAccess->GetScanline(y);
                     Scanline pScanAlpha = pWriteAccessAlpha->GetScanline(y);
-                    png_bytep pRow = aRows[y].data();
+                    png_bytep pRow = aRow.data();
                     png_read_row(pPng, pRow, nullptr);
                     size_t iAlpha = 0;
                     size_t iColor = 0;
@@ -365,6 +362,31 @@ bool reader(SvStream& rStream, BitmapEx& rBitmapEx,
                     }
                 }
             }
+            else
+            {
+                std::vector<std::vector<png_byte>> aRows(height);
+                for (auto& rRow : aRows)
+                    rRow.resize(aRowSizeBytes, 0);
+                for (int pass = 0; pass < nNumberOfPasses; pass++)
+                {
+                    for (png_uint_32 y = 0; y < height; y++)
+                    {
+                        Scanline pScanline = pWriteAccess->GetScanline(y);
+                        Scanline pScanAlpha = 
pWriteAccessAlpha->GetScanline(y);
+                        png_bytep pRow = aRows[y].data();
+                        png_read_row(pPng, pRow, nullptr);
+                        size_t iAlpha = 0;
+                        size_t iColor = 0;
+                        for (size_t i = 0; i < aRowSizeBytes; i += 4)
+                        {
+                            pScanline[iColor++] = pRow[i + 0];
+                            pScanline[iColor++] = pRow[i + 1];
+                            pScanline[iColor++] = pRow[i + 2];
+                            pScanAlpha[iAlpha++] = 0xFF - pRow[i + 3];
+                        }
+                    }
+                }
+            }
         }
     }
     else if (colorType == PNG_COLOR_TYPE_GRAY)

Reply via email to