vcl/source/filter/png/PngImageReader.cxx |   51 ++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 21 deletions(-)

New commits:
commit b9fa913d806aefc7e96be4cff1ffaeb2d3b20fe5
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Tue Apr 13 13:21:26 2021 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Thu Apr 15 21:13:44 2021 +0200

    use the bitmap buffer directly also when reading 32bit png bitmap
    
    Similarly how it's already done for rgb and gray. This saves
    memory and for multi-pass png's it should be also faster to do
    the processing just once at the end.
    This still leaves the split 24+8bpp case, but we'll hopefully
    eventually get rid of it whenever this complicated split stuff
    gets removed.
    
    Change-Id: Ia5e5dcd957d93cff41aa158d9bfcd25fc591e1c7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114162
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/vcl/source/filter/png/PngImageReader.cxx 
b/vcl/source/filter/png/PngImageReader.cxx
index c7ff5a9a8990..4136d9d9aa97 100644
--- a/vcl/source/filter/png/PngImageReader.cxx
+++ b/vcl/source/filter/png/PngImageReader.cxx
@@ -235,34 +235,43 @@ bool reader(SvStream& rStream, BitmapEx& rBitmapEx, bool 
bUseBitmap32)
                         png_set_bgr(pPng);
                     }
 
-                    aRows = std::vector<std::vector<png_byte>>(height);
-                    for (auto& rRow : aRows)
-                        rRow.resize(aRowSizeBytes, 0);
-
-                    auto const alphaFirst = (eFormat == 
ScanlineFormat::N32BitTcAbgr
-                                             || eFormat == 
ScanlineFormat::N32BitTcArgb);
                     for (int pass = 0; pass < nNumberOfPasses; pass++)
                     {
                         for (png_uint_32 y = 0; y < height; y++)
                         {
                             Scanline pScanline = pWriteAccess->GetScanline(y);
-                            png_bytep pRow = aRows[y].data();
-                            png_read_row(pPng, pRow, nullptr);
-                            size_t iColor = 0;
+                            png_read_row(pPng, pScanline, nullptr);
+                        }
+                    }
+                    const vcl::bitmap::lookup_table& premultiply
+                        = vcl::bitmap::get_premultiply_table();
+                    if (eFormat == ScanlineFormat::N32BitTcAbgr
+                        || eFormat == ScanlineFormat::N32BitTcArgb)
+                    { // alpha first and premultiply
+                        for (png_uint_32 y = 0; y < height; y++)
+                        {
+                            Scanline pScanline = pWriteAccess->GetScanline(y);
+                            for (size_t i = 0; i < aRowSizeBytes; i += 4)
+                            {
+                                const sal_uInt8 alpha = pScanline[i + 3];
+                                pScanline[i + 3] = 
premultiply[alpha][pScanline[i + 2]];
+                                pScanline[i + 2] = 
premultiply[alpha][pScanline[i + 1]];
+                                pScanline[i + 1] = 
premultiply[alpha][pScanline[i]];
+                                pScanline[i] = alpha;
+                            }
+                        }
+                    }
+                    else
+                    { // keep alpha last, only premultiply
+                        for (png_uint_32 y = 0; y < height; y++)
+                        {
+                            Scanline pScanline = pWriteAccess->GetScanline(y);
                             for (size_t i = 0; i < aRowSizeBytes; i += 4)
                             {
-                                sal_Int8 alpha = pRow[i + 3];
-                                if (alphaFirst)
-                                {
-                                    pScanline[iColor++] = alpha;
-                                }
-                                pScanline[iColor++] = 
vcl::bitmap::premultiply(pRow[i + 0], alpha);
-                                pScanline[iColor++] = 
vcl::bitmap::premultiply(pRow[i + 1], alpha);
-                                pScanline[iColor++] = 
vcl::bitmap::premultiply(pRow[i + 2], alpha);
-                                if (!alphaFirst)
-                                {
-                                    pScanline[iColor++] = alpha;
-                                }
+                                const sal_uInt8 alpha = pScanline[i + 3];
+                                pScanline[i] = 
premultiply[alpha][pScanline[i]];
+                                pScanline[i + 1] = 
premultiply[alpha][pScanline[i + 1]];
+                                pScanline[i + 2] = 
premultiply[alpha][pScanline[i + 2]];
                             }
                         }
                     }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to