summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-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]];
}
}
}