vcl/source/filter/png/PngImageReader.cxx | 42 ++++++++----------------------- 1 file changed, 12 insertions(+), 30 deletions(-)
New commits: commit 329465f19d7800c87f641565cd7e5a69f0a63d47 Author: Caolán McNamara <caolan.mcnam...@collabora.com> AuthorDate: Thu Sep 11 09:34:44 2025 +0100 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Thu Sep 11 16:03:13 2025 +0200 ofz#438873386 pngfuzzer Out-of-memory we can skip the intermediate buffer now and use the bitmap data itself as the buffer. Change-Id: Ifea467ca16ffb5a6f5b1b88dfb08f9a0426168f9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190797 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/vcl/source/filter/png/PngImageReader.cxx b/vcl/source/filter/png/PngImageReader.cxx index f89e3cc6db12..b0312c72610a 100644 --- a/vcl/source/filter/png/PngImageReader.cxx +++ b/vcl/source/filter/png/PngImageReader.cxx @@ -515,44 +515,26 @@ bool reader(SvStream& rStream, ImportOutput& rImportOutput, { size_t aRowSizeBytes = png_get_rowbytes(pPng, pInfo); - if (nNumberOfPasses == 1) + // Reuse the bitmap data as a buffer for reading the png data. The + // order is possibly incorrect from what it should finally be and + // in any case the result is not premultiplied. + for (int pass = 0; pass < nNumberOfPasses; pass++) { - // 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); - png_bytep pRow = aRow.data(); - png_read_row(pPng, pRow, nullptr); - for (size_t i = 0; i < aRowSizeBytes; i += 4) - { - Color aCol(ColorAlpha, pRow[i + 3], pRow[i + 0], pRow[i + 1], pRow[i + 2]); - pWriteAccess->SetPixelOnData(pScanline, i / 4, aCol); - } + png_read_row(pPng, pScanline, nullptr); } } - else + // Fix order and do premultiplication + for (png_uint_32 y = 0; y < height; y++) { - 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++) - { - png_bytep pRow = aRows[y].data(); - png_read_row(pPng, pRow, nullptr); - } - } - for (png_uint_32 y = 0; y < height; y++) + Scanline pScanline = pWriteAccess->GetScanline(y); + for (size_t i = 0; i < aRowSizeBytes; i += 4) { - Scanline pScanline = pWriteAccess->GetScanline(y); - png_bytep pRow = aRows[y].data(); - for (size_t i = 0; i < aRowSizeBytes; i += 4) - { - Color aCol(ColorAlpha, pRow[i + 3], pRow[i + 0], pRow[i + 1], pRow[i + 2]); - pWriteAccess->SetPixelOnData(pScanline, i / 4, aCol); - } + Color aCol(ColorAlpha, pScanline[i + 3], pScanline[i + 0], pScanline[i + 1], + pScanline[i + 2]); + pWriteAccess->SetPixelOnData(pScanline, i / 4, aCol); } } }