include/vcl/filter/PngImageReader.hxx | 39 ++++ vcl/CppunitTest_vcl_png_test.mk | 52 +++++ vcl/Library_vcl.mk | 2 vcl/Module_vcl.mk | 1 vcl/qa/cppunit/png/PngFilterTest.cxx | 155 ++++++++++++++++ vcl/qa/cppunit/png/data/alpha-rect-8bit-RGBA.png |binary vcl/qa/cppunit/png/data/color-rect-4bit-pal.png |binary vcl/qa/cppunit/png/data/color-rect-8bit-RGB.png |binary vcl/qa/cppunit/png/data/rect-1bit-pal.png |binary vcl/source/filter/png/PngImageReader.cxx | 214 +++++++++++++++++++++++ vcl/source/image/ImplImageTree.cxx | 14 - 11 files changed, 469 insertions(+), 8 deletions(-)
New commits: commit bec35535b4cb784800a79cd315b4f761d0a6758e Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Sat Feb 9 10:04:03 2019 +0100 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Sat Feb 9 11:57:55 2019 +0100 Use PngImageReader for loading the icons from the icon-themes Change-Id: Id48c7707fd6c0ef72a41b102048be5749d5c4858 Reviewed-on: https://gerrit.libreoffice.org/67578 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/source/image/ImplImageTree.cxx b/vcl/source/image/ImplImageTree.cxx index c24d3e4221eb..9b9cfab2fc16 100644 --- a/vcl/source/image/ImplImageTree.cxx +++ b/vcl/source/image/ImplImageTree.cxx @@ -44,13 +44,13 @@ #include <vcl/bitmapex.hxx> #include <vcl/dibtools.hxx> -#include <vcl/pngread.hxx> #include <vcl/settings.hxx> #include <vcl/svapp.hxx> #include <vcl/BitmapTools.hxx> #include <vcl/IconThemeScanner.hxx> -#include <vcl/pngwrite.hxx> +#include <vcl/filter/PngImageReader.hxx> #include <vcl/outdev.hxx> +#include <vcl/pngwrite.hxx> #include <BitmapLightenFilter.hxx> @@ -158,9 +158,8 @@ void loadImageFromStream(std::shared_ptr<SvStream> const & xStream, OUString con if (rPath.endsWith(".png")) { - vcl::PNGReader aPNGReader(*xStream); - aPNGReader.SetIgnoreGammaChunk(true); - rParameters.mrBitmap = aPNGReader.Read(); + vcl::PngImageReader aPNGReader(*xStream); + aPNGReader.read(rParameters.mrBitmap); } else if (rPath.endsWith(".svg")) { @@ -362,9 +361,8 @@ bool loadDiskCachedVersion(OUString const & sVariant, ImageRequestParameters& rP if (!urlExists(sUrl)) return false; SvFileStream aFileStream(sUrl, StreamMode::READ); - vcl::PNGReader aPNGReader(aFileStream); - aPNGReader.SetIgnoreGammaChunk(true); - rParameters.mrBitmap = aPNGReader.Read(); + vcl::PngImageReader aPNGReader(aFileStream); + aPNGReader.read(rParameters.mrBitmap); return true; } commit 34a6e8443312c5f9aa0a1bb055fac50d722a90ff Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Fri Feb 8 21:30:39 2019 +0100 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Sat Feb 9 11:57:48 2019 +0100 add PngImageFilter that uses libpng for PNG loading This adds loading of PNG images that uses libpng instead of our own solution. It always loaded the image as either RGB or RGBA image and if the source PNG is using something else, libpng converts to either RGB or RGBA. In addition this adds tests for loading of various PNG files to make sure the resulting bitmaps are using pixel data as expected. (especially needed to check the RGBA bitmaps) Change-Id: I194321caf76c2ec2365bb6075c79c5e84983658a Reviewed-on: https://gerrit.libreoffice.org/67571 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/include/vcl/filter/PngImageReader.hxx b/include/vcl/filter/PngImageReader.hxx new file mode 100644 index 000000000000..f555939a4836 --- /dev/null +++ b/include/vcl/filter/PngImageReader.hxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <vcl/graph.hxx> +#include <vcl/dllapi.h> +#include <com/sun/star/task/XStatusIndicator.hpp> +#include <tools/stream.hxx> +#include <vcl/bitmapex.hxx> + +#ifndef INCLUDED_VCL_SOURCE_FILTER_PNG_PNGIMAGEREADER_HXX +#define INCLUDED_VCL_SOURCE_FILTER_PNG_PNGIMAGEREADER_HXX + +namespace vcl +{ +class VCL_DLLPUBLIC PngImageReader +{ + SvStream& mrStream; + css::uno::Reference<css::task::XStatusIndicator> mxStatusIndicator; + +public: + PngImageReader(SvStream& rStream); + + virtual ~PngImageReader() {} + + bool read(BitmapEx& rBitmap); +}; + +} // namespace vcl + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/CppunitTest_vcl_png_test.mk b/vcl/CppunitTest_vcl_png_test.mk new file mode 100644 index 000000000000..1f88209313a0 --- /dev/null +++ b/vcl/CppunitTest_vcl_png_test.mk @@ -0,0 +1,52 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,vcl_png_test)) + +$(eval $(call gb_CppunitTest_add_exception_objects,vcl_png_test, \ + vcl/qa/cppunit/png/PngFilterTest \ +)) + +$(eval $(call gb_CppunitTest_set_include,vcl_png_test,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,vcl_png_test, \ + comphelper \ + cppu \ + cppuhelper \ + sal \ + svt \ + test \ + tl \ + unotest \ + vcl \ + utl \ + $(gb_UWINAPI) \ +)) + +$(eval $(call gb_CppunitTest_use_api,vcl_png_test,\ + udkapi \ + offapi \ +)) + +$(eval $(call gb_CppunitTest_use_ure,vcl_png_test)) +$(eval $(call gb_CppunitTest_use_vcl,vcl_png_test)) + +$(eval $(call gb_CppunitTest_use_components,vcl_png_test,\ + configmgr/source/configmgr \ + i18npool/util/i18npool \ + ucb/source/core/ucb1 \ + unotools/util/utl \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,vcl_png_test)) + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 31e677b9e37d..0178ffc809df 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -66,6 +66,7 @@ $(eval $(call gb_Library_use_custom_headers,vcl,\ $(eval $(call gb_Library_use_externals,vcl,\ libjpeg \ libeot \ + libpng \ $(if $(filter PDFIUM,$(BUILD_TYPE)),pdfium) \ )) @@ -407,6 +408,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/filter/wmf/wmf \ vcl/source/filter/wmf/wmfexternal \ vcl/source/filter/wmf/wmfwr \ + vcl/source/filter/png/PngImageReader \ vcl/source/font/Feature \ vcl/source/font/FeatureCollector \ vcl/source/font/FeatureParser \ diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index 95dd579c38de..14e3eacf1bf5 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -205,6 +205,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\ CppunitTest_vcl_errorhandler \ CppunitTest_vcl_bitmap_render_test \ CppunitTest_vcl_apitests \ + CppunitTest_vcl_png_test \ )) ifneq (,$(filter PDFIUM,$(BUILD_TYPE))) diff --git a/vcl/qa/cppunit/png/PngFilterTest.cxx b/vcl/qa/cppunit/png/PngFilterTest.cxx new file mode 100644 index 000000000000..1a9dd0a4cead --- /dev/null +++ b/vcl/qa/cppunit/png/PngFilterTest.cxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <test/bootstrapfixture.hxx> +#include <vcl/filter/PngImageReader.hxx> +#include <vcl/bitmapaccess.hxx> +#include <vcl/alpha.hxx> + +using namespace css; + +class PngFilterTest : public test::BootstrapFixture +{ + OUString maDataUrl; + + OUString getFullUrl(const OUString& sFileName) + { + return m_directories.getURLFromSrc(maDataUrl) + sFileName; + } + +public: + PngFilterTest() + : BootstrapFixture(true, false) + , maDataUrl("/vcl/qa/cppunit/png/data/") + { + } + + void testPng(); + + CPPUNIT_TEST_SUITE(PngFilterTest); + CPPUNIT_TEST(testPng); + CPPUNIT_TEST_SUITE_END(); +}; + +void PngFilterTest::testPng() +{ + for (const OUString& aFileName : { OUString("rect-1bit-pal.png") }) + { + SvFileStream aFileStream(getFullUrl(aFileName), StreamMode::READ); + + vcl::PngImageReader aPngReader(aFileStream); + BitmapEx aBitmapEx; + aPngReader.read(aBitmapEx); + + Bitmap aBitmap = aBitmapEx.GetBitmap(); + { + Bitmap::ScopedReadAccess pAccess(aBitmap); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(24), pAccess->GetBitCount()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Width()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Height()); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(0, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(3, 3)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(3, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(0, 3)); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x00, 0x00), pAccess->GetPixel(1, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x00, 0x00), pAccess->GetPixel(1, 2)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x00, 0x00), pAccess->GetPixel(2, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x00, 0x00), pAccess->GetPixel(2, 2)); + } + } + for (const OUString& aFileName : + { OUString("color-rect-8bit-RGB.png"), OUString("color-rect-4bit-pal.png") }) + { + SvFileStream aFileStream(getFullUrl(aFileName), StreamMode::READ); + + vcl::PngImageReader aPngReader(aFileStream); + BitmapEx aBitmapEx; + aPngReader.read(aBitmapEx); + + Bitmap aBitmap = aBitmapEx.GetBitmap(); + { + Bitmap::ScopedReadAccess pAccess(aBitmap); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(24), pAccess->GetBitCount()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Width()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Height()); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(0, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(3, 3)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(3, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(0, 3)); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0x00, 0x00, 0x00), pAccess->GetPixel(1, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0xFF, 0x00, 0x00), pAccess->GetPixel(1, 2)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0xFF, 0x00), pAccess->GetPixel(2, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0x00, 0x00), pAccess->GetPixel(2, 2)); + } + } + for (const OUString& aFileName : { OUString("alpha-rect-8bit-RGBA.png") }) + { + SvFileStream aFileStream(getFullUrl(aFileName), StreamMode::READ); + + vcl::PngImageReader aPngReader(aFileStream); + BitmapEx aBitmapEx; + aPngReader.read(aBitmapEx); + + Bitmap aBitmap = aBitmapEx.GetBitmap(); + { + Bitmap::ScopedReadAccess pAccess(aBitmap); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(24), pAccess->GetBitCount()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Width()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Height()); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(0, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(3, 3)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(3, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0xFF, 0x00), pAccess->GetPixel(0, 3)); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0x00, 0x00, 0x00), pAccess->GetPixel(1, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0xFF, 0x00, 0x00), pAccess->GetPixel(1, 2)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0xFF, 0x00), pAccess->GetPixel(2, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0xFF, 0xFF, 0x00, 0x00), pAccess->GetPixel(2, 2)); + } + AlphaMask aAlpha = aBitmapEx.GetAlpha(); + { + AlphaMask::ScopedReadAccess pAccess(aAlpha); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), pAccess->GetBitCount()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Width()); + CPPUNIT_ASSERT_EQUAL(4L, pAccess->Height()); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x80, 0x00), pAccess->GetPixel(0, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x80, 0x00), pAccess->GetPixel(3, 3)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x80, 0x00), pAccess->GetPixel(3, 0)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x80, 0x00), pAccess->GetPixel(0, 3)); + + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x40, 0x00), pAccess->GetPixel(1, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0xC0, 0x00), pAccess->GetPixel(1, 2)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0xC0, 0x00), pAccess->GetPixel(2, 1)); + CPPUNIT_ASSERT_EQUAL(BitmapColor(0x00, 0x00, 0x40, 0x00), pAccess->GetPixel(2, 2)); + } + } + // CPPUNIT_ASSERT(false); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(PngFilterTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qa/cppunit/png/data/alpha-rect-8bit-RGBA.png b/vcl/qa/cppunit/png/data/alpha-rect-8bit-RGBA.png new file mode 100644 index 000000000000..1e90e1a6cfed Binary files /dev/null and b/vcl/qa/cppunit/png/data/alpha-rect-8bit-RGBA.png differ diff --git a/vcl/qa/cppunit/png/data/color-rect-4bit-pal.png b/vcl/qa/cppunit/png/data/color-rect-4bit-pal.png new file mode 100644 index 000000000000..740eede512d1 Binary files /dev/null and b/vcl/qa/cppunit/png/data/color-rect-4bit-pal.png differ diff --git a/vcl/qa/cppunit/png/data/color-rect-8bit-RGB.png b/vcl/qa/cppunit/png/data/color-rect-8bit-RGB.png new file mode 100644 index 000000000000..727859d8a7c1 Binary files /dev/null and b/vcl/qa/cppunit/png/data/color-rect-8bit-RGB.png differ diff --git a/vcl/qa/cppunit/png/data/rect-1bit-pal.png b/vcl/qa/cppunit/png/data/rect-1bit-pal.png new file mode 100644 index 000000000000..cf7ac3e7c31b Binary files /dev/null and b/vcl/qa/cppunit/png/data/rect-1bit-pal.png differ diff --git a/vcl/source/filter/png/PngImageReader.cxx b/vcl/source/filter/png/PngImageReader.cxx new file mode 100644 index 000000000000..790336654714 --- /dev/null +++ b/vcl/source/filter/png/PngImageReader.cxx @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <vcl/filter/PngImageReader.hxx> +#include <png.h> +#include <vcl/bitmapaccess.hxx> +#include <bitmapwriteaccess.hxx> +#include <vcl/bitmap.hxx> +#include <vcl/alpha.hxx> + +namespace +{ +void lclReadStream(png_structp pPng, png_bytep pOutBytes, png_size_t nBytesToRead) +{ + png_voidp pIO = png_get_io_ptr(pPng); + + if (pIO == nullptr) + return; + + SvStream* pStream = static_cast<SvStream*>(pIO); + + sal_Size nBytesRead = pStream->ReadBytes(pOutBytes, nBytesToRead); + + if (nBytesRead != nBytesToRead) + png_error(pPng, "Error reading"); +} + +bool reader(SvStream& rStream, BitmapEx& rBitmapEx) +{ + enum + { + PNG_SIGNATURE_SIZE = 8 + }; + + sal_uInt8 aHeader[PNG_SIGNATURE_SIZE]; + rStream.ReadBytes(aHeader, PNG_SIGNATURE_SIZE); + + if (png_sig_cmp(aHeader, 0, PNG_SIGNATURE_SIZE)) + return false; + + png_structp pPng = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (!pPng) + return false; + + png_infop pInfo = png_create_info_struct(pPng); + if (!pInfo) + { + png_destroy_read_struct(&pPng, nullptr, nullptr); + return false; + } + + if (setjmp(png_jmpbuf(pPng))) + { + png_destroy_read_struct(&pPng, &pInfo, nullptr); + return false; + } + + png_set_read_fn(pPng, &rStream, lclReadStream); + + png_set_crc_action(pPng, PNG_CRC_WARN_USE, PNG_CRC_WARN_DISCARD); + + png_set_sig_bytes(pPng, PNG_SIGNATURE_SIZE); + + png_read_info(pPng, pInfo); + + png_uint_32 width = 0; + png_uint_32 height = 0; + int bitDepth = 0; + int colorType = -1; + int interlace = -1; + + png_uint_32 returnValue = png_get_IHDR(pPng, pInfo, &width, &height, &bitDepth, &colorType, + &interlace, nullptr, nullptr); + + if (returnValue != 1) + { + png_destroy_read_struct(&pPng, &pInfo, nullptr); + return false; + } + + Bitmap aBitmap(Size(width, height), 24); + AlphaMask aBitmapAlpha(Size(width, height), nullptr); + + png_set_bgr(pPng); + + if (colorType == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(pPng); + + if (colorType == PNG_COLOR_TYPE_GRAY) + png_set_expand_gray_1_2_4_to_8(pPng); + + if (png_get_valid(pPng, pInfo, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(pPng); + + if (bitDepth == 16) + png_set_scale_16(pPng); + + if (bitDepth < 8) + png_set_packing(pPng); + + if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) + { + png_set_gray_to_rgb(pPng); + } + + // Sets the filler byte - if RGB it converts to RGBA + // png_set_filler(pPng, 0xFF, PNG_FILLER_AFTER); + + int nNumberOfPasses = png_set_interlace_handling(pPng); + + png_read_update_info(pPng, pInfo); + returnValue = png_get_IHDR(pPng, pInfo, &width, &height, &bitDepth, &colorType, nullptr, + nullptr, nullptr); + + if (returnValue != 1) + { + png_destroy_read_struct(&pPng, &pInfo, nullptr); + return false; + } + + if (bitDepth != 8 + || !(colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA)) + { + png_destroy_read_struct(&pPng, &pInfo, nullptr); + return false; + } + + { + if (colorType == PNG_COLOR_TYPE_RGB) + { + size_t aRowSizeBytes = png_get_rowbytes(pPng, pInfo); + + BitmapScopedWriteAccess pWriteAccess(aBitmap); + + std::vector<png_byte> aRow(aRowSizeBytes, 0); + + for (int pass = 0; pass < nNumberOfPasses; pass++) + { + for (png_uint_32 y = 0; y < height; y++) + { + Scanline pScanline = pWriteAccess->GetScanline(y); + png_bytep pRow = aRow.data(); + png_read_rows(pPng, &pRow, nullptr, 1); + size_t iColor = 0; + for (size_t i = 0; i < aRowSizeBytes; i += 3) + { + pScanline[iColor++] = pRow[i + 0]; + pScanline[iColor++] = pRow[i + 1]; + pScanline[iColor++] = pRow[i + 2]; + } + } + } + } + else if (colorType == PNG_COLOR_TYPE_RGB_ALPHA) + { + size_t aRowSizeBytes = png_get_rowbytes(pPng, pInfo); + + BitmapScopedWriteAccess pWriteAccess(aBitmap); + AlphaScopedWriteAccess pWriteAccessAlpha(aBitmapAlpha); + + std::vector<png_byte> aRow(aRowSizeBytes, 0); + + for (int pass = 0; pass < nNumberOfPasses; pass++) + { + for (png_uint_32 y = 0; y < height; y++) + { + Scanline pScanAlpha = pWriteAccessAlpha->GetScanline(y); + Scanline pScanline = pWriteAccess->GetScanline(y); + png_bytep pRow = aRow.data(); + png_read_rows(pPng, &pRow, nullptr, 1); + 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]; + } + } + } + } + } + + png_read_end(pPng, pInfo); + + png_destroy_read_struct(&pPng, &pInfo, nullptr); + + rBitmapEx = BitmapEx(aBitmap, aBitmapAlpha); + + return true; +} + +} // anonymous namespace + +namespace vcl +{ +PngImageReader::PngImageReader(SvStream& rStream) + : mrStream(rStream) +{ +} + +bool PngImageReader::read(BitmapEx& rBitmapEx) { return reader(mrStream, rBitmapEx); } + +} // namespace vcl + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits