summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-04-13 13:21:26 +0200
committerLuboš Luňák <l.lunak@collabora.com>2021-04-15 21:13:44 +0200
commitb9fa913d806aefc7e96be4cff1ffaeb2d3b20fe5 (patch)
treea470630fe53c2782b6c89d8bd0377c0c5f4360b9
parentcb09533c4a007e7cfde69046bcaeb47117d30a86 (diff)
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.lunak@collabora.com>
-rw-r--r--vcl/source/filter/png/PngImageReader.cxx51
1 files changed, 30 insertions, 21 deletions
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]];
}
}
}