summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2022-05-14 11:42:28 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-05-16 08:08:09 +0200
commit2fe18c214be06065a2966ffa3d4af5db6606b7ae (patch)
treee8591fde99b6c665728a75e23a613a0f0249ee00
parentfc2716740bd513154ae4ab5404d9c575678172e0 (diff)
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.grandin@collabora.co.uk>
-rw-r--r--vcl/source/filter/png/PngImageReader.cxx36
1 files changed, 29 insertions, 7 deletions
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)