Commit 5602fef5 authored by Leon Scroggins III's avatar Leon Scroggins III Committed by Commit Bot

Update libpng to 1.6.34

Bug: 761608
Bug: 771075

Downloaded from http://libpng.download/src/libpng16

https://github.com/glennrp/libpng/commit/edef058e180be435afd8feebb742a22360a7fa3f
(included in this revision) moved the SSE opts directly into the main
libpng source, so contrib/intel/intel_sse.patch is no longer necessary,
as its changes are already included.

Other changes:
- README.chromium:
  - Update version number.
  - Remove references to cherry-picks from upstream, as the fixes are
    now included without cherry-picks.
  - Remove reference to applying intel_sse.patch, which is no longer
    necessary.
- BUILD.gn:
  - Build the intel code from its new location.
- PNGImageDecoderTest.cpp:
  - Remove unnecessary tests. TestFailureDuringDecode attempted to
    modify a valid PNG file to have an error, and then verified that it
    actually had an error, while leaving the FrameCount unchanged. I do
    not see much value to the test, and the apparently more lenient
    newer libpng no longer considers this modified file to be broken.

Change-Id: I2c7e517403609aed2051b91df47dd9f87f62e1ab
Reviewed-on: https://chromium-review.googlesource.com/671029Reviewed-by: default avatarLeon Scroggins <scroggo@chromium.org>
Reviewed-by: default avatarMike Klein <mtklein@chromium.org>
Commit-Queue: Leon Scroggins <scroggo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#506749}
parent fe862f37
...@@ -258,36 +258,6 @@ void TestProgressiveDecodingContinuesAfterFullData( ...@@ -258,36 +258,6 @@ void TestProgressiveDecodingContinuesAfterFullData(
EXPECT_EQ(hash_full, hash_upfront); EXPECT_EQ(hash_full, hash_upfront);
} }
// Modify the frame data bytes for frame |frame_index| so that decoding fails.
// Parsing should work fine, and is checked with |expected_frame_count|.
void TestFailureDuringDecode(const char* file,
size_t idat_offset,
size_t frame_index,
size_t expected_frame_count) {
RefPtr<SharedBuffer> full_data = ReadFile(file);
ASSERT_FALSE(full_data->IsEmpty());
// This is the offset where the frame data chunk frame |frame_index| starts.
RefPtr<SharedBuffer> data =
SharedBuffer::Create(full_data->Data(), idat_offset + 8u);
// Repeat the first 8 bytes of the frame data. This should result in a
// successful parse, since frame data is not analyzed in that step, but
// should give an error during decoding.
data->Append(full_data->Data() + idat_offset, 8u);
data->Append(full_data->Data() + idat_offset + 16u,
full_data->size() - idat_offset - 16u);
auto decoder = CreatePNGDecoder();
decoder->SetData(data.get(), true);
EXPECT_EQ(expected_frame_count, decoder->FrameCount());
decoder->DecodeFrameBufferAtIndex(frame_index);
ASSERT_EQ(true, decoder->Failed());
EXPECT_EQ(expected_frame_count, decoder->FrameCount());
}
} // Anonymous namespace } // Anonymous namespace
// Animated PNG Tests // Animated PNG Tests
...@@ -699,23 +669,6 @@ TEST(AnimatedPNGTests, FailureMissingIendChunk) { ...@@ -699,23 +669,6 @@ TEST(AnimatedPNGTests, FailureMissingIendChunk) {
EXPECT_TRUE(decoder->Failed()); EXPECT_TRUE(decoder->Failed());
} }
TEST(AnimatedPNGTests, FailureDuringDecodingInvalidatesDecoder) {
TestFailureDuringDecode(
"/LayoutTests/images/resources/"
"png-animated-idat-part-of-animation.png",
291u, // fdat offset for frame index 2, plus 12 to move past sequence
// number.
2u, // try to decode frame index 2
4u); // expected frame count before failure
TestFailureDuringDecode(
"/LayoutTests/images/resources/"
"png-animated-idat-part-of-animation.png",
133u, // idat offset for frame index 0
0u, // try to decode frame index 0
4u); // expected frame count before failure
}
// Verify that a malformatted PNG, where the IEND appears before any frame data // Verify that a malformatted PNG, where the IEND appears before any frame data
// (IDAT), invalidates the decoder. // (IDAT), invalidates the decoder.
TEST(AnimatedPNGTests, VerifyIENDBeforeIDATInvalidatesDecoder) { TEST(AnimatedPNGTests, VerifyIENDBeforeIDATInvalidatesDecoder) {
...@@ -976,13 +929,6 @@ TEST(StaticPNGTests, ProgressiveDecodingContinuesAfterFullData) { ...@@ -976,13 +929,6 @@ TEST(StaticPNGTests, ProgressiveDecodingContinuesAfterFullData) {
"/LayoutTests/images/resources/png-simple.png", 1000u); "/LayoutTests/images/resources/png-simple.png", 1000u);
} }
TEST(StaticPNGTests, FailureDuringDecodingInvalidatesDecoder) {
TestFailureDuringDecode("/LayoutTests/images/resources/png-simple.png",
85u, // idat offset for frame index 0
0u, // try to decode frame index 0
1u); // expected frame count before failure
}
TEST(PNGTests, VerifyFrameCompleteBehavior) { TEST(PNGTests, VerifyFrameCompleteBehavior) {
struct { struct {
const char* name; const char* name;
......
...@@ -66,8 +66,8 @@ source_set("libpng_sources") { ...@@ -66,8 +66,8 @@ source_set("libpng_sources") {
if (current_cpu == "x86" || current_cpu == "x64") { if (current_cpu == "x86" || current_cpu == "x64") {
sources += [ sources += [
"contrib/intel/filter_sse2_intrinsics.c", "intel/filter_sse2_intrinsics.c",
"contrib/intel/intel_init.c", "intel/intel_init.c",
] ]
defines += [ "PNG_INTEL_SSE_OPT=1" ] defines += [ "PNG_INTEL_SSE_OPT=1" ]
} else if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon) { } else if ((current_cpu == "arm" || current_cpu == "arm64") && arm_use_neon) {
......
...@@ -12,8 +12,8 @@ Using custom versions of pnglibconf.h and pngprefix.h for Chrome. ...@@ -12,8 +12,8 @@ Using custom versions of pnglibconf.h and pngprefix.h for Chrome.
This code is released under the libpng license. This code is released under the libpng license.
libpng versions 1.0.7, July 1, 2000 through 1.6.22, May 26, 2016 are libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
derived from libpng-1.0.6, and are distributed according to the same derived from libpng-1.0.6, and are distributed according to the same
disclaimer and license as libpng-1.0.6 with the following individuals disclaimer and license as libpng-1.0.6 with the following individuals
added to the list of Contributing Authors: added to the list of Contributing Authors:
...@@ -24,6 +24,9 @@ added to the list of Contributing Authors: ...@@ -24,6 +24,9 @@ added to the list of Contributing Authors:
Cosmin Truta Cosmin Truta
Gilles Vollant Gilles Vollant
James Yu James Yu
Mandar Sahastrabuddhe
Google Inc.
Vadim Barkov
and with the following additions to the disclaimer: and with the following additions to the disclaimer:
...@@ -129,4 +132,4 @@ any encryption software. See the EAR, paragraphs 734.3(b)(3) and ...@@ -129,4 +132,4 @@ any encryption software. See the EAR, paragraphs 734.3(b)(3) and
Glenn Randers-Pehrson Glenn Randers-Pehrson
glennrp at users.sourceforge.net glennrp at users.sourceforge.net
May 26, 2016 September 29, 2017
README for libpng version 1.6.22 - May 26, 2016 (shared library 16.0) README for libpng version 1.6.34 - September 29, 2017 (shared library 16.0)
See the note about version numbers near the top of png.h See the note about version numbers near the top of png.h
See INSTALL for instructions on how to install libpng. See INSTALL for instructions on how to install libpng.
...@@ -23,7 +23,7 @@ earlier versions if you are using a shared library. The type of the ...@@ -23,7 +23,7 @@ earlier versions if you are using a shared library. The type of the
png_uint_32, which will affect shared-library applications that use png_uint_32, which will affect shared-library applications that use
this function. this function.
To avoid problems with changes to the internals of png info_struct, To avoid problems with changes to the internals of the png info_struct,
new APIs have been made available in 0.95 to avoid direct application new APIs have been made available in 0.95 to avoid direct application
access to info_ptr. These functions are the png_set_<chunk> and access to info_ptr. These functions are the png_set_<chunk> and
png_get_<chunk> functions. These functions should be used when png_get_<chunk> functions. These functions should be used when
...@@ -88,11 +88,11 @@ zlib should be available at the same place that libpng is, or at zlib.net. ...@@ -88,11 +88,11 @@ zlib should be available at the same place that libpng is, or at zlib.net.
You may also want a copy of the PNG specification. It is available You may also want a copy of the PNG specification. It is available
as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find
these at http://www.libpng.org/pub/png/documents/ these at http://www.libpng.org/pub/png/pngdocs.html .
This code is currently being archived at libpng.sf.net in the This code is currently being archived at libpng.sourceforge.io in the
[DOWNLOAD] area, and at ftp://ftp.simplesystems.org. If you can't find it [DOWNLOAD] area, and at http://libpng.download/src . If you
in any of those places, e-mail me, and I'll help you find it. can't find it in any of those places, e-mail me, and I'll help you find it.
I am not a lawyer, but I believe that the Export Control Classification I am not a lawyer, but I believe that the Export Control Classification
Number (ECCN) for libpng is EAR99, which means not subject to export Number (ECCN) for libpng is EAR99, which means not subject to export
...@@ -179,18 +179,25 @@ Files in this distribution: ...@@ -179,18 +179,25 @@ Files in this distribution:
pngwtran.c => Write data transformations pngwtran.c => Write data transformations
pngwutil.c => Write utility functions pngwutil.c => Write utility functions
arm => Contains optimized code for the ARM platform arm => Contains optimized code for the ARM platform
powerpc => Contains optimized code for the PowerPC platform
contrib => Contributions contrib => Contributions
arm-neon => Optimized code for ARM-NEON platform
powerpc-vsx => Optimized code for POWERPC-VSX platform
examples => Example programs examples => Example programs
gregbook => source code for PNG reading and writing, from gregbook => source code for PNG reading and writing, from
Greg Roelofs' "PNG: The Definitive Guide", Greg Roelofs' "PNG: The Definitive Guide",
O'Reilly, 1999 O'Reilly, 1999
libtests => Test programs libtests => Test programs
mips-msa => Optimized code for MIPS-MSA platform
pngminim => Minimal decoder, encoder, and progressive decoder pngminim => Minimal decoder, encoder, and progressive decoder
programs demonstrating use of pngusr.dfa programs demonstrating use of pngusr.dfa
pngminus => Simple pnm2png and png2pnm programs pngminus => Simple pnm2png and png2pnm programs
pngsuite => Test images pngsuite => Test images
testpngs
tools => Various tools tools => Various tools
visupng => Contains a MSVC workspace for VisualPng visupng => Contains a MSVC workspace for VisualPng
intel => Optimized code for INTEL-SSE2 platform
mips => Optimized code for MIPS platform
projects => Contains project files and workspaces for projects => Contains project files and workspaces for
building a DLL building a DLL
owatcom => Contains a WATCOM project for building libpng owatcom => Contains a WATCOM project for building libpng
......
Name: libpng Name: libpng
URL: http://libpng.org/ URL: http://libpng.org/
Version: 1.6.22 Version: 1.6.34
Security Critical: yes Security Critical: yes
License: libpng license License: libpng license
License Android Compatible: yes License Android Compatible: yes
Description: Description:
Updated to 1.6.22, stripped all unneeded files. Updated to 1.6.34, stripped all unneeded files.
- Turn on SSE optimizations for Intel platforms by running:
"patch -i contrib/intel/intel_sse.patch -p1"
- Use custom configuration file pnglibconf.h, which turns off all features that - Use custom configuration file pnglibconf.h, which turns off all features that
are not in use. are not in use.
- Use custom prefix file pngprefix.h, which avoids namespace conflicts with - Use custom prefix file pngprefix.h, which avoids namespace conflicts with
pdfium's copy of libpng. pdfium's copy of libpng.
- Configures custom png chunk user limits (crbug.com/117369) in pnglibconf.h. - Configures custom png chunk user limits (crbug.com/117369) in pnglibconf.h.
- Fix for potential memory leak from upstream:
https://github.com/glennrp/libpng/commit/8d1672537324d99c6e65eb78fc1678cdd46f75bd
https://github.com/glennrp/libpng/commit/6c7459e455a4f7d95c7700e9326bb12396e6eb1f
- Fix for handling empty first IDAT chunk from upstream:
https://github.com/glennrp/libpng/commit/3f46c67c6989f480bd932428aa1705f6625dbabf
https://github.com/glennrp/libpng/commit/81f0273d54aa9de663253b197b3c8228d659cc36
- Fix performance regression in png encoding (and overflow handling in filter heuristic)
from upstream (crbug.com/619850):
https://github.com/glennrp/libpng/commit/9c04f57cabbf736e91b831858d0eeecca703eabf
https://github.com/glennrp/libpng/commit/f7d5419816d85d0b996c403e788bb707b552524f
- Avoid leaking params on bad pCAL chunk from upstream (crbug.com/636214):
https://github.com/glennrp/libpng/commit/7dc03292502cf91a116766d2ab2c4f8fc23e4ab4
- Fix for large allocation for invalid ICC (crbug.com/729673)
https://github.com/glennrp/libpng/commit/92a7c79db2c962d04006b35e2603ba9d5ce75541
/* filter_neon.S - NEON optimised filter functions /* filter_neon.S - NEON optimised filter functions
* *
* Copyright (c) 2014 Glenn Randers-Pehrson * Copyright (c) 2014,2017 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011. * Written by Mans Rullgard, 2011.
* Last changed in libpng 1.6.16 [December 22, 2014] * Last changed in libpng 1.6.31 [July 27, 2017]
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define PNG_VERSION_INFO_ONLY #define PNG_VERSION_INFO_ONLY
#include "../pngpriv.h" #include "../pngpriv.h"
#if defined(__linux__) && defined(__ELF__) #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
#endif #endif
......
Enabling SSE support
Copyright (c) 2016 Google, Inc.
Written by Mike Klein, Matt Sarett
This INSTALL file written by Glenn Randers-Pehrson, 2016.
If you have moved intel_init.c and filter_sse2_intrinsics.c to a different
directory, be sure to update the '#include "../../pngpriv.h"' line in both
files if necessary to point to the correct relative location of pngpriv.h
with respect to the new location of those files.
To enable SSE support in libpng, follow the instructions in I, II, or III,
below:
I. Using patched "configure" scripts:
First, apply intel_sse.patch in your build directory.
patch -i contrib/intel/intel_sse.patch -p1
Then, if you are not building in a new GIT clone, e.g., in a tar
distribution, remove any existing pre-built configure scripts:
./configure --enable-maintainer-mode
make maintainer-clean
./autogen.sh --maintainer --clean
Finally, configure libpng with -DPNG_INTEL_SSE in CPPFLAGS:
./autogen.sh --maintainer
CPPFLAGS="-DPNG_INTEL_SSE" ./configure [options]
make CPPFLAGS="-DPNG_INTEL_SSE" [options]
make
II. Using a custom makefile:
If you are using a custom makefile makefile, you will have to update it
manually to include contrib/intel/*.o in the dependencies, and to define
PNG_INTEL_SSE.
III. Using manually updated "configure" scripts:
If you prefer, manually edit pngpriv.h, configure.ac, and Makefile.am,
following the instructions below, then follow the instructions in
section II of INSTALL in the main libpng directory, then configure libpng
with -DPNG_INTEL_SSE in CPPFLAGS.
1. Add the following code to configure.ac under HOST SPECIFIC OPTIONS
directly beneath the section for ARM:
-----------------cut----------------
# INTEL
# =====
#
# INTEL SSE (SIMD) support.
AC_ARG_ENABLE([intel-sse],
AS_HELP_STRING([[[--enable-intel-sse]]],
[Enable Intel SSE optimizations: =no/off, yes/on:]
[no/off: disable the optimizations;]
[yes/on: enable the optimizations.]
[If not specified: determined by the compiler.]),
[case "$enableval" in
no|off)
# disable the default enabling:
AC_DEFINE([PNG_INTEL_SSE_OPT], [0],
[Disable Intel SSE optimizations])
# Prevent inclusion of the assembler files below:
enable_intel_sse=no;;
yes|on)
AC_DEFINE([PNG_INTEL_SSE_OPT], [1],
[Enable Intel SSE optimizations]);;
*)
AC_MSG_ERROR([--enable-intel-sse=${enable_intel_sse}: invalid value])
esac])
# Add Intel specific files to all builds where the host_cpu is Intel ('x86*')
# or where Intel optimizations were explicitly requested (this allows a
# fallback if a future host CPU does not match 'x86*')
AM_CONDITIONAL([PNG_INTEL_SSE],
[test "$enable_intel_sse" != 'no' &&
case "$host_cpu" in
i?86|x86_64) :;;
*) test "$enable_intel_sse" != '';;
esac])
-----------------cut----------------
2. Add the following code to Makefile.am under HOST SPECIFIC OPTIONS
directly beneath the "if PNG_ARM_NEON ... endif" statement:
-----------------cut----------------
if PNG_INTEL_SSE
libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += contrib/intel/intel_init.c\
contrib/intel/filter_sse2_intrinsics.c
endif
-----------------cut----------------
3. Add the following lines to pngpriv.h, following the PNG_ARM_NEON_OPT
code:
-----------------cut----------------
#ifndef PNG_INTEL_SSE_OPT
# ifdef PNG_INTEL_SSE
/* Only check for SSE if the build configuration has been modified to
* enable SSE optimizations. This means that these optimizations will
* be off by default. See contrib/intel for more details.
*/
# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
(defined(_M_IX86_FP) && _M_IX86_FP >= 2)
# define PNG_INTEL_SSE_OPT 1
# endif
# endif
#endif
#if PNG_INTEL_SSE_OPT > 0
# ifndef PNG_INTEL_SSE_IMPLEMENTATION
# if defined(__SSE4_1__) || defined(__AVX__)
/* We are not actually using AVX, but checking for AVX is the best
way we can detect SSE4.1 and SSSE3 on MSVC.
*/
# define PNG_INTEL_SSE_IMPLEMENTATION 3
# elif defined(__SSSE3__)
# define PNG_INTEL_SSE_IMPLEMENTATION 2
# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
(defined(_M_IX86_FP) && _M_IX86_FP >= 2)
# define PNG_INTEL_SSE_IMPLEMENTATION 1
# else
# define PNG_INTEL_SSE_IMPLEMENTATION 0
# endif
# endif
# if PNG_INTEL_SSE_IMPLEMENTATION > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
# endif
#endif
-----------------cut----------------
4. Add the following lines to pngpriv.h, following the prototype for
png_read_filter_row_paeth4_neon:
-----------------cut----------------
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
-----------------cut----------------
diff --git libpng-1.6.22-orig/configure.ac libpng-1.6.22/configure.ac
--- libpng-1.6.22-orig/configure.ac 2016-05-25 18:59:10.000000000 -0400
+++ libpng-1.6.22/configure.ac 2016-05-25 19:48:10.631751170 -0400
@@ -341,16 +341,50 @@ AC_ARG_ENABLE([arm-neon],
AM_CONDITIONAL([PNG_ARM_NEON],
[test "$enable_arm_neon" != 'no' &&
case "$host_cpu" in
arm*|aarch64*) :;;
*) test "$enable_arm_neon" != '';;
esac])
+# INTEL
+# =====
+#
+# INTEL SSE (SIMD) support.
+
+AC_ARG_ENABLE([intel-sse],
+ AS_HELP_STRING([[[--enable-intel-sse]]],
+ [Enable Intel SSE optimizations: =no/off, yes/on:]
+ [no/off: disable the optimizations;]
+ [yes/on: enable the optimizations.]
+ [If not specified: determined by the compiler.]),
+ [case "$enableval" in
+ no|off)
+ # disable the default enabling:
+ AC_DEFINE([PNG_INTEL_SSE_OPT], [0],
+ [Disable Intel SSE optimizations])
+ # Prevent inclusion of the assembler files below:
+ enable_intel_sse=no;;
+ yes|on)
+ AC_DEFINE([PNG_INTEL_SSE_OPT], [1],
+ [Enable Intel SSE optimizations]);;
+ *)
+ AC_MSG_ERROR([--enable-intel-sse=${enable_intel_sse}: invalid value])
+ esac])
+
+# Add Intel specific files to all builds where the host_cpu is Intel ('x86*')
+# or where Intel optimizations were explicitly requested (this allows a
+# fallback if a future host CPU does not match 'x86*')
+AM_CONDITIONAL([PNG_INTEL_SSE],
+ [test "$enable_intel_sse" != 'no' &&
+ case "$host_cpu" in
+ i?86|x86_64) :;;
+ *) test "$enable_intel_sse" != '';;
+ esac])
AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]])
# Config files, substituting as above
AC_CONFIG_FILES([Makefile libpng.pc:libpng.pc.in])
AC_CONFIG_FILES([libpng-config:libpng-config.in],
[chmod +x libpng-config])
AC_OUTPUT
diff --git libpng-1.6.22-orig/Makefile.am libpng-1.6.22/Makefile.am
--- libpng-1.6.22-orig/Makefile.am 2016-05-17 18:15:12.000000000 -0400
+++ libpng-1.6.22/Makefile.am 2016-05-25 19:48:10.631751170 -0400
@@ -89,16 +89,20 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SO
pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c\
png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h pngusr.dfa
if PNG_ARM_NEON
libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += arm/arm_init.c\
arm/filter_neon.S arm/filter_neon_intrinsics.c
endif
+if PNG_INTEL_SSE
+libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += contrib/intel/intel_init.c\
+ contrib/intel/filter_sse2_intrinsics.c
+endif
nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h
libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined -export-dynamic \
-version-number @PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0
if HAVE_LD_VERSION_SCRIPT
# Versioned symbols and restricted exports
if HAVE_SOLARIS_LD
diff --git libpng-1.6.22-orig/pngpriv.h libpng-1.6.22/pngpriv.h
--- libpng-1.6.22-orig/pngpriv.h 2016-05-25 18:59:10.000000000 -0400
+++ libpng-1.6.22/pngpriv.h 2016-05-25 19:48:10.635751171 -0400
@@ -177,16 +177,52 @@
# endif /* !PNG_ARM_NEON_IMPLEMENTATION */
# ifndef PNG_ARM_NEON_IMPLEMENTATION
/* Use the intrinsics code by default. */
# define PNG_ARM_NEON_IMPLEMENTATION 1
# endif
#endif /* PNG_ARM_NEON_OPT > 0 */
+#ifndef PNG_INTEL_SSE_OPT
+# ifdef PNG_INTEL_SSE
+ /* Only check for SSE if the build configuration has been modified to
+ * enable SSE optimizations. This means that these optimizations will
+ * be off by default. See contrib/intel for more details.
+ */
+# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
+ defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
+ (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
+# define PNG_INTEL_SSE_OPT 1
+# endif
+# endif
+#endif
+
+#if PNG_INTEL_SSE_OPT > 0
+# ifndef PNG_INTEL_SSE_IMPLEMENTATION
+# if defined(__SSE4_1__) || defined(__AVX__)
+ /* We are not actually using AVX, but checking for AVX is the best
+ way we can detect SSE4.1 and SSSE3 on MSVC.
+ */
+# define PNG_INTEL_SSE_IMPLEMENTATION 3
+# elif defined(__SSSE3__)
+# define PNG_INTEL_SSE_IMPLEMENTATION 2
+# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
+ (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
+# define PNG_INTEL_SSE_IMPLEMENTATION 1
+# else
+# define PNG_INTEL_SSE_IMPLEMENTATION 0
+# endif
+# endif
+
+# if PNG_INTEL_SSE_IMPLEMENTATION > 0
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
+# endif
+#endif
+
/* Is this a build of a DLL where compilation of the object modules requires
* different preprocessor settings to those required for a simple library? If
* so PNG_BUILD_DLL must be set.
*
* If libpng is used inside a DLL but that DLL does not export the libpng APIs
* PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a
* static library of libpng then link the DLL against that.
*/
@@ -1184,16 +1220,29 @@ PNG_INTERNAL_FUNCTION(void,png_read_filt
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+
/* Choose the best filter to use and filter the row data */
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
png_row_infop row_info),PNG_EMPTY);
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
/* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer
/* intel_init.c - SSE2 optimized filter functions /* intel_init.c - SSE2 optimized filter functions
* *
* Copyright (c) 2016 Google, Inc. * Copyright (c) 2016-2017 Glenn Randers-Pehrson
* Written by Mike Klein and Matt Sarett * Written by Mike Klein and Matt Sarett, Google, Inc.
* Derived from arm/arm_init.c, which was * Derived from arm/arm_init.c
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
* *
* Last changed in libpng 1.6.22 [May 26, 2016] * Last changed in libpng 1.6.29 [March 16, 2017]
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
* and license in png.h * and license in png.h
*/ */
#include "../../pngpriv.h" #include "../pngpriv.h"
#ifdef PNG_READ_SUPPORTED #ifdef PNG_READ_SUPPORTED
#if PNG_INTEL_SSE_IMPLEMENTATION > 0 #if PNG_INTEL_SSE_IMPLEMENTATION > 0
......
This diff is collapsed.
This diff is collapsed.
/* pngconf.h - machine configurable file for libpng /* pngconf.h - machine configurable file for libpng
* *
* libpng version 1.6.22, May 26, 2016 * libpng version 1.6.34, September 29, 2017
* *
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -188,27 +188,27 @@ ...@@ -188,27 +188,27 @@
* compatible with GCC or Visual C because of different calling conventions. * compatible with GCC or Visual C because of different calling conventions.
*/ */
# if PNG_API_RULE == 2 # if PNG_API_RULE == 2
/* If this line results in an error, either because __watcall is not /* If this line results in an error, either because __watcall is not
* understood or because of a redefine just below you cannot use *this* * understood or because of a redefine just below you cannot use *this*
* build of the library with the compiler you are using. *This* build was * build of the library with the compiler you are using. *This* build was
* build using Watcom and applications must also be built using Watcom! * build using Watcom and applications must also be built using Watcom!
*/ */
# define PNGCAPI __watcall # define PNGCAPI __watcall
# endif # endif
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) # if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl # define PNGCAPI __cdecl
# if PNG_API_RULE == 1 # if PNG_API_RULE == 1
/* If this line results in an error __stdcall is not understood and /* If this line results in an error __stdcall is not understood and
* PNG_API_RULE should not have been set to '1'. * PNG_API_RULE should not have been set to '1'.
*/ */
# define PNGAPI __stdcall # define PNGAPI __stdcall
# endif # endif
# else # else
/* An older compiler, or one not detected (erroneously) above, /* An older compiler, or one not detected (erroneously) above,
* if necessary override on the command line to get the correct * if necessary override on the command line to get the correct
* variants for the compiler. * variants for the compiler.
*/ */
# ifndef PNGCAPI # ifndef PNGCAPI
# define PNGCAPI _cdecl # define PNGCAPI _cdecl
# endif # endif
...@@ -225,10 +225,10 @@ ...@@ -225,10 +225,10 @@
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ # if (defined(_MSC_VER) && _MSC_VER < 800) ||\
(defined(__BORLANDC__) && __BORLANDC__ < 0x500) (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
/* older Borland and MSC /* older Borland and MSC
* compilers used '__export' and required this to be after * compilers used '__export' and required this to be after
* the type. * the type.
*/ */
# ifndef PNG_EXPORT_TYPE # ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP # define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# endif # endif
...@@ -244,9 +244,9 @@ ...@@ -244,9 +244,9 @@
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System # define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */ # else /* !Windows/x86 && !OS/2 */
/* Use the defaults, or define PNG*API on the command line (but /* Use the defaults, or define PNG*API on the command line (but
* this will have to be done for every compile!) * this will have to be done for every compile!)
*/ */
# endif /* other system, !OS/2 */ # endif /* other system, !OS/2 */
#endif /* !Windows/x86 */ #endif /* !Windows/x86 */
...@@ -267,7 +267,7 @@ ...@@ -267,7 +267,7 @@
*/ */
#ifndef PNG_IMPEXP #ifndef PNG_IMPEXP
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) # if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
/* This forces use of a DLL, disallowing static linking */ /* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT # define PNG_IMPEXP PNG_DLL_IMPORT
# endif # endif
...@@ -340,7 +340,7 @@ ...@@ -340,7 +340,7 @@
* less efficient code. * less efficient code.
*/ */
# if defined(__clang__) && defined(__has_attribute) # if defined(__clang__) && defined(__has_attribute)
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) # if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) # define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif # endif
...@@ -507,9 +507,9 @@ ...@@ -507,9 +507,9 @@
# error "libpng requires a signed 32-bit (or more) type" # error "libpng requires a signed 32-bit (or more) type"
#endif #endif
#if UINT_MAX > 4294967294 #if UINT_MAX > 4294967294U
typedef unsigned int png_uint_32; typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294 #elif ULONG_MAX > 4294967294U
typedef unsigned long int png_uint_32; typedef unsigned long int png_uint_32;
#else #else
# error "libpng requires an unsigned 32-bit (or more) type" # error "libpng requires an unsigned 32-bit (or more) type"
......
/* pngerror.c - stub functions for i/o and memory allocation /* pngerror.c - stub functions for i/o and memory allocation
* *
* Last changed in libpng 1.6.15 [November 20, 2014] * Last changed in libpng 1.6.31 [July 27, 2017]
* Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -26,7 +26,7 @@ static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr, ...@@ -26,7 +26,7 @@ static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
#ifdef PNG_WARNINGS_SUPPORTED #ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */ static void /* PRIVATE */
png_default_warning PNGARG((png_const_structrp png_ptr, png_default_warning PNGARG((png_const_structrp png_ptr,
png_const_charp warning_message)); png_const_charp warning_message));
#endif /* WARNINGS */ #endif /* WARNINGS */
/* This function is called whenever there is a fatal error. This function /* This function is called whenever there is a fatal error. This function
...@@ -37,7 +37,7 @@ png_default_warning PNGARG((png_const_structrp png_ptr, ...@@ -37,7 +37,7 @@ png_default_warning PNGARG((png_const_structrp png_ptr,
#ifdef PNG_ERROR_TEXT_SUPPORTED #ifdef PNG_ERROR_TEXT_SUPPORTED
PNG_FUNCTION(void,PNGAPI PNG_FUNCTION(void,PNGAPI
png_error,(png_const_structrp png_ptr, png_const_charp error_message), png_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16]; char msg[16];
...@@ -65,18 +65,18 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message), ...@@ -65,18 +65,18 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message),
else else
error_message += offset; error_message += offset;
} }
else else
{
if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
{ {
msg[0] = '0'; if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
msg[1] = '\0'; {
error_message = msg; msg[0] = '0';
msg[1] = '\0';
error_message = msg;
}
} }
} }
}
} }
#endif #endif
if (png_ptr != NULL && png_ptr->error_fn != NULL) if (png_ptr != NULL && png_ptr->error_fn != NULL)
...@@ -110,7 +110,7 @@ png_err,(png_const_structrp png_ptr),PNG_NORETURN) ...@@ -110,7 +110,7 @@ png_err,(png_const_structrp png_ptr),PNG_NORETURN)
*/ */
size_t size_t
png_safecat(png_charp buffer, size_t bufsize, size_t pos, png_safecat(png_charp buffer, size_t bufsize, size_t pos,
png_const_charp string) png_const_charp string)
{ {
if (buffer != NULL && pos < bufsize) if (buffer != NULL && pos < bufsize)
{ {
...@@ -131,7 +131,7 @@ png_safecat(png_charp buffer, size_t bufsize, size_t pos, ...@@ -131,7 +131,7 @@ png_safecat(png_charp buffer, size_t bufsize, size_t pos,
*/ */
png_charp png_charp
png_format_number(png_const_charp start, png_charp end, int format, png_format_number(png_const_charp start, png_charp end, int format,
png_alloc_size_t number) png_alloc_size_t number)
{ {
int count = 0; /* number of digits output */ int count = 0; /* number of digits output */
int mincount = 1; /* minimum number required */ int mincount = 1; /* minimum number required */
...@@ -163,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format, ...@@ -163,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02u: case PNG_NUMBER_FORMAT_02u:
/* Expects at least 2 digits. */ /* Expects at least 2 digits. */
mincount = 2; mincount = 2;
/* FALL THROUGH */ /* FALLTHROUGH */
case PNG_NUMBER_FORMAT_u: case PNG_NUMBER_FORMAT_u:
*--end = digits[number % 10]; *--end = digits[number % 10];
...@@ -173,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format, ...@@ -173,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02x: case PNG_NUMBER_FORMAT_02x:
/* This format expects at least two digits */ /* This format expects at least two digits */
mincount = 2; mincount = 2;
/* FALL THROUGH */ /* FALLTHROUGH */
case PNG_NUMBER_FORMAT_x: case PNG_NUMBER_FORMAT_x:
*--end = digits[number & 0xf]; *--end = digits[number & 0xf];
...@@ -233,7 +233,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message) ...@@ -233,7 +233,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
} }
if (png_ptr != NULL && png_ptr->warning_fn != NULL) if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
warning_message + offset); warning_message + offset);
else else
png_default_warning(png_ptr, warning_message + offset); png_default_warning(png_ptr, warning_message + offset);
} }
...@@ -245,7 +245,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message) ...@@ -245,7 +245,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
*/ */
void void
png_warning_parameter(png_warning_parameters p, int number, png_warning_parameter(png_warning_parameters p, int number,
png_const_charp string) png_const_charp string)
{ {
if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
(void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
...@@ -253,7 +253,7 @@ png_warning_parameter(png_warning_parameters p, int number, ...@@ -253,7 +253,7 @@ png_warning_parameter(png_warning_parameters p, int number,
void void
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
png_alloc_size_t value) png_alloc_size_t value)
{ {
char buffer[PNG_NUMBER_BUFFER_SIZE]; char buffer[PNG_NUMBER_BUFFER_SIZE];
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
...@@ -261,7 +261,7 @@ png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, ...@@ -261,7 +261,7 @@ png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
void void
png_warning_parameter_signed(png_warning_parameters p, int number, int format, png_warning_parameter_signed(png_warning_parameters p, int number, int format,
png_int_32 value) png_int_32 value)
{ {
png_alloc_size_t u; png_alloc_size_t u;
png_charp str; png_charp str;
...@@ -282,7 +282,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format, ...@@ -282,7 +282,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
void void
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
png_const_charp message) png_const_charp message)
{ {
/* The internal buffer is just 192 bytes - enough for all our messages, /* The internal buffer is just 192 bytes - enough for all our messages,
* overflow doesn't happen because this code checks! If someone figures * overflow doesn't happen because this code checks! If someone figures
...@@ -391,10 +391,10 @@ png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) ...@@ -391,10 +391,10 @@ png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
void /* PRIVATE */ void /* PRIVATE */
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
{ {
if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
png_warning(png_ptr, error_message); png_warning(png_ptr, error_message);
else else
png_error(png_ptr, error_message); png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED # ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message) PNG_UNUSED(error_message)
...@@ -404,10 +404,10 @@ png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) ...@@ -404,10 +404,10 @@ png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
void /* PRIVATE */ void /* PRIVATE */
png_app_error(png_const_structrp png_ptr, png_const_charp error_message) png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
{ {
if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
png_warning(png_ptr, error_message); png_warning(png_ptr, error_message);
else else
png_error(png_ptr, error_message); png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED # ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message) PNG_UNUSED(error_message)
...@@ -478,7 +478,7 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp ...@@ -478,7 +478,7 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
PNG_FUNCTION(void,PNGAPI PNG_FUNCTION(void,PNGAPI
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
char msg[18+PNG_MAX_ERROR_TEXT]; char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL) if (png_ptr == NULL)
...@@ -573,7 +573,7 @@ png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) ...@@ -573,7 +573,7 @@ png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
{ {
# define fixed_message "fixed point overflow in " # define fixed_message "fixed point overflow in "
# define fixed_message_ln ((sizeof fixed_message)-1) # define fixed_message_ln ((sizeof fixed_message)-1)
int iin; unsigned int iin;
char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
memcpy(msg, fixed_message, fixed_message_ln); memcpy(msg, fixed_message, fixed_message_ln);
iin = 0; iin = 0;
...@@ -620,7 +620,7 @@ png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, ...@@ -620,7 +620,7 @@ png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
else else
{ {
png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
png_malloc_warn(png_ptr, jmp_buf_size)); png_malloc_warn(png_ptr, jmp_buf_size));
if (png_ptr->jmp_buf_ptr == NULL) if (png_ptr->jmp_buf_ptr == NULL)
return NULL; /* new NULL return on OOM */ return NULL; /* new NULL return on OOM */
...@@ -709,7 +709,7 @@ png_free_jmpbuf(png_structrp png_ptr) ...@@ -709,7 +709,7 @@ png_free_jmpbuf(png_structrp png_ptr)
*/ */
static PNG_FUNCTION(void /* PRIVATE */, static PNG_FUNCTION(void /* PRIVATE */,
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
#ifdef PNG_CONSOLE_IO_SUPPORTED #ifdef PNG_CONSOLE_IO_SUPPORTED
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
...@@ -883,7 +883,7 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) ...@@ -883,7 +883,7 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
*/ */
PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
const png_const_structrp png_ptr = png_nonconst_ptr; const png_const_structrp png_ptr = png_nonconst_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
...@@ -906,7 +906,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), ...@@ -906,7 +906,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
/* Missing longjmp buffer, the following is to help debugging: */ /* Missing longjmp buffer, the following is to help debugging: */
{ {
size_t pos = png_safecat(image->message, (sizeof image->message), 0, size_t pos = png_safecat(image->message, (sizeof image->message), 0,
"bad longjmp: "); "bad longjmp: ");
png_safecat(image->message, (sizeof image->message), pos, png_safecat(image->message, (sizeof image->message), pos,
error_message); error_message);
} }
......
/* pngget.c - retrieval of values from info struct /* pngget.c - retrieval of values from info struct
* *
* Last changed in libpng 1.6.17 [March 26, 2015] * Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -338,7 +338,7 @@ ppi_from_ppm(png_uint_32 ppm) ...@@ -338,7 +338,7 @@ ppi_from_ppm(png_uint_32 ppm)
png_fixed_point result; png_fixed_point result;
if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
5000) != 0) 5000) != 0)
return result; return (png_uint_32)result;
/* Overflow. */ /* Overflow. */
return 0; return 0;
...@@ -486,7 +486,7 @@ png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) ...@@ -486,7 +486,7 @@ png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
#ifdef PNG_bKGD_SUPPORTED #ifdef PNG_bKGD_SUPPORTED
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
png_color_16p *background) png_color_16p *background)
{ {
if (png_ptr != NULL && info_ptr != NULL && if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_bKGD) != 0 && (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
...@@ -526,28 +526,28 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, ...@@ -526,28 +526,28 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (white_x != NULL) if (white_x != NULL)
*white_x = png_float(png_ptr, *white_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
if (white_y != NULL) if (white_y != NULL)
*white_y = png_float(png_ptr, *white_y = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
if (red_x != NULL) if (red_x != NULL)
*red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
"cHRM red X"); "cHRM red X");
if (red_y != NULL) if (red_y != NULL)
*red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
"cHRM red Y"); "cHRM red Y");
if (green_x != NULL) if (green_x != NULL)
*green_x = png_float(png_ptr, *green_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
if (green_y != NULL) if (green_y != NULL)
*green_y = png_float(png_ptr, *green_y = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
if (blue_x != NULL) if (blue_x != NULL)
*blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
"cHRM blue X"); "cHRM blue X");
if (blue_y != NULL) if (blue_y != NULL)
*blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
"cHRM blue Y"); "cHRM blue Y");
return (PNG_INFO_cHRM); return (PNG_INFO_cHRM);
} }
...@@ -556,42 +556,42 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, ...@@ -556,42 +556,42 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
double *red_X, double *red_Y, double *red_Z, double *green_X, double *red_X, double *red_Y, double *red_Z, double *green_X,
double *green_Y, double *green_Z, double *blue_X, double *blue_Y, double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
double *blue_Z) double *blue_Z)
{ {
if (png_ptr != NULL && info_ptr != NULL && if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{ {
png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
if (red_X != NULL) if (red_X != NULL)
*red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
"cHRM red X"); "cHRM red X");
if (red_Y != NULL) if (red_Y != NULL)
*red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
"cHRM red Y"); "cHRM red Y");
if (red_Z != NULL) if (red_Z != NULL)
*red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
"cHRM red Z"); "cHRM red Z");
if (green_X != NULL) if (green_X != NULL)
*green_X = png_float(png_ptr, *green_X = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
if (green_Y != NULL) if (green_Y != NULL)
*green_Y = png_float(png_ptr, *green_Y = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
if (green_Z != NULL) if (green_Z != NULL)
*green_Z = png_float(png_ptr, *green_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
if (blue_X != NULL) if (blue_X != NULL)
*blue_X = png_float(png_ptr, *blue_X = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
if (blue_Y != NULL) if (blue_Y != NULL)
*blue_Y = png_float(png_ptr, *blue_Y = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
if (blue_Z != NULL) if (blue_Z != NULL)
*blue_Z = png_float(png_ptr, *blue_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
return (PNG_INFO_cHRM); return (PNG_INFO_cHRM);
} }
...@@ -681,8 +681,8 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, ...@@ -681,8 +681,8 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_debug1(1, "in %s retrieval function", "gAMA"); png_debug1(1, "in %s retrieval function", "gAMA");
if (png_ptr != NULL && info_ptr != NULL && if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
file_gamma != NULL) file_gamma != NULL)
{ {
*file_gamma = info_ptr->colorspace.gamma; *file_gamma = info_ptr->colorspace.gamma;
return (PNG_INFO_gAMA); return (PNG_INFO_gAMA);
...@@ -704,7 +704,7 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, ...@@ -704,7 +704,7 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
file_gamma != NULL) file_gamma != NULL)
{ {
*file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
"png_get_gAMA"); "png_get_gAMA");
return (PNG_INFO_gAMA); return (PNG_INFO_gAMA);
} }
...@@ -773,6 +773,35 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, ...@@ -773,6 +773,35 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
} }
#endif #endif
#ifdef PNG_eXIf_SUPPORTED
png_uint_32 PNGAPI
png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytep *exif)
{
png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
PNG_UNUSED(info_ptr)
PNG_UNUSED(exif)
return 0;
}
png_uint_32 PNGAPI
png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_uint_32 *num_exif, png_bytep *exif)
{
png_debug1(1, "in %s retrieval function", "eXIf");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
{
*num_exif = info_ptr->num_exif;
*exif = info_ptr->exif;
return (PNG_INFO_eXIf);
}
return (0);
}
#endif
#ifdef PNG_hIST_SUPPORTED #ifdef PNG_hIST_SUPPORTED
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
...@@ -901,7 +930,7 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, ...@@ -901,7 +930,7 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*/ */
*width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
"sCAL height"); "sCAL height");
return (PNG_INFO_sCAL); return (PNG_INFO_sCAL);
} }
......
...@@ -185,6 +185,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) ...@@ -185,6 +185,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
#endif #endif
#ifdef PNG_eXIf_SUPPORTED
int num_exif; /* Added at libpng-1.6.31 */
png_bytep exif;
# ifdef PNG_READ_eXIf_SUPPORTED
png_bytep eXIf_buf; /* Added at libpng-1.6.32 */
# endif
#endif
#ifdef PNG_hIST_SUPPORTED #ifdef PNG_hIST_SUPPORTED
/* The hIST chunk contains the relative frequency or importance of the /* The hIST chunk contains the relative frequency or importance of the
* various palette entries, so that a viewer can intelligently select a * various palette entries, so that a viewer can intelligently select a
......
/* pngmem.c - stub functions for memory allocation /* pngmem.c - stub functions for memory allocation
* *
* Last changed in libpng 1.6.15 [November 20, 2014] * Last changed in libpng 1.6.26 [October 20, 2016]
* Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -66,7 +66,7 @@ png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) ...@@ -66,7 +66,7 @@ png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
*/ */
PNG_FUNCTION(png_voidp /* PRIVATE */, PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED) PNG_ALLOCATED)
{ {
/* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
* allocators have also been removed in 1.6.0, so any 16-bit system now has * allocators have also been removed in 1.6.0, so any 16-bit system now has
...@@ -107,9 +107,9 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), ...@@ -107,9 +107,9 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
*/ */
static png_voidp static png_voidp
png_malloc_array_checked(png_const_structrp png_ptr, int nelements, png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
size_t element_size) size_t element_size)
{ {
png_alloc_size_t req = nelements; /* known to be > 0 */ png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
if (req <= PNG_SIZE_MAX/element_size) if (req <= PNG_SIZE_MAX/element_size)
return png_malloc_base(png_ptr, req * element_size); return png_malloc_base(png_ptr, req * element_size);
...@@ -120,7 +120,7 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements, ...@@ -120,7 +120,7 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */, PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_array,(png_const_structrp png_ptr, int nelements, png_malloc_array,(png_const_structrp png_ptr, int nelements,
size_t element_size),PNG_ALLOCATED) size_t element_size),PNG_ALLOCATED)
{ {
if (nelements <= 0 || element_size == 0) if (nelements <= 0 || element_size == 0)
png_error(png_ptr, "internal error: array alloc"); png_error(png_ptr, "internal error: array alloc");
...@@ -130,7 +130,7 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements, ...@@ -130,7 +130,7 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */, PNG_FUNCTION(png_voidp /* PRIVATE */,
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
{ {
/* These are internal errors: */ /* These are internal errors: */
if (add_elements <= 0 || element_size == 0 || old_elements < 0 || if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
...@@ -143,7 +143,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, ...@@ -143,7 +143,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
if (add_elements <= INT_MAX - old_elements) if (add_elements <= INT_MAX - old_elements)
{ {
png_voidp new_array = png_malloc_array_checked(png_ptr, png_voidp new_array = png_malloc_array_checked(png_ptr,
old_elements+add_elements, element_size); old_elements+add_elements, element_size);
if (new_array != NULL) if (new_array != NULL)
{ {
...@@ -154,7 +154,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, ...@@ -154,7 +154,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
memcpy(new_array, old_array, element_size*(unsigned)old_elements); memcpy(new_array, old_array, element_size*(unsigned)old_elements);
memset((char*)new_array + element_size*(unsigned)old_elements, 0, memset((char*)new_array + element_size*(unsigned)old_elements, 0,
element_size*(unsigned)add_elements); element_size*(unsigned)add_elements);
return new_array; return new_array;
} }
...@@ -187,7 +187,7 @@ png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) ...@@ -187,7 +187,7 @@ png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
PNG_FUNCTION(png_voidp,PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED PNG_DEPRECATED) PNG_ALLOCATED PNG_DEPRECATED)
{ {
png_voidp ret; png_voidp ret;
...@@ -210,7 +210,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), ...@@ -210,7 +210,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
*/ */
PNG_FUNCTION(png_voidp,PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED) PNG_ALLOCATED)
{ {
if (png_ptr != NULL) if (png_ptr != NULL)
{ {
......
/* pngpread.c - read a png file in push mode /* pngpread.c - read a png file in push mode
* *
* Last changed in libpng 1.6.18 [July 23, 2015] * Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -77,11 +77,11 @@ png_process_data_pause(png_structrp png_ptr, int save) ...@@ -77,11 +77,11 @@ png_process_data_pause(png_structrp png_ptr, int save)
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_process_data_skip(png_structrp png_ptr) png_process_data_skip(png_structrp png_ptr)
{ {
/* TODO: Deprecate and remove this API. /* TODO: Deprecate and remove this API.
* Somewhere the implementation of this seems to have been lost, * Somewhere the implementation of this seems to have been lost,
* or abandoned. It was only to support some internal back-door access * or abandoned. It was only to support some internal back-door access
* to png_struct) in libpng-1.4.x. * to png_struct) in libpng-1.4.x.
*/ */
png_app_warning(png_ptr, png_app_warning(png_ptr,
"png_process_data_skip is not implemented in any current version of libpng"); "png_process_data_skip is not implemented in any current version of libpng");
return 0; return 0;
...@@ -189,6 +189,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) ...@@ -189,6 +189,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_crc_read(png_ptr, chunk_tag, 4); png_crc_read(png_ptr, chunk_tag, 4);
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
png_check_chunk_name(png_ptr, png_ptr->chunk_name); png_check_chunk_name(png_ptr, png_ptr->chunk_name);
png_check_chunk_length(png_ptr, png_ptr->push_length);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
} }
...@@ -410,7 +411,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) ...@@ -410,7 +411,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
{ {
PNG_PUSH_SAVE_BUFFER_IF_FULL PNG_PUSH_SAVE_BUFFER_IF_FULL
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
PNG_HANDLE_CHUNK_AS_DEFAULT); PNG_HANDLE_CHUNK_AS_DEFAULT);
} }
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
...@@ -501,7 +502,10 @@ png_push_save_buffer(png_structrp png_ptr) ...@@ -501,7 +502,10 @@ png_push_save_buffer(png_structrp png_ptr)
png_error(png_ptr, "Insufficient memory for save_buffer"); png_error(png_ptr, "Insufficient memory for save_buffer");
} }
memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); if (old_buffer)
memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
else if (png_ptr->save_buffer_size)
png_error(png_ptr, "save_buffer error");
png_free(png_ptr, old_buffer); png_free(png_ptr, old_buffer);
png_ptr->save_buffer_max = new_max; png_ptr->save_buffer_max = new_max;
} }
...@@ -518,7 +522,7 @@ png_push_save_buffer(png_structrp png_ptr) ...@@ -518,7 +522,7 @@ png_push_save_buffer(png_structrp png_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
png_size_t buffer_length) png_size_t buffer_length)
{ {
png_ptr->current_buffer = buffer; png_ptr->current_buffer = buffer;
png_ptr->current_buffer_size = buffer_length; png_ptr->current_buffer_size = buffer_length;
...@@ -621,7 +625,7 @@ png_push_read_IDAT(png_structrp png_ptr) ...@@ -621,7 +625,7 @@ png_push_read_IDAT(png_structrp png_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
png_size_t buffer_length) png_size_t buffer_length)
{ {
/* The caller checks for a non-zero buffer length. */ /* The caller checks for a non-zero buffer length. */
if (!(buffer_length > 0) || buffer == NULL) if (!(buffer_length > 0) || buffer == NULL)
...@@ -681,7 +685,12 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, ...@@ -681,7 +685,12 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
png_warning(png_ptr, "Truncated compressed data in IDAT"); png_warning(png_ptr, "Truncated compressed data in IDAT");
else else
png_error(png_ptr, "Decompression error in IDAT"); {
if (ret == Z_DATA_ERROR)
png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
else
png_error(png_ptr, "Decompression error in IDAT");
}
/* Skip the check on unprocessed input */ /* Skip the check on unprocessed input */
return; return;
...@@ -779,7 +788,7 @@ png_push_process_row(png_structrp png_ptr) ...@@ -779,7 +788,7 @@ png_push_process_row(png_structrp png_ptr)
{ {
if (png_ptr->pass < 6) if (png_ptr->pass < 6)
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
png_ptr->transformations); png_ptr->transformations);
switch (png_ptr->pass) switch (png_ptr->pass)
{ {
...@@ -1041,7 +1050,7 @@ png_push_have_row(png_structrp png_ptr, png_bytep row) ...@@ -1041,7 +1050,7 @@ png_push_have_row(png_structrp png_ptr, png_bytep row)
{ {
if (png_ptr->row_fn != NULL) if (png_ptr->row_fn != NULL)
(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
(int)png_ptr->pass); (int)png_ptr->pass);
} }
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
......
This diff is collapsed.
This diff is collapsed.
/* pngrio.c - functions for data input /* pngrio.c - functions for data input
* *
* Last changed in libpng 1.6.17 [March 26, 2015] * Last changed in libpng 1.6.24 [August 4, 2016]
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -85,7 +85,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) ...@@ -85,7 +85,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
*/ */
void PNGAPI void PNGAPI
png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
png_rw_ptr read_data_fn) png_rw_ptr read_data_fn)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* pngstruct.h - header file for PNG reference library /* pngstruct.h - header file for PNG reference library
* *
* Last changed in libpng 1.6.18 [July 23, 2015] * Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -249,7 +249,7 @@ struct png_struct_def ...@@ -249,7 +249,7 @@ struct png_struct_def
png_byte filter; /* file filter type (always 0) */ png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
png_byte pass; /* current interlace pass (0 - 6) */ png_byte pass; /* current interlace pass (0 - 6) */
png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */
png_byte color_type; /* color type of file */ png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */ png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row: write only */ png_byte usr_bit_depth; /* bit depth of users row: write only */
...@@ -263,7 +263,7 @@ struct png_struct_def ...@@ -263,7 +263,7 @@ struct png_struct_def
/* pixel depth used for the row buffers */ /* pixel depth used for the row buffers */
png_byte transformed_pixel_depth; png_byte transformed_pixel_depth;
/* pixel depth after read/write transforms */ /* pixel depth after read/write transforms */
#if PNG_ZLIB_VERNUM >= 0x1240 #if ZLIB_VERNUM >= 0x1240
png_byte zstream_start; /* at start of an input zlib stream */ png_byte zstream_start; /* at start of an input zlib stream */
#endif /* Zlib >= 1.2.4 */ #endif /* Zlib >= 1.2.4 */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
...@@ -353,7 +353,7 @@ struct png_struct_def ...@@ -353,7 +353,7 @@ struct png_struct_def
/* Options */ /* Options */
#ifdef PNG_SET_OPTION_SUPPORTED #ifdef PNG_SET_OPTION_SUPPORTED
png_byte options; /* On/off state (up to 4 options) */ png_uint_32 options; /* On/off state (up to 16 options) */
#endif #endif
#if PNG_LIBPNG_VER < 10700 #if PNG_LIBPNG_VER < 10700
......
This diff is collapsed.
/* pngtrans.c - transforms the data in a row (used by both readers and writers) /* pngtrans.c - transforms the data in a row (used by both readers and writers)
* *
* Last changed in libpng 1.6.18 [July 23, 2015] * Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -172,13 +172,14 @@ png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) ...@@ -172,13 +172,14 @@ png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
* size! * size!
*/ */
png_app_error(png_ptr, png_app_error(png_ptr,
"png_set_filler is invalid for low bit depth gray output"); "png_set_filler is invalid for"
" low bit depth gray output");
return; return;
} }
default: default:
png_app_error(png_ptr, png_app_error(png_ptr,
"png_set_filler: inappropriate color type"); "png_set_filler: inappropriate color type");
return; return;
} }
# else # else
...@@ -513,11 +514,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) ...@@ -513,11 +514,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
++sp; ++sp;
else /* Skip initial channel and, for sp, the filler */ else /* Skip initial channel and, for sp, the filler */
sp += 2, ++dp; {
sp += 2; ++dp;
}
/* For a 1 pixel wide image there is nothing to do */ /* For a 1 pixel wide image there is nothing to do */
while (sp < ep) while (sp < ep)
*dp++ = *sp, sp += 2; {
*dp++ = *sp; sp += 2;
}
row_info->pixel_depth = 8; row_info->pixel_depth = 8;
} }
...@@ -527,10 +532,14 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) ...@@ -527,10 +532,14 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
sp += 2; sp += 2;
else /* Skip initial channel and, for sp, the filler */ else /* Skip initial channel and, for sp, the filler */
sp += 4, dp += 2; {
sp += 4; dp += 2;
}
while (sp < ep) while (sp < ep)
*dp++ = *sp++, *dp++ = *sp, sp += 3; {
*dp++ = *sp++; *dp++ = *sp; sp += 3;
}
row_info->pixel_depth = 16; row_info->pixel_depth = 16;
} }
...@@ -553,11 +562,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) ...@@ -553,11 +562,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
++sp; ++sp;
else /* Skip initial channels and, for sp, the filler */ else /* Skip initial channels and, for sp, the filler */
sp += 4, dp += 3; {
sp += 4; dp += 3;
}
/* Note that the loop adds 3 to dp and 4 to sp each time. */ /* Note that the loop adds 3 to dp and 4 to sp each time. */
while (sp < ep) while (sp < ep)
*dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; {
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
}
row_info->pixel_depth = 24; row_info->pixel_depth = 24;
} }
...@@ -567,14 +580,16 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) ...@@ -567,14 +580,16 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
sp += 2; sp += 2;
else /* Skip initial channels and, for sp, the filler */ else /* Skip initial channels and, for sp, the filler */
sp += 8, dp += 6; {
sp += 8; dp += 6;
}
while (sp < ep) while (sp < ep)
{ {
/* Copy 6 bytes, skip 2 */ /* Copy 6 bytes, skip 2 */
*dp++ = *sp++, *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp, sp += 3; *dp++ = *sp++; *dp++ = *sp; sp += 3;
} }
row_info->pixel_depth = 48; row_info->pixel_depth = 48;
...@@ -594,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) ...@@ -594,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
return; /* The filler channel has gone already */ return; /* The filler channel has gone already */
/* Fix the rowbytes value. */ /* Fix the rowbytes value. */
row_info->rowbytes = dp-row; row_info->rowbytes = (png_size_t)(dp-row);
} }
#endif #endif
...@@ -692,8 +707,8 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) ...@@ -692,8 +707,8 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
* and this calculation is used because it avoids warnings that other * and this calculation is used because it avoids warnings that other
* forms produced on either GCC or MSVC. * forms produced on either GCC or MSVC.
*/ */
int padding = (-row_info->pixel_depth * row_info->width) & 7; int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
png_bytep rp = png_ptr->row_buf + row_info->rowbytes; png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
switch (row_info->bit_depth) switch (row_info->bit_depth)
{ {
...@@ -797,7 +812,7 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp ...@@ -797,7 +812,7 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
{ {
png_app_error(png_ptr, png_app_error(png_ptr,
"info change after png_start_read_image or png_read_update_info"); "info change after png_start_read_image or png_read_update_info");
return; return;
} }
#endif #endif
......
/* pngwio.c - functions for data output /* pngwio.c - functions for data output
* *
* Last changed in libpng 1.6.15 [November 20, 2014] * Last changed in libpng 1.6.24 [August 4, 2016]
* Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -35,7 +35,7 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) ...@@ -35,7 +35,7 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
/* NOTE: write_data_fn must not change the buffer! */ /* NOTE: write_data_fn must not change the buffer! */
if (png_ptr->write_data_fn != NULL ) if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
length); length);
else else
png_error(png_ptr, "Call to NULL write function"); png_error(png_ptr, "Call to NULL write function");
......
This diff is collapsed.
/* pngwtran.c - transforms the data in a row for PNG writers /* pngwtran.c - transforms the data in a row for PNG writers
* *
* Last changed in libpng 1.6.18 [July 23, 2015] * Last changed in libpng 1.6.26 [October 20, 2016]
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
...@@ -177,7 +177,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, ...@@ -177,7 +177,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{ {
int shift_start[4], shift_dec[4]; int shift_start[4], shift_dec[4];
int channels = 0; unsigned int channels = 0;
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
{ {
...@@ -525,7 +525,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) ...@@ -525,7 +525,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
#ifdef PNG_WRITE_FILLER_SUPPORTED #ifdef PNG_WRITE_FILLER_SUPPORTED
if ((png_ptr->transformations & PNG_FILLER) != 0) if ((png_ptr->transformations & PNG_FILLER) != 0)
png_do_strip_channel(row_info, png_ptr->row_buf + 1, png_do_strip_channel(row_info, png_ptr->row_buf + 1,
!(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
#endif #endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
...@@ -549,7 +549,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) ...@@ -549,7 +549,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
#ifdef PNG_WRITE_SHIFT_SUPPORTED #ifdef PNG_WRITE_SHIFT_SUPPORTED
if ((png_ptr->transformations & PNG_SHIFT) != 0) if ((png_ptr->transformations & PNG_SHIFT) != 0)
png_do_shift(row_info, png_ptr->row_buf + 1, png_do_shift(row_info, png_ptr->row_buf + 1,
&(png_ptr->shift)); &(png_ptr->shift));
#endif #endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment