[Libreoffice-commits] core.git: 2 commits - include/vcl vcl/CppunitTest_vcl_png_test.mk vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/qa vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Sat Feb 9 10:58:09 UTC 2019


 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.vajngerl at collabora.co.uk>
AuthorDate: Sat Feb 9 10:04:03 2019 +0100
Commit:     Tomaž Vajngerl <quikee at 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 <quikee at 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.vajngerl at collabora.co.uk>
AuthorDate: Fri Feb 8 21:30:39 2019 +0100
Commit:     Tomaž Vajngerl <quikee at 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 <quikee at 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: */


More information about the Libreoffice-commits mailing list