diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-04-13 13:21:26 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-04-15 21:13:44 +0200 |
commit | b9fa913d806aefc7e96be4cff1ffaeb2d3b20fe5 (patch) | |
tree | a470630fe53c2782b6c89d8bd0377c0c5f4360b9 /vcl | |
parent | cb09533c4a007e7cfde69046bcaeb47117d30a86 (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>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/filter/png/PngImageReader.cxx | 51 |
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]]; } } } |