Imported Upstream version 1.6.36 07/196507/1 upstream/1.6.36
authorjiyong.min <jiyong.min@samsung.com>
Wed, 2 Jan 2019 02:14:25 +0000 (11:14 +0900)
committerjiyong.min <jiyong.min@samsung.com>
Wed, 2 Jan 2019 02:15:24 +0000 (11:15 +0900)
Change-Id: I7dbd4c4ae0ff9a3fde971cda9146037fac5e54bc

245 files changed:
ANNOUNCE
AUTHORS [new file with mode: 0644]
CHANGES
CMakeLists.txt
INSTALL
LICENSE
Makefile.am
Makefile.in
README
TODO
TRADEMARK [new file with mode: 0644]
aclocal.m4
arm/arm_init.c
arm/filter_neon.S
arm/filter_neon_intrinsics.c
arm/palette_neon_intrinsics.c [new file with mode: 0644]
autogen.sh
compile
config.guess
config.h.in
config.sub
configure
configure.ac
contrib/arm-neon/android-ndk.c
contrib/arm-neon/linux.c
contrib/conftest/pngcp.dfa [new file with mode: 0644]
contrib/examples/README.txt
contrib/examples/iccfrompng.c
contrib/examples/pngpixel.c
contrib/examples/pngtopng.c
contrib/gregbook/README
contrib/gregbook/readpng.c
contrib/gregbook/readpng2.c
contrib/gregbook/readppm.c
contrib/gregbook/rpng-win.c
contrib/gregbook/rpng-x.c
contrib/gregbook/rpng2-win.c
contrib/gregbook/rpng2-x.c
contrib/gregbook/wpng.c
contrib/gregbook/writepng.c
contrib/libtests/makepng.c
contrib/libtests/pngimage.c
contrib/libtests/pngstest.c
contrib/libtests/pngunknown.c
contrib/libtests/pngvalid.c
contrib/libtests/readpng.c
contrib/libtests/tarith.c
contrib/libtests/timepng.c
contrib/mips-msa/README [new file with mode: 0644]
contrib/mips-msa/linux.c [new file with mode: 0644]
contrib/oss-fuzz/Dockerfile [new file with mode: 0644]
contrib/oss-fuzz/README.txt [new file with mode: 0644]
contrib/oss-fuzz/build.sh [new file with mode: 0755]
contrib/oss-fuzz/libpng_read_fuzzer.cc [new file with mode: 0644]
contrib/oss-fuzz/libpng_read_fuzzer.options [new file with mode: 0644]
contrib/oss-fuzz/png.dict [new file with mode: 0644]
contrib/pngminus/README
contrib/pngminus/png2pnm.bat
contrib/pngminus/png2pnm.c
contrib/pngminus/png2pnm.sh
contrib/pngminus/pnm2png.bat
contrib/pngminus/pnm2png.c
contrib/pngminus/pnm2png.sh
contrib/pngsuite/README
contrib/pngsuite/bad_interlace_conversions.txt [new file with mode: 0644]
contrib/pngsuite/ibasn0g08.png [new file with mode: 0644]
contrib/pngsuite/ibasn0g16.png [new file with mode: 0644]
contrib/pngsuite/ibasn2c08.png [new file with mode: 0644]
contrib/pngsuite/ibasn2c16.png [new file with mode: 0644]
contrib/pngsuite/ibasn3p08.png [new file with mode: 0644]
contrib/pngsuite/ibasn4a08.png [new file with mode: 0644]
contrib/pngsuite/ibasn4a16.png [new file with mode: 0644]
contrib/pngsuite/ibasn6a08.png [new file with mode: 0644]
contrib/pngsuite/ibasn6a16.png [new file with mode: 0644]
contrib/pngsuite/iftbbn2c16.png [new file with mode: 0644]
contrib/pngsuite/iftbbn3p08.png [new file with mode: 0644]
contrib/pngsuite/iftbgn2c16.png [new file with mode: 0644]
contrib/pngsuite/iftbgn3p08.png [new file with mode: 0644]
contrib/pngsuite/iftbrn2c08.png [new file with mode: 0644]
contrib/pngsuite/iftbwn0g16.png [new file with mode: 0644]
contrib/pngsuite/iftbwn3p08.png [new file with mode: 0644]
contrib/pngsuite/iftbyn3p08.png [new file with mode: 0644]
contrib/pngsuite/iftp0n0g08.png [new file with mode: 0644]
contrib/pngsuite/iftp0n2c08.png [new file with mode: 0644]
contrib/pngsuite/iftp0n3p08.png [new file with mode: 0644]
contrib/pngsuite/iftp1n3p08.png [new file with mode: 0644]
contrib/pngsuite/interlaced/README [new file with mode: 0644]
contrib/pngsuite/interlaced/ibasn0g01.png [new file with mode: 0644]
contrib/pngsuite/interlaced/ibasn0g02.png [new file with mode: 0644]
contrib/pngsuite/interlaced/ibasn0g04.png [new file with mode: 0644]
contrib/pngsuite/interlaced/ibasn3p01.png [new file with mode: 0644]
contrib/pngsuite/interlaced/ibasn3p02.png [new file with mode: 0644]
contrib/pngsuite/interlaced/ibasn3p04.png [new file with mode: 0644]
contrib/pngsuite/interlaced/iftbbn0g01.png [new file with mode: 0644]
contrib/pngsuite/interlaced/iftbbn0g02.png [new file with mode: 0644]
contrib/pngsuite/interlaced/iftbbn0g04.png [new file with mode: 0644]
contrib/powerpc-vsx/README [new file with mode: 0644]
contrib/powerpc-vsx/linux.c [new file with mode: 0644]
contrib/powerpc-vsx/linux_aux.c [new file with mode: 0644]
contrib/testpngs/crashers/bad_iCCP.png [new file with mode: 0644]
contrib/testpngs/crashers/badadler.png [new file with mode: 0644]
contrib/testpngs/crashers/badcrc.png [new file with mode: 0644]
contrib/testpngs/crashers/empty_ancillary_chunks.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_IDAT.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_bKGD_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_cHRM_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_eXIf_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_gAMA_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_hIST_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_iCCP_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_iTXt_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_juNk_safe_to_copy.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_pCAL_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_pHYs_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_sCAL_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_sPLT_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_sRGB_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_sTER_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_tEXt_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_tIME_chunk.png [new file with mode: 0644]
contrib/testpngs/crashers/huge_zTXt_chunk.png [new file with mode: 0644]
contrib/testpngs/makepngs.sh
contrib/tools/README.txt
contrib/tools/chkfmt
contrib/tools/genpng.c
contrib/tools/makesRGB.c
contrib/tools/pngcp.c [new file with mode: 0644]
contrib/tools/pngfix.c
contrib/tools/reindent [new file with mode: 0755]
contrib/tools/sRGB.h
contrib/visupng/PngFile.c
contrib/visupng/PngFile.h
contrib/visupng/VisualPng.c
depcomp
example.c
install-sh
intel/filter_sse2_intrinsics.c [new file with mode: 0644]
intel/intel_init.c [new file with mode: 0644]
libpng-manual.txt
libpng.3
libpng.pc.in
libpngpf.3
ltmain.sh [changed mode: 0644->0755]
mips/filter_msa_intrinsics.c [new file with mode: 0644]
mips/mips_init.c [new file with mode: 0644]
missing
png.5
png.c
png.h
pngconf.h
pngdebug.h
pngerror.c
pngget.c
pnginfo.h
pngmem.c
pngpread.c
pngpriv.h
pngread.c
pngrio.c
pngrtran.c
pngrutil.c
pngset.c
pngstruct.h
pngtest.c
pngtest.png
pngtrans.c
pngwio.c
pngwrite.c
pngwtran.c
pngwutil.c
powerpc/filter_vsx_intrinsics.c [new file with mode: 0644]
powerpc/powerpc_init.c [new file with mode: 0644]
projects/owatcom/pngconfig.mak
projects/visualc71/README.txt
projects/vstudio/README.txt
projects/vstudio/libpng/libpng.vcxproj
projects/vstudio/pnglibconf/pnglibconf.vcxproj
projects/vstudio/pngstest/pngstest.vcxproj
projects/vstudio/pngtest/pngtest.vcxproj
projects/vstudio/pngunknown/pngunknown.vcxproj
projects/vstudio/pngvalid/pngvalid.vcxproj
projects/vstudio/zlib.props
projects/vstudio/zlib/zlib.vcxproj
scripts/README.txt
scripts/def.c [deleted file]
scripts/descrip.mms
scripts/genchk.cmake.in [new file with mode: 0644]
scripts/genout.cmake.in [new file with mode: 0644]
scripts/gensrc.cmake.in [new file with mode: 0644]
scripts/libpng-config-head.in
scripts/libpng.pc.in
scripts/makefile.32sunu
scripts/makefile.64sunu
scripts/makefile.bor [deleted file]
scripts/makefile.cegcc
scripts/makefile.darwin
scripts/makefile.freebsd
scripts/makefile.hp64
scripts/makefile.hpgcc
scripts/makefile.hpux
scripts/makefile.knr [deleted file]
scripts/makefile.linux
scripts/makefile.linux-opt [moved from scripts/makefile.solaris-x86 with 67% similarity]
scripts/makefile.mips
scripts/makefile.msc [deleted file]
scripts/makefile.msys
scripts/makefile.ne12bsd
scripts/makefile.netbsd
scripts/makefile.openbsd
scripts/makefile.sco
scripts/makefile.sggcc
scripts/makefile.sgi
scripts/makefile.so9
scripts/makefile.solaris
scripts/makefile.std
scripts/makefile.sunos
scripts/makefile.tc3 [deleted file]
scripts/options.awk
scripts/pnglibconf.dfa
scripts/pnglibconf.h.prebuilt
scripts/symbols.def
scripts/test.cmake.in [new file with mode: 0644]
test-driver
tests/pngstest
tests/pngstest-0g01 [deleted file]
tests/pngstest-0g02 [deleted file]
tests/pngstest-0g04 [deleted file]
tests/pngstest-0g08 [deleted file]
tests/pngstest-0g16 [deleted file]
tests/pngstest-2c08 [deleted file]
tests/pngstest-2c16 [deleted file]
tests/pngstest-3p01 [deleted file]
tests/pngstest-3p02 [deleted file]
tests/pngstest-3p04 [deleted file]
tests/pngstest-3p08 [deleted file]
tests/pngstest-4a08 [deleted file]
tests/pngstest-4a16 [deleted file]
tests/pngstest-6a08 [deleted file]
tests/pngstest-6a16 [deleted file]
tests/pngstest-error [deleted file]
tests/pngtest-badpngs [new file with mode: 0755]
tests/pngunknown-sAPI
tests/pngvalid-progressive-interlace-size [deleted file]
tests/pngvalid-progressive-interlace-transform [deleted file]

index 5de4eed..f1724c0 100644 (file)
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,60 +1,77 @@
-Libpng 1.6.21 - January 15, 2016
+libpng 1.6.36 - December 1, 2018
+================================
 
-This is a public release of libpng, intended for use in production codes.
+This is a public release of libpng, intended for use in production code.
 
-Files available for download:
 
-Source files with LF line endings (for Unix/Linux) and with a
-"configure" script
+Files available for download
+----------------------------
 
-   libpng-1.6.21.tar.xz (LZMA-compressed, recommended)
-   libpng-1.6.21.tar.gz
+Source files with LF line endings (for Unix/Linux):
 
-Source files with CRLF line endings (for Windows), without the
-"configure" script
+ * libpng-1.6.36.tar.xz (LZMA-compressed, recommended)
+ * libpng-1.6.36.tar.gz
 
-   /scratch/glennrp/Libpng16/lpng1621.7z  (LZMA-compressed, recommended)
-   /scratch/glennrp/Libpng16/lpng1621.zip
+Source files with CRLF line endings (for Windows):
+
+ * lp1636.7z (LZMA-compressed, recommended)
+ * lp1636.zip
 
 Other information:
 
-   libpng-1.6.21-README.txt
-   libpng-1.6.21-LICENSE.txt
-   libpng-1.6.21-*.asc (armored detached GPG signatures)
-
-Changes since the last public release (1.6.20):
-
-  Fixed syntax "$(command)" in tests/pngstest that some shells other than
-    bash could not parse (Bug report by Nelson Beebe). Use `command` instead.
-  Moved png_check_keyword() from pngwutil.c to pngset.c
-  Removed LE/BE dependencies in pngvalid, to 'fix' the current problem
-    in the BigEndian tests by not testing it, making the BE code the same 
-    as the LE version.
-  Fixes to pngvalid for various reduced build configurations (eliminate unused
-    statics) and a fix for the case in rgb_to_gray when the digitize option
-    reduces graylo to 0, producing a large error.
-  Widened the 'limit' check on the internally calculated error limits in
-    the 'DIGITIZE' case (the code used prior to 1.7 for rgb_to_gray error
-    checks) and changed the check to only operate in non-release builds
-   (base build type not RC or RELEASE.)
-  Fixed undefined behavior in pngvalid.c, undefined because
-    (png_byte) << shift is undefined if it changes the signed bit
-    (because png_byte is promoted to int). The libpng exported functions
-    png_get_uint_32 and png_get_uint_16 handle this. (Bug reported by
-    David Drysdale as a result of reports from UBSAN in clang 3.8).
-  This changes pngvalid to use BE random numbers; this used to produce
-    errors but these should not be fixed as a result of the previous changes.
-  In projects/vstudio, combined readme.txt and WARNING into README.txt
-  Relocated assert() in contrib/tools/pngfix.c, bug found by American
-    Fuzzy Lop, reported by Brian Carpenter.
-  Marked 'limit' UNUSED in transform_range_check().  This only affects
-    release builds.
-  Worked around a false-positive Coverity issue in pngvalid.c.
-
-Send comments/corrections/commendations to png-mng-implement at lists.sf.net
-(subscription required; visit
-https://lists.sourceforge.net/lists/listinfo/png-mng-implement
-to subscribe)
-or to glennrp at users.sourceforge.net
+ * README.md
+ * LICENSE.md
+ * AUTHORS.md
+ * TRADEMARK.md
+
+
+IMPORTANT licensing update: libpng license v2
+---------------------------------------------
+
+The new libpng license comprises the terms and conditions from the zlib
+license, and the disclaimer from the Boost license.
+
+The legacy libpng license, used until libpng-1.6.35, is appended to the
+new license, following the precedent established in the Python Software
+Foundation License version 2.
 
-Glenn R-P
+From now on, the list of contributing authors shall be maintained in a
+separate AUTHORS file.  The lists of previous contributing authors,
+mentioned in the legacy libpng license and considered to be an integral
+part of that license, are kept intact, with no further updates.
+
+
+Changes since the previous public release (version 1.6.35)
+----------------------------------------------------------
+
+ * Optimized png_do_expand_palette for ARM processors.
+   Improved performance by around 10-22% on a recent ARM Chromebook.
+   (Contributed by Richard Townsend, ARM Holdings)
+ * Fixed manipulation of machine-specific optimization options.
+   (Contributed by Vicki Pfau)
+ * Used memcpy instead of manual pointer arithmetic on Intel SSE2.
+   (Contributed by Samuel Williams)
+ * Fixed build errors with MSVC on ARM64.
+   (Contributed by Zhijie Liang)
+ * Fixed detection of libm in CMakeLists.
+   (Contributed by Cameron Cawley)
+ * Fixed incorrect creation of pkg-config file in CMakeLists.
+   (Contributed by Kyle Bentley)
+ * Fixed the CMake build on Windows MSYS by avoiding symlinks.
+ * Fixed a build warning on OpenBSD.
+   (Contributed by Theo Buehler)
+ * Fixed various typos in comments.
+   (Contributed by "luz.paz")
+ * Raised the minimum required CMake version from 3.0.2 to 3.1.
+ * Removed yet more of the vestigial support for pre-ANSI C compilers.
+ * Removed ancient makefiles for ancient systems that have been broken
+   across all previous libpng-1.6.x versions.
+ * Removed the Y2K compliance statement and the export control
+   information.
+ * Applied various code style and documentation fixes.
+
+
+Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
+Subscription is required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe.
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..79a3d10
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,45 @@
+PNG REFERENCE LIBRARY AUTHORS
+=============================
+
+This is the list of PNG Reference Library ("libpng") Contributing
+Authors, for copyright and licensing purposes.
+
+ * Andreas Dilger
+ * Cosmin Truta
+ * Dave Martindale
+ * Eric S. Raymond
+ * Gilles Vollant
+ * Glenn Randers-Pehrson
+ * Greg Roelofs
+ * Guy Eric Schalnat
+ * James Yu
+ * John Bowler
+ * Kevin Bracey
+ * Magnus Holmgren
+ * Mandar Sahastrabuddhe
+ * Mans Rullgard
+ * Matt Sarett
+ * Mike Klein
+ * Paul Schmidt
+ * Sam Bushell
+ * Samuel Williams
+ * Simon-Pierre Cadieux
+ * Tim Wegner
+ * Tom Lane
+ * Tom Tanner
+ * Vadim Barkov
+ * Willem van Schaik
+ * Zhijie Liang
+ * Arm Holdings
+   - Richard Townsend
+ * Google Inc.
+   - Matt Sarett
+   - Mike Klein
+
+The build projects, the build scripts, the test scripts, and other
+files in the "projects", "scripts" and "tests" directories, have other
+copyright owners, but are released under the libpng license.
+
+Some files in the "contrib" directory, and some tools-generated files
+that are distributed with libpng, have other copyright owners, and are
+released under other open source licenses.
diff --git a/CHANGES b/CHANGES
index 8e589f6..bdd4480 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,3 @@
-#if 0
 CHANGES - changes for libpng
 
 version 0.1 [March 29, 1995]
@@ -593,7 +592,7 @@ Version 1.0.5e [November 30, 1999]
     with trailing compressed parts easier in the future, and added new functions
     png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
     png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
-  NOTE: Applications that write text chunks MUST define png_text->lang
+    NOTE: Applications that write text chunks MUST define png_text->lang
     before calling png_set_text(). It must be set to NULL if you want to
     write tEXt or zTXt chunks.  If you want your application to be able to
     run with older versions of libpng, use
@@ -833,7 +832,7 @@ Version 1.0.7beta11 [May 7, 2000]
   Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
     which are no longer used.
   Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is
-    defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED
+    defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXt_SUPPORTED
     is defined.
   Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
     overrun when old applications fill the info_ptr->text structure directly.
@@ -1454,7 +1453,7 @@ Version 1.2.6beta4 [July 28, 2004]
     sequential read support.
   Added some "#if PNG_WRITE_SUPPORTED" blocks.
   Added #ifdef to remove some redundancy in png_malloc_default().
-  Use png_malloc instead of png_zalloc to allocate the pallete.
+  Use png_malloc instead of png_zalloc to allocate the palette.
 
 Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004]
   Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS().
@@ -3259,7 +3258,7 @@ Version 1.5.2beta01 [February 13, 2011]
   Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the
     old VisualC++ preprocessor.
   Turned on interlace handling in png_read_png().
-  Fixed gcc pendantic warnings.
+  Fixed gcc pedantic warnings.
   Handle longjmp in Cygwin.
   Fixed png_get_current_row_number() in the interlaced case.
   Cleaned up ALPHA flags and transformations.
@@ -3359,7 +3358,7 @@ Version 1.5.3beta05 [May 6, 2011]
   Pass "" instead of '\0' to png_default_error() in png_err().  This mistake
     was introduced in libpng-1.2.20beta01.  This fixes CVE-2011-2691.
   Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte
-    optimization configureable.
+    optimization configurable.
   IDAT compression failed if preceded by a compressed text chunk (bug
     introduced in libpng-1.5.3beta01-02).  This was because the attempt to
     reset the zlib stream in png_write_IDAT happened after the first IDAT
@@ -3643,7 +3642,7 @@ Version 1.5.6beta05 [October 12, 2011]
   Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01.
 
 Version 1.5.6beta06 [October 17, 2011]
-  Removed two redundant tests for unitialized row.
+  Removed two redundant tests for uninitialized row.
   Fixed a relatively harmless memory overwrite in compressed text writing
     with a 1 byte zlib buffer.
   Add ability to call png_read_update_info multiple times to pngvalid.c.
@@ -3689,7 +3688,7 @@ Version 1.5.7beta01 [November 4, 2011]
     crash.  The pngmem.c implementation of png_malloc() included a cast
     to png_size_t which would fail on large allocations on 16-bit systems.
   Fix for the preprocessor of the Intel C compiler. The preprocessor
-    splits adjacent @ signs with a space; this changes the concatentation
+    splits adjacent @ signs with a space; this changes the concatenation
     token from @-@-@ to PNG_JOIN; that should work with all compiler
     preprocessors.
   Paeth filter speed improvements from work by Siarhei Siamashka. This
@@ -3735,7 +3734,7 @@ Version 1.5.7beta03 [November 17, 2011]
     gray (on palette) itself.
   Fixes for C++ compilation using g++ When libpng source is compiled
     using g++. The compiler imposes C++ rules on the C source; thus it
-    is desireable to make the source work with either C or C++ rules
+    is desirable to make the source work with either C or C++ rules
     without throwing away useful error information.  This change adds
     png_voidcast to allow C semantic (void*) cases or the corresponding
     C++ static_cast operation, as appropriate.
@@ -4061,7 +4060,7 @@ Version 1.6.0beta17 [March 10, 2012]
     possible to call png_inflate() incrementally.  A warning is no longer
     issued if the language tag or translated keyword in the iTXt chunk
     has zero length.
-  If benign errors are disabled use maximum window on ancilliary inflate.
+  If benign errors are disabled use maximum window on ancillary inflate.
     This works round a bug introduced in 1.5.4 where compressed ancillary
     chunks could end up with a too-small windowBits value in the deflate
     header.
@@ -4176,7 +4175,7 @@ Version 1.6.0beta27 [August 11, 2012]
     declared even though the functions are never actually defined.  This
     change provides a dummy definition so that the declarations work, yet any
     implementation will fail to compile because of an incomplete type.
-  Re-eliminated the use of strcpy() in pngtest.c.  An unncessary use of
+  Re-eliminated the use of strcpy() in pngtest.c.  An unnecessary use of
     strcpy() was accidentally re-introduced in libpng16; this change replaces
     it with strncpy().
   Eliminated use of png_sizeof(); use sizeof() instead.
@@ -4309,7 +4308,7 @@ Version 1.6.0beta31 [November 1, 2012]
     resulting in VS2010 having to update the files.
   Removed non-working ICC profile support code that was mostly added to
     libpng-1.6.0beta29 and beta30. There was too much code for too little
-    gain; implementing full ICC color correction may be desireable but is left
+    gain; implementing full ICC color correction may be desirable but is left
     up to applications.
 
 Version 1.6.0beta32 [November 25, 2012]
@@ -4592,7 +4591,7 @@ Version 1.6.3beta07 [June 8, 2013]
     the optimizations ('check' vs 'api') are exposed in the public header files
     except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the
     decision about whether or not to use the optimizations.
-  Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage.
+  Protect symbol prefixing against CC/CPPFLAGS/CFLAGS usage.
     Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test
     on __ARM_NEON__ from configure time to compile time.  This breaks symbol
     prefixing because the definition of the special png_init_filter_functions
@@ -5063,7 +5062,8 @@ Version 1.6.15beta04 [November 4, 2014]
 Version 1.6.15beta05 [November 5, 2014]
   Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in
     example.c, pngtest.c, and applications in the contrib directory.
-  Avoid out-of-bounds memory access in png_user_version_check().
+  Fixed an out-of-range read in png_user_version_check() (Bug report from
+    Qixue Xiao, CVE-2015-8540).
   Simplified and future-proofed png_user_version_check().
   Fixed GCC unsigned int->float warnings. Various versions of GCC
     seem to generate warnings when an unsigned value is implicitly
@@ -5484,11 +5484,613 @@ Version 1.6.21rc02 [January 7, 2016]
 Version 1.6.21 [January 15, 2016]
   Worked around a false-positive Coverity issue in pngvalid.c.
 
+Version 1.6.22beta01 [January 23, 2016]
+  Changed PNG_USE_MKSTEMP to __COVERITY__ to select alternate
+    "tmpfile()" implementation in contrib/libtests/pngstest.c
+  Fixed NO_STDIO build of pngunknown.c to skip calling png_init_io()
+    if there is no stdio.h support.
+  Added a png_image_write_to_memory() API and a number of assist macros
+    to allow an application that uses the simplified API write to bypass
+    stdio and write directly to memory.
+  Added some warnings (png.h) and some check code to detect *possible*
+    overflow in the ROW_STRIDE and simplified image SIZE macros.  This
+    disallows image width/height/format that *might* overflow.  This is
+    a quiet API change that limits in-memory image size (uncompressed) to
+    less than 4GByte and image row size (stride) to less than 2GByte.
+  Revised workaround for false-positive Coverity issue in pngvalid.c.
+
+Version 1.6.22beta02 [February 8, 2016]
+  Only use exit(77) in configure builds.
+  Corrected error in PNG_IMAGE_PNG_SIZE_MAX. This new macro underreported
+    the palette size because it failed to take into account that the memory
+    palette has to be expanded to full RGB when it is written to PNG.
+  Updated CMakeLists.txt, added supporting scripts/gen*.cmake.in
+    and test.cmake.in (Roger Leigh).
+  Relaxed limit checks on gamma values in pngrtran.c. As suggested in
+    the comments gamma values outside the range currently permitted
+    by png_set_alpha_mode are useful for HDR data encoding.  These values
+    are already permitted by png_set_gamma so it is reasonable caution to
+    extend the png_set_alpha_mode range as HDR imaging systems are starting
+    to emerge.
+
+Version 1.6.22beta03 [March 9, 2016]
+  Added a common-law trademark notice and export control information
+    to the LICENSE file, png.h, and the man page.
+  Restored "& 0xff" in png_save_uint_16() and png_save_uint_32() that
+    were accidentally removed from libpng-1.6.17. 
+  Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h
+    (Robert C. Seacord).
+  Removed dubious "#if INT_MAX" test from png.h that was added to
+    libpng-1.6.19beta02 (John Bowler).
+  Add ${INCLUDES} in scripts/genout.cmake.in (Bug report by Nixon Kwok).
+  Updated LICENSE to say files in the contrib directory are not
+    necessarily under the libpng license, and that some makefiles have
+    other copyright owners.
+  Added INTEL-SSE2 support (Mike Klein and Matt Sarett, Google, Inc.).
+  Made contrib/libtests/timepng more robust.  The code no longer gives
+    up/fails on invalid PNG data, it just skips it (with error messages).
+    The code no longer fails on PNG files with data beyond IEND.  Options
+    exist to use png_read_png (reading the whole image, not by row) and, in
+    that case, to apply any of the supported transforms.  This makes for
+    more realistic testing; the decoded data actually gets used in a
+    meaningful fashion (John Bowler).
+  Fixed some misleading indentation (Krishnaraj Bhat).
+
+Version 1.6.22beta04 [April 5, 2016]
+  Force GCC compilation to C89 if needed (Dagobert Michelsen).
+  SSE filter speed improvements for bpp=3:
+    memcpy-free implementations of load3() / store3().
+    call load3() only when needed at the end of a scanline.
+
+Version 1.6.22beta05 [April 27, 2016]
+  Added PNG_FAST_FILTERS macro (defined as
+    PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_UP).
+  Various fixes for contrib/libtests/timepng.c
+  Moved INTEL-SSE code from pngpriv.h into contrib/intel/intel_sse.patch.
+  Fixed typo (missing underscore) in #define PNG_READ_16_TO_8_SUPPORTED
+    (Bug report by Y.Ohashik).
+
+Version 1.6.22beta06 [May 5, 2016]
+  Rebased contrib/intel_sse.patch.
+  Quieted two Coverity issues in contrib/libtests/timepng.c.
+  Fixed issues with scripts/genout.cmake.in (David Capello, Nixon Kwok):
+    Added support to use multiple directories in ZLIBINCDIR variable,
+    Fixed CMAKE_C_FLAGS with multiple values when genout is compiled on MSVC,
+    Fixed pnglibconf.c compilation on OS X including the sysroot path.
+
+Version 1.6.22rc01 [May 14, 2016]
+  No changes.
+
+Version 1.6.22rc02 [May 16, 2016]
+  Removed contrib/timepng from default build; it does not build on platforms
+    that don't supply clock_gettime().
+
+Version 1.6.22rc03 [May 17, 2016]
+  Restored contrib/timepng to default build but check for the presence
+    of clock_gettime() in configure.ac and Makefile.am.
+
+Version 1.6.22 [May 26, 2016]
+  No changes.
+
+Version 1.6.23beta01 [May 29, 2016]
+  Stop a potential memory leak in png_set_tRNS() (Bug report by Ted Ying).
+  Fixed the progressive reader to handle empty first IDAT chunk properly
+    (patch by Timothy Nikkel).  This bug was introduced in libpng-1.6.0 and
+    only affected the libpng16 branch.
+  Added tests in pngvalid.c to check zero-length IDAT chunks in various
+    positions.  Fixed the sequential reader to handle these more robustly
+    (John Bowler).
+
+Version 1.6.23rc01 [June 2, 2016]
+  Corrected progressive read input buffer in pngvalid.c. The previous version
+    the code invariably passed just one byte at a time to libpng.  The intent
+    was to pass a random number of bytes in the range 0..511.
+  Moved sse2 prototype from pngpriv.h to contrib/intel/intel_sse.patch.
+  Added missing ")" in pngerror.c (Matt Sarrett).
+
+Version 1.6.23rc02 [June 4, 2016]
+  Fixed undefined behavior in png_push_save_buffer(). Do not call
+    memcpy() with a null source, even if count is zero (Leon Scroggins III).
+
+Version 1.6.23 [June 9, 2016]
+  Fixed bad link to RFC2083 in png.5 (Nikola Forro).
+
+Version 1.6.24beta01 [June 11, 2016]
+  Avoid potential overflow of the PNG_IMAGE_SIZE macro.  This macro
+    is not used within libpng, but is used in some of the examples.
+
+Version 1.6.24beta02 [June 23, 2016]
+  Correct filter heuristic overflow handling. This was broken when the
+    write filter code was moved out-of-line; if there is a single filter and
+    the heuristic sum overflows the calculation of the filtered line is not
+    completed.  In versions prior to 1.6 the code was duplicated in-line
+    and the check not performed, so the filter operation completed; however,
+    in the multi-filter case where the sum is performed the 'none' filter would
+    be selected if all the sums overflowed, even if it wasn't in the filter
+    list.  The fix to the first problem is simply to provide PNG_SIZE_MAX as
+    the current lmins sum value; this means the sum can never exceed it and
+    overflows silently.  A reasonable compiler that does choose to inline
+    the code will simply eliminate the sum check.
+  The fix to the second problem is to use high precision arithmetic (this is
+    implemented in 1.7), however a simple safe fix here is to chose the lowest
+    numbered filter in the list from png_set_filter (this only works if the
+    first problem is also fixed) (John Bowler).
+  Use a more efficient absolute value calculation on SSE2 (Matthieu Darbois).
+  Fixed the case where PNG_IMAGE_BUFFER_SIZE can overflow in the application
+    as a result of the application using an increased 'row_stride'; previously
+    png_image_finish_read only checked for overflow on the base calculation of
+    components.  (I.e. it checked for overflow of a 32-bit number on the total
+    number of pixel components in the output format, not the possibly padded row
+    length and not the number of bytes, which for linear formats is twice the
+    number of components.)
+  MSVC does not like '-(unsigned)', so replaced it with 0U-(unsigned)
+  MSVC does not like (uInt) = -(unsigned) (i.e. as an initializer), unless
+    the conversion is explicitly invoked by a cast.
+  Put the SKIP definition in the correct place. It needs to come after the
+    png.h include (see all the other .c files in contrib/libtests) because it
+    depends on PNG_LIBPNG_VER.
+  Removed the three compile warning options from the individual project
+    files into the zlib.props globals.  It increases the warning level from 4
+    to All and adds a list of the warnings that need to be turned off.  This is
+    semi-documentary; the intent is to tell libpng users which warnings have
+    been examined and judged non-fixable at present.  The warning about
+    structure padding is fixable, but it would be a significant change (moving
+    structure members around).
+
+Version 1.6.24beta03 [July 4, 2016]
+  Optimized absolute value calculation in filter selection, similar to
+    code in the PAETH decoder in pngrutil.c. Build with PNG_USE_ABS to
+    use this.
+  Added pngcp to the build together with a pngcp.dfa configuration test.
+  Added high resolution timing to pngcp.
+  Added "Common linking failures" section to INSTALL.
+  Relocated misplaced #endif in png.c sRGB profile checking.
+  Fixed two Coverity issues in pngcp.c.
+
+Version 1.6.24beta04 [July 8, 2016]
+  Avoid filter-selection heuristic sum calculations in cases where only one
+    filter is a candidate for selection. This trades off code size (added
+    private png_setup_*_row_only() functions) for speed.
+
+Version 1.6.24beta05 [July 13, 2016]
+  Fixed some indentation to comply with our coding style.
+  Added contrib/tools/reindent.
+
+Version 1.6.24beta06 [July 18, 2016]
+  Fixed more indentation to comply with our coding style.
+  Eliminated unnecessary tests of boolean png_isaligned() vs 0.
+
+Version 1.6.24rc01 [July 25, 2016]
+  No changes.
+
+Version 1.6.24rc02 [August 1, 2016]
+  Conditionally compile SSE2 headers in contrib/intel/intel_sse.patch
+  Conditionally compile png_decompress_chunk().
+
+Version 1.6.24rc03 [August 2, 2016]
+  Conditionally compile ARM_NEON headers in pngpriv.h
+  Updated contrib/intel/intel_sse.patch
+
+Version 1.6.24[August 4, 2016]
+  No changes.
+
+Version 1.6.25beta01 [August 12, 2016]
+  Reject oversized iCCP profile immediately.
+  Cleaned up PNG_DEBUG compile of pngtest.c.
+  Conditionally compile png_inflate().
+
+Version 1.6.25beta02 [August 18, 2016]
+  Don't install pngcp; it conflicts with pngcp in the pngtools package.
+  Minor editing of INSTALL, (whitespace, added copyright line)
+
+Version 1.6.25rc01 [August 24, 2016]
+  No changes.
+
+Version 1.6.25rc02 [August 29, 2016]
+  Added MIPS support (Mandar Sahastrabuddhe <Mandar.Sahastrabuddhe@imgtec.com>).
+  Only the UP filter is currently implemented.
+
+Version 1.6.25rc03 [August 29, 2016]
+  Rebased contrib/intel/intel_sse.patch after the MIPS implementation.
+
+Version 1.6.25rc04 [August 30, 2016]
+  Added MIPS support for SUB, AVG, and PAETH filters (Mandar Sahastrabuddhe).
+
+Version 1.6.25rc05 [August 30, 2016]
+  Rebased contrib/intel/intel_sse.patch after the MIPS implementation update..
+
+Version 1.6.25 [September 1, 2016]
+  No changes.
+
+Version 1.6.26beta01 [September 26, 2016]
+  Fixed handling zero length IDAT in pngfix (bug report by Agostino Sarubbo,
+    bugfix by John Bowler).
+  Do not issue a png_error() on read in png_set_pCAL() because png_handle_pCAL
+    has allocated memory that libpng needs to free.
+  Conditionally compile png_set_benign_errors() in pngread.c and pngtest.c
+  Issue a png_benign_error instead of a png_error on ADLER32 mismatch
+    while decoding compressed data chunks.
+  Changed PNG_ZLIB_VERNUM to ZLIB_VERNUM in pngpriv.h, pngstruct.h, and
+    pngrutil.c.
+  If CRC handling of critical chunks has been set to PNG_CRC_QUIET_USE,
+    ignore the ADLER32 checksum in the IDAT chunk as well as the chunk CRCs.
+  Issue png_benign_error() on ADLER32 checksum mismatch instead of png_error().
+  Add tests/badcrc.png and tests/badadler.png to tests/pngtest.
+  Merged pngtest.c with libpng-1.7.0beta84/pngtest.c
+
+Version 1.6.26beta02 [October 1, 2016]
+  Updated the documentation about CRC and ADLER32 handling.
+  Quieted 117 warnings from clang-3.8 in pngtrans.c, pngread.c,
+     pngwrite.c, pngunknown.c, and pngvalid.c.
+  Quieted 58 (out of 144) -Wconversion compiler warnings by changing
+    flag definitions in pngpriv.h from 0xnnnn to 0xnnnnU and trivial changes
+    in png.c, pngread.c, and pngwutil.c.
+
+Version 1.6.26beta03 [October 2, 2016]
+  Removed contrib/libtests/*.orig and *.rej that slipped into the tarballs.
+  Quieted the 86 remaining -Wconversion compiler warnings by
+    revising the png_isaligned() macro and trivial changes in png.c,
+    pngerror.c, pngget.c, pngmem.c, pngset.c, pngrtran.c, pngrutil.c,
+    pngwtran.c, pngwrite.c, and pngwutil.c.
+
+Version 1.6.26beta04 [October 3, 2016]
+  Quieted (bogus?) clang warnings about "absolute value has no effect"
+    when PNG_USE_ABS is defined.
+  Fixed offsets in contrib/intel/intel_sse.patch
+
+Version 1.6.26beta05 [October 6, 2016]
+  Changed integer constant 4294967294 to unsigned 4294967294U in pngconf.h
+    to avoid a signed/unsigned compare in the preprocessor.
+
+Version 1.6.26beta06 [October 7, 2016]
+  Use zlib-1.2.8.1 inflateValidate() instead of inflateReset2() to
+    optionally avoid ADLER32 evaluation.
+
+Version 1.6.26rc01 [October 12, 2016]
+  No changes.
+
+Version 1.6.26 [October 20, 2016]
+  Cosmetic change, "ptr != 0" to "ptr != NULL" in png.c and pngrutil.c
+  Despammed email addresses (replaced "@" with " at ").
+
+Version 1.6.27beta01 [November 2, 2016]
+  Restrict the new ADLER32-skipping to IDAT chunks.  It broke iCCP chunk
+    handling: an erroneous iCCP chunk would throw a png_error and reject the
+    entire PNG image instead of rejecting just the iCCP chunk with a warning,
+    if built with zlib-1.2.8.1.
+
+Version 1.6.27rc01 [December 27, 2016]
+  Control ADLER32 checking with new PNG_IGNORE_ADLER32 option. Fixes
+    an endless loop when handling erroneous ADLER32 checksums; bug
+    introduced in libpng-1.6.26.
+  Removed the use of a macro containing the pre-processor 'defined'
+    operator.  It is unclear whether this is valid; a macro that
+    "generates" 'defined' is not permitted, but the use of the word
+    "generates" within the C90 standard seems to imply more than simple
+    substitution of an expression itself containing a well-formed defined
+    operation.
+  Added ARM support to CMakeLists.txt (Andreas Franek).
+
+Version 1.6.27 [December 29, 2016]
+  Fixed a potential null pointer dereference in png_set_text_2() (bug report
+    and patch by Patrick Keshishian, CVE-2016-10087).
+
+Version 1.6.28rc01 [January 3, 2017]
+  Fixed arm/aarch64 detection in CMakeLists.txt (Gianfranco Costamagna).
+  Added option to Cmake build allowing a custom location of zlib to be
+    specified in a scenario where libpng is being built as a subproject
+    alongside zlib by another project (Sam Serrels).
+  Changed png_ptr->options from a png_byte to png_uint_32, to accommodate
+    up to 16 options.
+
+Version 1.6.28rc02 [January 4, 2017]
+  Added "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna).
+  Moved SSE2 optimization code into the main libpng source directory.
+    Configure libpng with "configure --enable-intel-sse" or compile
+    libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it.
+
+Version 1.6.28rc03 [January 4, 2017]
+  Backed out the SSE optimization and last CMakeLists.txt to allow time for QA.
+
+Version 1.6.28 [January 5, 2017]
+  No changes.
+
+Version 1.6.29beta01 [January 12, 2017]
+  Readded "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna).
+  Moved SSE2 optimization code into the main libpng source directory.
+    Configure libpng with "configure --enable-intel-sse" or compile
+    libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it.
+  Simplified conditional compilation in pngvalid.c, for AIX (Michael Felt).
+
+Version 1.6.29beta02 [February 22, 2017]
+  Avoid conditional directives that break statements in pngrutil.c (Romero
+    Malaquias)
+  The contrib/examples/pngtopng.c recovery code was in the wrong "if"
+    branches; the comments were correct.
+  Added code for PowerPC VSX optimisation (Vadim Barkov).
+
+Version 1.6.29beta03 [March 1, 2017]
+  Avoid potential overflow of shift operations in png_do_expand() (Aaron Boxer).
+  Change test ZLIB_VERNUM >= 0x1281 to ZLIB_VERNUM >= 0x1290 in pngrutil.c
+    because Solaris 11 distributes zlib-1.2.8.f that is older than 1.2.8.1,
+    as suggested in zlib FAQ, item 24.
+  Suppress clang warnings about implicit sign changes in png.c
+
+Version 1.6.29 [March 16, 2017]
+  No changes.
+
+Version 1.6.30beta01 [April 1, 2017]
+  Added missing "$(CPPFLAGS)" to the compile line for c.pic.o in
+    makefile.linux and makefile.solaris-x86 (Cosmin).
+  Revised documentation of png_get_error_ptr() in the libpng manual.
+  Silence clang -Wcomma and const drop warnings (Viktor Szakats).
+  Update Sourceforge URLs in documentation (https instead of http).
+
+Version 1.6.30beta02 [April 22, 2017]
+  Document need to check for integer overflow when allocating a pixel
+    buffer for multiple rows in contrib/gregbook, contrib/pngminus,
+    example.c, and in the manual (suggested by Jaeseung Choi). This
+    is similar to the bug reported against pngquant in CVE-2016-5735.
+  Removed reference to the obsolete PNG_SAFE_LIMITS macro in the documentation.
+
+Version 1.6.30beta03 [May 22, 2017]
+  Check for integer overflow in contrib/visupng and contrib/tools/genpng.
+  Do not double evaluate CMAKE_SYSTEM_PROCESSOR in CMakeLists.txt.
+  Test CMAKE_HOST_WIN32 instead of WIN32 in CMakeLists.txt.
+  Fix some URL in documentation.
+
+Version 1.6.30beta04 [June 7, 2017]
+  Avoid writing an empty IDAT when the last IDAT exactly fills the
+    compression buffer (bug report by Brian Baird). This bug was
+    introduced in libpng-1.6.0.
+
+Version 1.6.30rc01 [June 14, 2017]
+  No changes.
+
+Version 1.6.30rc02 [June 25, 2017]
+  Update copyright year in pnglibconf.h, make ltmain.sh executable.
+  Add a reference to the libpng.download site in README.
+
+Version 1.6.30 [June 28, 2017]
+  No changes.
+
+Version 1.6.31beta01 [July 5, 2017]
+  Guard the definition of _POSIX_SOURCE in pngpriv.h (AIX already defines it;
+    bug report by Michael Felt).
+  Revised pngpriv.h to work around failure to compile arm/filter_neon.S
+    ("typedef" directive is unrecognized by the assembler). The problem
+    was introduced in libpng-1.6.30beta01.
+  Added "Requires: zlib" to libpng.pc.in (Pieter Neerincx).
+  Added special case for FreeBSD in arm/filter_neon.S (Maya Rashish).
+
+Version 1.6.31beta02 [July 8, 2017]
+  Added instructions for disabling hardware optimizations in INSTALL.
+  Added "--enable-hardware-optimizations" configuration flag to enable
+    or disable all hardware optimizations with one flag.
+
+Version 1.6.31beta03 [July 9, 2017]
+  Updated CMakeLists.txt to add INTEL_SSE and MIPS_MSA platforms.
+  Changed "int" to "png_size_t" in intel/filter_sse2.c to prevent
+    possible integer overflow (Bug report by John Bowler).
+  Quieted "declaration after statement" warnings in intel/filter_sse2.c.
+  Added scripts/makefile-linux-opt, which has hardware optimizations enabled.
+
+Version 1.6.31beta04 [July 11, 2017]
+  Removed one of the GCC-7.1.0 'strict-overflow' warnings that result when
+    integers appear on both sides of a compare.  Worked around the others by
+    forcing the strict-overflow setting in the relevant functions to a level
+    where they are not reported (John Bowler).
+  Changed "FALL THROUGH" comments to "FALLTHROUGH" because GCC doesn't like
+    the space.
+  Worked around some C-style casts from (void*) because g++ 5.4.0 objects
+    to them.
+  Increased the buffer size for 'sprint' to pass the gcc 7.1.0 'sprint
+    overflow' check that is on by default with -Wall -Wextra.
+
+Version 1.6.31beta05 [July 13, 2017]
+  Added eXIf chunk support.
+
+Version 1.6.31beta06 [July 17, 2017]
+  Added a minimal eXIf chunk (with Orientation and FocalLengthIn35mmFilm
+    tags) to pngtest.png.
+
+Version 1.6.31beta07 [July 18, 2017]
+  Revised the eXIf chunk in pngtest.png to fix "Bad IFD1 Directory" warning.
+
+Version 1.6.31rc01 [July 19, 2017]
+  No changes.
+
+Version 1.6.31rc02 [July 25, 2017]
+  Fixed typo in example.c (png_free_image should be png_image_free) (Bug
+    report by John Smith)
+
+Version 1.6.31 [July 27, 2017]
+  No changes.
+
+Version 1.6.32beta01 [July 31, 2017]
+  Avoid possible NULL dereference in png_handle_eXIf when benign_errors
+    are allowed. Avoid leaking the input buffer "eXIf_buf".
+  Eliminated png_ptr->num_exif member from pngstruct.h and added num_exif
+    to arguments for png_get_eXIf() and png_set_eXIf().
+  Added calls to png_handle_eXIf(() in pngread.c and png_write_eXIf() in
+    pngwrite.c, and made various other fixes to png_write_eXIf().
+  Changed name of png_get_eXIF and png_set_eXIf() to png_get_eXIf_1() and
+    png_set_eXIf_1(), respectively, to avoid breaking API compatibility
+    with libpng-1.6.31.
+
+Version 1.6.32beta02 [August 1, 2017]
+  Updated contrib/libtests/pngunknown.c with eXIf chunk.
+
+Version 1.6.32beta03 [August 2, 2017]
+  Initialized btoa[] in pngstest.c
+  Stop memory leak when returning from png_handle_eXIf() with an error
+    (Bug report from the OSS-fuzz project).
+
+Version 1.6.32beta04 [August 2, 2017]
+  Replaced local eXIf_buf with info_ptr-eXIf_buf in png_handle_eXIf().
+  Update libpng.3 and libpng-manual.txt about eXIf functions.
+
+Version 1.6.32beta05 [August 2, 2017]
+  Restored png_get_eXIf() and png_set_eXIf() to maintain API compatibility.
+
+Version 1.6.32beta06 [August 2, 2017]
+  Removed png_get_eXIf_1() and png_set_eXIf_1().
+
+Version 1.6.32beta07 [August 3, 2017]
+  Check length of all chunks except IDAT against user limit to fix an
+    OSS-fuzz issue (Fixes CVE-2017-12652).
+
+Version 1.6.32beta08 [August 3, 2017]
+  Check length of IDAT against maximum possible IDAT size, accounting
+    for height, rowbytes, interlacing and zlib/deflate overhead.
+  Restored png_get_eXIf_1() and png_set_eXIf_1(), because strlen(eXIf_buf)
+    does not work (the eXIf chunk data can contain zeroes).
+
+Version 1.6.32beta09 [August 3, 2017]
+  Require cmake-2.8.8 in CMakeLists.txt. Revised symlink creation,
+    no longer using deprecated cmake LOCATION feature (Clifford Yapp).
+  Fixed five-byte error in the calculation of IDAT maximum possible size.
+  
+Version 1.6.32beta10 [August 5, 2017]
+  Moved chunk-length check into a png_check_chunk_length() private
+    function (Suggested by Max Stepin).
+  Moved bad pngs from tests to contrib/libtests/crashers
+  Moved testing of bad pngs into a separate tests/pngtest-badpngs script
+  Added the --xfail (expected FAIL) option to pngtest.c. It writes XFAIL
+    in the output but PASS for the libpng test.
+  Require cmake-3.0.2 in CMakeLists.txt (Clifford Yapp).
+  Fix "const" declaration info_ptr argument to png_get_eXIf_1() and the
+    num_exif argument to png_get_eXIf_1() (Github Issue 171).
+
+Version 1.6.32beta11 [August 7, 2017]
+  Added "eXIf" to "chunks_to_ignore[]" in png_set_keep_unknown_chunks().
+  Added huge_IDAT.png and empty_ancillary_chunks.png to testpngs/crashers.
+  Make pngtest --strict, --relax, --xfail options imply -m (multiple).
+  Removed unused chunk_name parameter from png_check_chunk_length().
+  Relocated setting free_me for eXIf data, to stop an OSS-fuzz leak.
+  Initialize profile_header[] in png_handle_iCCP() to fix OSS-fuzz issue.
+  Initialize png_ptr->row_buf[0] to 255 in png_read_row() to fix OSS-fuzz UMR.
+  Attempt to fix a UMR in png_set_text_2() to fix OSS-fuzz issue.
+  Increase minimum zlib stream from 9 to 14 in png_handle_iCCP(), to account
+    for the minimum 'deflate' stream, and relocate the test to a point
+    after the keyword has been read.
+  Check that the eXIf chunk has at least 2 bytes and begins with "II" or "MM".
+
+Version 1.6.32rc01 [August 18, 2017]
+  Added a set of "huge_xxxx_chunk.png" files to contrib/testpngs/crashers,
+    one for each known chunk type, with length = 2GB-1.
+  Check for 0 return from png_get_rowbytes() and added some (size_t) typecasts
+    in contrib/pngminus/*.c to stop some Coverity issues (162705, 162706,
+    and 162707).
+  Renamed chunks in contrib/testpngs/crashers to avoid having files whose
+    names differ only in case; this causes problems with some platforms
+    (github issue #172).
+
+Version 1.6.32rc02 [August 22, 2017]
+  Added contrib/oss-fuzz directory which contains files used by the oss-fuzz
+    project (https://github.com/google/oss-fuzz/tree/master/projects/libpng).
+
+Version 1.6.32 [August 24, 2017]
+  No changes.
+
+Version 1.6.33beta01 [August 28, 2017]
+  Added PNGMINUS_UNUSED macro to contrib/pngminus/p*.c and added missing
+    parenthesis in contrib/pngminus/pnm2png.c (bug report by Christian Hesse).
+  Fixed off-by-one error in png_do_check_palette_indexes() (Bug report
+    by Mick P., Source Forge Issue #269).
+
+Version 1.6.33beta02 [September 3, 2017]
+  Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc
+    to fix shortlived oss-fuzz issue 3234.
+  Compute a larger limit on IDAT because some applications write a deflate
+    buffer for each row (Bug report by Andrew Church).
+  Use current date (DATE) instead of release-date (RDATE) in last
+    changed date of contrib/oss-fuzz files.
+  Enabled ARM support in CMakeLists.txt (Bernd Kuhls).
+
+Version 1.6.33beta03 [September 14, 2017]
+  Fixed incorrect typecast of some arguments to png_malloc() and
+    png_calloc() that were png_uint_32 instead of png_alloc_size_t
+    (Bug report by "irwir" in Github libpng issue #175).
+  Use pnglibconf.h.prebuilt when building for ANDROID with cmake (Github
+    issue 162, by rcdailey).
+
+Version 1.6.33rc01 [September 20, 2017]
+  Initialize memory allocated by png_inflate to zero, using memset, to
+    stop an oss-fuzz "use of uninitialized value" detection in png_set_text_2()
+    due to truncated iTXt or zTXt chunk.
+  Initialize memory allocated by png_read_buffer to zero, using memset, to
+    stop an oss-fuzz "use of uninitialized value" detection in
+    png_icc_check_tag_table() due to truncated iCCP chunk.
+  Removed a redundant test (suggested by "irwir" in Github issue #180).
+
+Version 1.6.33rc02 [September 23, 2017]
+  Added an interlaced version of each file in contrib/pngsuite.
+  Relocate new memset() call in pngrutil.c.
+  Removed more redundant tests (suggested by "irwir" in Github issue #180).
+  Add support for loading images with associated alpha in the Simplified
+    API (Samuel Williams).
+
+Version 1.6.33 [September 28, 2017]
+  Revert contrib/oss-fuzz/libpng_read_fuzzer.cc to libpng-1.6.32 state.
+  Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc
+  Add end_info structure and png_read_end() to the libpng fuzzer.
+
+Version 1.6.34 [September 29, 2017]
+  Removed contrib/pngsuite/i*.png; some of them caused test failures.
+
+Version 1.6.35beta01 [March 6, 2018]
+  Restored 21 of the contrib/pngsuite/i*.png, which do not cause test
+    failures. Placed the remainder in contrib/pngsuite/interlaced/i*.png.
+  Added calls to png_set_*() transforms commonly used by browsers to
+    the fuzzer.
+  Removed some unnecessary brackets in pngrtran.c
+  Fixed miscellaneous typos (Patch by github user "luzpaz").
+  Change "ASM C" to "C ASM" in CMakeLists.txt
+  Fixed incorrect handling of bKGD chunk in sub-8-bit files (Cosmin)
+  Added hardware optimization directories to zip and 7z distributions.
+  Fixed incorrect bitmask for options.
+  Fixed many spelling typos.
+
+Version 1.6.35beta02 [March 28, 2018]
+  Make png_get_iCCP consistent with man page (allow compression-type argument
+  to be NULL, bug report by Lenard Szolnoki).
+
+Version 1.6.35 [July 15, 2018]
+  Replaced the remaining uses of png_size_t with size_t (Cosmin)
+  Fixed the calculation of row_factor in png_check_chunk_length
+    (reported by Thuan Pham in SourceForge issue #278)
+  Added missing parentheses to a macro definition
+    (suggested by "irwir" in GitHub issue #216)
+
+Version 1.6.36 [December 1, 2018]
+  Optimized png_do_expand_palette for ARM processors.
+  Improved performance by around 10-22% on a recent ARM Chromebook.
+  (Contributed by Richard Townsend, ARM Holdings)
+  Fixed manipulation of machine-specific optimization options.
+  (Contributed by Vicki Pfau)
+  Used memcpy instead of manual pointer arithmetic on Intel SSE2.
+  (Contributed by Samuel Williams)
+  Fixed build errors with MSVC on ARM64.
+  (Contributed by Zhijie Liang)
+  Fixed detection of libm in CMakeLists.
+  (Contributed by Cameron Cawley)
+  Fixed incorrect creation of pkg-config file in CMakeLists.
+  (Contributed by Kyle Bentley)
+  Fixed the CMake build on Windows MSYS by avoiding symlinks.
+  Fixed a build warning on OpenBSD.
+  (Contributed by Theo Buehler)
+  Fixed various typos in comments.
+  (Contributed by "luz.paz")
+  Raised the minimum required CMake version from 3.0.2 to 3.1.
+  Removed yet more of the vestigial support for pre-ANSI C compilers.
+  Removed ancient makefiles for ancient systems that have been broken
+  across all previous libpng-1.6.x versions.
+  Removed the Y2K compliance statement and the export control
+  information.
+  Applied various code style and documentation fixes.
+
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
-to subscribe)
-or to glennrp at users.sourceforge.net
-
-Glenn R-P
-#endif
+to subscribe).
index 2f180b5..73044c9 100644 (file)
@@ -1,39 +1,52 @@
 # CMakeLists.txt
 
-# Copyright (C) 2007-2015 Glenn Randers-Pehrson
+# Copyright (C) 2018 Cosmin Truta
+# Copyright (C) 2007,2009-2018 Glenn Randers-Pehrson
+# Written by Christian Ehrlicher, 2007
+# Revised by Roger Lowman, 2009-2010
+# Revised by Clifford Yapp, 2011-2012,2017
+# Revised by Roger Leigh, 2016
+# Revised by Andreas Franek, 2016
+# Revised by Sam Serrels, 2017
+# Revised by Vadim Barkov, 2017
+# Revised by Vicky Pfau, 2018
+# Revised by Cameron Cawley, 2018
+# Revised by Cosmin Truta, 2018
+# Revised by Kyle Bentley, 2018
 
 # This code is released under the libpng license.
 # For conditions of distribution and use, see the disclaimer
 # and license in png.h
 
-cmake_minimum_required(VERSION 2.4.4)
-set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
+cmake_minimum_required(VERSION 3.1)
+cmake_policy(VERSION 3.1)
 
-set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")
-
-project(libpng C)
+project(libpng C ASM)
 enable_testing()
 
 set(PNGLIB_MAJOR 1)
 set(PNGLIB_MINOR 6)
-set(PNGLIB_RELEASE 21)
+set(PNGLIB_RELEASE 36)
 set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
 set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
 
+include(GNUInstallDirs)
+
 # needed packages
-find_package(ZLIB REQUIRED)
-include_directories(${ZLIB_INCLUDE_DIR})
-
-if(NOT WIN32)
-  find_library(M_LIBRARY
-    NAMES m
-    PATHS /usr/lib /usr/local/lib
-  )
-  if(NOT M_LIBRARY)
-    message(STATUS "math lib 'libm' not found; floating point support disabled")
-  endif()
+
+# Allow users to specify location of Zlib.
+# Useful if zlib is being built alongside this as a sub-project.
+option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" OFF)
+
+if(NOT PNG_BUILD_ZLIB)
+  find_package(ZLIB REQUIRED)
+  include_directories(${ZLIB_INCLUDE_DIR})
+endif()
+
+if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
+  find_library(M_LIBRARY m)
 else()
-  # not needed on windows
+  # libm is not needed and/or not available
   set(M_LIBRARY "")
 endif()
 
@@ -44,8 +57,144 @@ option(PNG_TESTS  "Build libpng tests" ON)
 
 # Many more configuration options could be added here
 option(PNG_FRAMEWORK "Build OS X framework" OFF)
-option(PNG_DEBUG     "Build with debug output" OFF)
-option(PNGARG        "Disable ANSI-C prototypes" OFF)
+option(PNG_DEBUG "Build with debug output" OFF)
+option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON)
+
+set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names")
+set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings")
+
+if(PNG_HARDWARE_OPTIMIZATIONS)
+
+# set definitions and sources for arm
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
+  CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
+  set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
+  set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations:
+     check: (default) use internal checking code;
+     off: disable the optimizations;
+     on: turn on unconditionally.")
+  set_property(CACHE PNG_ARM_NEON PROPERTY STRINGS
+     ${PNG_ARM_NEON_POSSIBLE_VALUES})
+  list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index)
+  if(index EQUAL -1)
+    message(FATAL_ERROR
+            "PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]")
+  elseif(NOT ${PNG_ARM_NEON} STREQUAL "off")
+    set(libpng_arm_sources
+      arm/arm_init.c
+      arm/filter_neon.S
+      arm/filter_neon_intrinsics.c
+      arm/palette_neon_intrinsics.c)
+
+    if(${PNG_ARM_NEON} STREQUAL "on")
+      add_definitions(-DPNG_ARM_NEON_OPT=2)
+    elseif(${PNG_ARM_NEON} STREQUAL "check")
+      add_definitions(-DPNG_ARM_NEON_CHECK_SUPPORTED)
+    endif()
+  else()
+    add_definitions(-DPNG_ARM_NEON_OPT=0)
+  endif()
+endif()
+
+# set definitions and sources for powerpc
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
+   CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
+  set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
+  set(PNG_POWERPC_VSX "on" CACHE STRING "Enable POWERPC VSX optimizations:
+     off: disable the optimizations.")
+  set_property(CACHE PNG_POWERPC_VSX PROPERTY STRINGS
+     ${PNG_POWERPC_VSX_POSSIBLE_VALUES})
+  list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index)
+  if(index EQUAL -1)
+    message(FATAL_ERROR
+            "PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]")
+  elseif(NOT ${PNG_POWERPC_VSX} STREQUAL "off")
+    set(libpng_powerpc_sources
+      powerpc/powerpc_init.c
+      powerpc/filter_vsx_intrinsics.c)
+    if(${PNG_POWERPC_VSX} STREQUAL "on")
+      add_definitions(-DPNG_POWERPC_VSX_OPT=2)
+    endif()
+  else()
+    add_definitions(-DPNG_POWERPC_VSX_OPT=0)
+  endif()
+endif()
+
+# set definitions and sources for intel
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
+   CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
+  set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
+  set(PNG_INTEL_SSE "on" CACHE STRING "Enable INTEL_SSE optimizations:
+     off: disable the optimizations")
+  set_property(CACHE PNG_INTEL_SSE PROPERTY STRINGS
+     ${PNG_INTEL_SSE_POSSIBLE_VALUES})
+  list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index)
+  if(index EQUAL -1)
+    message(FATAL_ERROR
+            "PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]")
+  elseif(NOT ${PNG_INTEL_SSE} STREQUAL "off")
+    set(libpng_intel_sources
+      intel/intel_init.c
+      intel/filter_sse2_intrinsics.c)
+    if(${PNG_INTEL_SSE} STREQUAL "on")
+      add_definitions(-DPNG_INTEL_SSE_OPT=1)
+    endif()
+  else()
+    add_definitions(-DPNG_INTEL_SSE_OPT=0)
+  endif()
+endif()
+
+# set definitions and sources for MIPS
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
+   CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
+  set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
+  set(PNG_MIPS_MSA "on" CACHE STRING "Enable MIPS_MSA optimizations:
+     off: disable the optimizations")
+  set_property(CACHE PNG_MIPS_MSA PROPERTY STRINGS
+     ${PNG_MIPS_MSA_POSSIBLE_VALUES})
+  list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index)
+  if(index EQUAL -1)
+    message(FATAL_ERROR
+            "PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]")
+  elseif(NOT ${PNG_MIPS_MSA} STREQUAL "off")
+    set(libpng_mips_sources
+      mips/mips_init.c
+      mips/filter_msa_intrinsics.c)
+    if(${PNG_MIPS_MSA} STREQUAL "on")
+      add_definitions(-DPNG_MIPS_MSA_OPT=2)
+    endif()
+  else()
+    add_definitions(-DPNG_MIPS_MSA_OPT=0)
+  endif()
+endif()
+
+else(PNG_HARDWARE_OPTIMIZATIONS)
+
+# set definitions and sources for arm
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
+   CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
+  add_definitions(-DPNG_ARM_NEON_OPT=0)
+endif()
+
+# set definitions and sources for powerpc
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
+   CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
+  add_definitions(-DPNG_POWERPC_VSX_OPT=0)
+endif()
+
+# set definitions and sources for intel
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
+   CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
+  add_definitions(-DPNG_INTEL_SSE_OPT=0)
+endif()
+
+# set definitions and sources for MIPS
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
+   CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
+  add_definitions(-DPNG_MIPS_MSA_OPT=0)
+endif()
+
+endif(PNG_HARDWARE_OPTIMIZATIONS)
 
 # SET LIBNAME
 set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
@@ -53,26 +202,275 @@ set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
 # to distinguish between debug and release lib
 set(CMAKE_DEBUG_POSTFIX "d")
 
-# Use the prebuilt pnglibconf.h file from the scripts folder
-# TODO: fix this by building with awk; without this no cmake build can be
-# configured directly (to do so indirectly use your local awk to build a
-# pnglibconf.h in the build directory.)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
-               ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
+include(CheckCSourceCompiles)
+option(ld-version-script "Enable linker version script" ON)
+if(ld-version-script AND NOT APPLE)
+  # Check if LD supports linker scripts.
+  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" "VERS_1 {
+        global: sym;
+        local: *;
+};
+
+VERS_2 {
+        global: sym2;
+                main;
+} VERS_1;
+")
+  set(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})
+  set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'")
+  check_c_source_compiles("void sym(void) {}
+void sym2(void) {}
+int main(void) {return 0;}
+" HAVE_LD_VERSION_SCRIPT)
+  if(NOT HAVE_LD_VERSION_SCRIPT)
+    set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE} "-Wl,-M -Wl,${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
+  check_c_source_compiles("void sym(void) {}
+void sym2(void) {}
+int main(void) {return 0;}
+" HAVE_SOLARIS_LD_VERSION_SCRIPT)
+  endif()
+  set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})
+  file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
+endif()
+
+# Find symbol prefix.  Likely obsolete and unnecessary with recent
+# toolchains (it's not done in many other projects).
+function(symbol_prefix)
+  set(SYMBOL_PREFIX)
+
+  execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E" "-"
+                  INPUT_FILE /dev/null
+                  OUTPUT_VARIABLE OUT
+                  RESULT_VARIABLE STATUS)
+
+  if(CPP_FAIL)
+    message(WARNING "Failed to run the C preprocessor")
+  endif()
+
+  string(REPLACE "\n" ";" OUT "${OUT}")
+  foreach(line ${OUT})
+    string(REGEX MATCH "^PREFIX=" found_match "${line}")
+    if(found_match)
+      string(REGEX REPLACE "^PREFIX=(.*\)" "\\1" prefix "${line}")
+      string(REGEX MATCH "__USER_LABEL_PREFIX__" found_match "${prefix}")
+      if(found_match)
+        string(REGEX REPLACE "(.*)__USER_LABEL_PREFIX__(.*)" "\\1\\2" prefix "${prefix}")
+      endif()
+      set(SYMBOL_PREFIX "${prefix}")
+    endif()
+  endforeach()
+
+  message(STATUS "Symbol prefix: ${SYMBOL_PREFIX}")
+  set(SYMBOL_PREFIX "${SYMBOL_PREFIX}" PARENT_SCOPE)
+endfunction()
+
+if(UNIX)
+  symbol_prefix()
+endif()
+
+find_program(AWK NAMES gawk awk)
+
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
+if(NOT AWK OR ANDROID)
+  # No awk available to generate sources; use pre-built pnglibconf.h
+  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
+                 ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
+  add_custom_target(genfiles) # Dummy
+else()
+  include(CMakeParseArguments)
+  # Generate .chk from .out with awk
+  # generate_chk(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
+  function(generate_chk)
+    set(options)
+    set(oneValueArgs INPUT OUTPUT)
+    set(multiValueArgs DEPENDS)
+    cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    if(NOT _GC_INPUT)
+      message(FATAL_ERROR "generate_chk: Missing INPUT argument")
+    endif()
+    if(NOT _GC_OUTPUT)
+      message(FATAL_ERROR "generate_chk: Missing OUTPUT argument")
+    endif()
+
+    add_custom_command(OUTPUT "${_GC_OUTPUT}"
+                       COMMAND "${CMAKE_COMMAND}"
+                               "-DINPUT=${_GC_INPUT}"
+                               "-DOUTPUT=${_GC_OUTPUT}"
+                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake"
+                       DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS}
+                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+  endfunction()
+
+  # Generate .out from .c with awk
+  # generate_out(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
+  function(generate_out)
+    set(options)
+    set(oneValueArgs INPUT OUTPUT)
+    set(multiValueArgs DEPENDS)
+    cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    if(NOT _GO_INPUT)
+      message(FATAL_ERROR "generate_out: Missing INPUT argument")
+    endif()
+    if(NOT _GO_OUTPUT)
+      message(FATAL_ERROR "generate_out: Missing OUTPUT argument")
+    endif()
+
+    add_custom_command(OUTPUT "${_GO_OUTPUT}"
+                       COMMAND "${CMAKE_COMMAND}"
+                               "-DINPUT=${_GO_INPUT}"
+                               "-DOUTPUT=${_GO_OUTPUT}"
+                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake"
+                       DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS}
+                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+  endfunction()
+
+  # Generate specific source file with awk
+  # generate_source(OUTPUT outputfile [DEPENDS dep1 [dep2...]])
+  function(generate_source)
+    set(options)
+    set(oneValueArgs OUTPUT)
+    set(multiValueArgs DEPENDS)
+    cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    if(NOT _GSO_OUTPUT)
+      message(FATAL_ERROR "generate_source: Missing OUTPUT argument")
+    endif()
+
+    add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}"
+                       COMMAND "${CMAKE_COMMAND}"
+                               "-DOUTPUT=${_GSO_OUTPUT}"
+                               -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake"
+                       DEPENDS ${_GSO_DEPENDS}
+                       WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+  endfunction()
+
+  # Copy file
+  function(generate_copy source destination)
+    add_custom_command(OUTPUT "${destination}"
+                       COMMAND "${CMAKE_COMMAND}" -E remove "${destination}"
+                       COMMAND "${CMAKE_COMMAND}" -E copy "${source}"
+                                                          "${destination}"
+                       DEPENDS "${source}")
+  endfunction()
+
+  # Generate scripts/pnglibconf.h
+  generate_source(OUTPUT "scripts/pnglibconf.c"
+                  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
+
+  # Generate pnglibconf.c
+  generate_source(OUTPUT "pnglibconf.c"
+                  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
+                          "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
+
+  if(PNG_PREFIX)
+    set(PNGLIBCONF_H_EXTRA_DEPENDS
+        "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
+        "${CMAKE_CURRENT_SOURCE_DIR}/scripts/macro.lst")
+    set(PNGPREFIX_H_EXTRA_DEPENDS
+        "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out")
+  endif()
+
+  generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
+               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
+
+  # Generate pnglibconf.h
+  generate_source(OUTPUT "pnglibconf.h"
+                  DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
+                          ${PNGLIBCONF_H_EXTRA_DEPENDS})
+
+  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c"
+               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
+               DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
+
+  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c"
+               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
+               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
+                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
+                       "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
+
+  # Generate pngprefix.h
+  generate_source(OUTPUT "pngprefix.h"
+                  DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS})
+
+  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c"
+               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
+               DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
+
+  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c"
+               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
+               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
+                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
+                       "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt")
+
+  generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c"
+               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
+               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
+                       "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
+                       "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
+
+  generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
+               OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
+               DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk"
+                       "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def")
+
+  add_custom_target(symbol-check DEPENDS
+                    "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk")
+
+  generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
+                "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
+  generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
+                "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
+
+  add_custom_target(genvers DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
+  add_custom_target(gensym DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
+
+  add_custom_target("genprebuilt"
+                    COMMAND "${CMAKE_COMMAND}"
+                            "-DOUTPUT=scripts/pnglibconf.h.prebuilt"
+                            -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake"
+                    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+
+  # A single target handles generation of all generated files.  If
+  # they are depended upon separately by multiple targets, this
+  # confuses parallel make (it would require a separate top-level
+  # target for each file to track the dependencies properly).
+  add_custom_target(genfiles DEPENDS
+    "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym"
+    "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
+    "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
+    "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
+    "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
+    "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h"
+    "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
+    "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c"
+    "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
+    "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
+    "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
+    "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
+    "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
+endif(NOT AWK OR ANDROID)
+
 # OUR SOURCES
 set(libpng_public_hdrs
   png.h
   pngconf.h
-  ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h
+  "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
 )
-set(libpng_sources
-  ${libpng_public_hdrs}
+set(libpng_private_hdrs
+  pngpriv.h
   pngdebug.h
   pnginfo.h
-  pngpriv.h
   pngstruct.h
+)
+if(AWK AND NOT ANDROID)
+  list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
+endif()
+set(libpng_sources
+  ${libpng_public_hdrs}
+  ${libpng_private_hdrs}
   png.c
   pngerror.c
   pngget.c
@@ -88,6 +486,10 @@ set(libpng_sources
   pngwrite.c
   pngwtran.c
   pngwutil.c
+  ${libpng_arm_sources}
+  ${libpng_intel_sources}
+  ${libpng_mips_sources}
+  ${libpng_powerpc_sources}
 )
 set(pngtest_sources
   pngtest.c
@@ -98,11 +500,22 @@ set(pngvalid_sources
 set(pngstest_sources
   contrib/libtests/pngstest.c
 )
-# SOME NEEDED DEFINITIONS
+set(pngunknown_sources
+  contrib/libtests/pngunknown.c
+)
+set(pngimage_sources
+  contrib/libtests/pngimage.c
+)
+set(pngfix_sources
+  contrib/tools/pngfix.c
+)
+set(png_fix_itxt_sources
+  contrib/tools/png-fix-itxt.c
+)
 
 if(MSVC)
   add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
-endif(MSVC)
+endif()
 
 if(PNG_DEBUG)
   add_definitions(-DPNG_DEBUG)
@@ -114,33 +527,59 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIR})
 unset(PNG_LIB_TARGETS)
 
 if(PNG_SHARED)
-  add_library(${PNG_LIB_NAME} SHARED ${libpng_sources})
-  set(PNG_LIB_TARGETS ${PNG_LIB_NAME})
+  add_library(png SHARED ${libpng_sources})
+  set(PNG_LIB_TARGETS png)
+  set_target_properties(png PROPERTIES OUTPUT_NAME ${PNG_LIB_NAME})
+  add_dependencies(png genfiles)
   if(MSVC)
     # msvc does not append 'lib' - do it here to have consistent name
-    set_target_properties(${PNG_LIB_NAME} PROPERTIES PREFIX "lib")
-    set_target_properties(${PNG_LIB_NAME} PROPERTIES IMPORT_PREFIX "lib")
+    set_target_properties(png PROPERTIES PREFIX "lib")
+    set_target_properties(png PROPERTIES IMPORT_PREFIX "lib")
+  endif()
+  target_link_libraries(png ${ZLIB_LIBRARY} ${M_LIBRARY})
+
+  if(UNIX AND AWK)
+    if(HAVE_LD_VERSION_SCRIPT)
+      set_target_properties(png PROPERTIES LINK_FLAGS
+        "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
+    elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT)
+      set_target_properties(png PROPERTIES LINK_FLAGS
+        "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
+    endif()
   endif()
-  target_link_libraries(${PNG_LIB_NAME} ${ZLIB_LIBRARY} ${M_LIBRARY})
 endif()
 
 if(PNG_STATIC)
   # does not work without changing name
-  set(PNG_LIB_NAME_STATIC ${PNG_LIB_NAME}_static)
-  add_library(${PNG_LIB_NAME_STATIC} STATIC ${libpng_sources})
-  list(APPEND PNG_LIB_TARGETS ${PNG_LIB_NAME_STATIC})
+  set(PNG_LIB_NAME_STATIC png_static)
+  add_library(png_static STATIC ${libpng_sources})
+  add_dependencies(png_static genfiles)
+  # MSVC doesn't use a different file extension for shared vs. static
+  # libs.  We are able to change OUTPUT_NAME to remove the _static
+  # for all other platforms.
+  if(NOT MSVC)
+    set_target_properties(png_static PROPERTIES
+      OUTPUT_NAME "${PNG_LIB_NAME}"
+      CLEAN_DIRECT_OUTPUT 1)
+  else()
+    set_target_properties(png_static PROPERTIES
+      OUTPUT_NAME "${PNG_LIB_NAME}_static"
+      CLEAN_DIRECT_OUTPUT 1)
+  endif()
+  list(APPEND PNG_LIB_TARGETS png_static)
   if(MSVC)
     # msvc does not append 'lib' - do it here to have consistent name
-    set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES PREFIX "lib")
+    set_target_properties(png_static PROPERTIES PREFIX "lib")
   endif()
-  target_link_libraries(${PNG_LIB_NAME_STATIC} ${ZLIB_LIBRARY} ${M_LIBRARY})
+  target_link_libraries(png_static ${ZLIB_LIBRARY} ${M_LIBRARY})
 endif()
 
 if(PNG_FRAMEWORK)
-  set(PNG_LIB_NAME_FRAMEWORK ${PNG_LIB_NAME}_framework)
-  add_library(${PNG_LIB_NAME_FRAMEWORK} SHARED ${libpng_sources})
-  list(APPEND PNG_LIB_TARGETS ${PNG_LIB_NAME_FRAMEWORK})
-  set_target_properties(${PNG_LIB_NAME_FRAMEWORK} PROPERTIES
+  set(PNG_LIB_NAME_FRAMEWORK png_framework)
+  add_library(png_framework SHARED ${libpng_sources})
+  add_dependencies(png_framework genfiles)
+  list(APPEND PNG_LIB_TARGETS png_framework)
+  set_target_properties(png_framework PROPERTIES
     FRAMEWORK TRUE
     FRAMEWORK_VERSION ${PNGLIB_VERSION}
     MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PNGLIB_MAJOR}.${PNGLIB_MINOR}
@@ -149,200 +588,320 @@ if(PNG_FRAMEWORK)
     XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
     PUBLIC_HEADER "${libpng_public_hdrs}"
     OUTPUT_NAME png)
-  target_link_libraries(${PNG_LIB_NAME_FRAMEWORK} ${ZLIB_LIBRARY} ${M_LIBRARY})
+  target_link_libraries(png_framework ${ZLIB_LIBRARY} ${M_LIBRARY})
 endif()
 
 if(NOT PNG_LIB_TARGETS)
   message(SEND_ERROR
     "No library variant selected to build. "
     "Please enable at least one of the following options: "
-    " PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK")
+    "PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK")
 endif()
 
 if(PNG_SHARED AND WIN32)
-  set_target_properties(${PNG_LIB_NAME} PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
+  set_target_properties(png PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
 endif()
 
+function(png_add_test)
+  set(options)
+  set(oneValueArgs NAME COMMAND)
+  set(multiValueArgs OPTIONS FILES)
+  cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+  if(NOT _PAT_NAME)
+    message(FATAL_ERROR "png_add_test: Missing NAME argument")
+  endif()
+  if(NOT _PAT_COMMAND)
+    message(FATAL_ERROR "png_add_test: Missing COMMAND argument")
+  endif()
+
+  set(TEST_OPTIONS "${_PAT_OPTIONS}")
+  set(TEST_FILES "${_PAT_FILES}")
+
+  configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/test.cmake.in"
+                 "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" @ONLY)
+  add_test(NAME "${_PAT_NAME}"
+           COMMAND "${CMAKE_COMMAND}"
+           "-DLIBPNG=$<TARGET_FILE:png>"
+           "-DTEST_COMMAND=$<TARGET_FILE:${_PAT_COMMAND}>"
+           -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
+endfunction()
+
 if(PNG_TESTS AND PNG_SHARED)
-  # does not work with msvc due to png_lib_ver issue
+  # Find test PNG files by globbing, but sort lists to ensure
+  # consistency between different filesystems.
+  file(GLOB PNGSUITE_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/*.png")
+  list(SORT PNGSUITE_PNGS)
+  file(GLOB TEST_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/*.png")
+  list(SORT TEST_PNGS)
+
+  set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png")
+
   add_executable(pngtest ${pngtest_sources})
-  target_link_libraries(pngtest ${PNG_LIB_NAME})
-  add_test(pngtest ./pngtest ${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png)
-  #
+  target_link_libraries(pngtest png)
+
+  png_add_test(NAME pngtest COMMAND pngtest FILES "${PNGTEST_PNG}")
+
   add_executable(pngvalid ${pngvalid_sources})
-  target_link_libraries(pngvalid ${PNG_LIB_NAME})
-  add_test(pngvalid ./pngvalid)
+  target_link_libraries(pngvalid png)
+
+  png_add_test(NAME pngvalid-gamma-16-to-8
+               COMMAND pngvalid OPTIONS --gamma-16-to-8)
+  png_add_test(NAME pngvalid-gamma-alpha-mode
+               COMMAND pngvalid OPTIONS --gamma-alpha-mode)
+  png_add_test(NAME pngvalid-gamma-background
+               COMMAND pngvalid OPTIONS --gamma-background)
+  png_add_test(NAME pngvalid-gamma-expand16-alpha-mode
+               COMMAND pngvalid OPTIONS --gamma-alpha-mode --expand16)
+  png_add_test(NAME pngvalid-gamma-expand16-background
+               COMMAND pngvalid OPTIONS --gamma-background --expand16)
+  png_add_test(NAME pngvalid-gamma-expand16-transform
+               COMMAND pngvalid OPTIONS --gamma-transform --expand16)
+  png_add_test(NAME pngvalid-gamma-sbit
+               COMMAND pngvalid OPTIONS --gamma-sbit)
+  png_add_test(NAME pngvalid-gamma-threshold
+               COMMAND pngvalid OPTIONS --gamma-threshold)
+  png_add_test(NAME pngvalid-gamma-transform
+               COMMAND pngvalid OPTIONS --gamma-transform)
+  png_add_test(NAME pngvalid-progressive-interlace-standard
+               COMMAND pngvalid OPTIONS --standard --progressive-read --interlace)
+  png_add_test(NAME pngvalid-progressive-size
+               COMMAND pngvalid OPTIONS --size --progressive-read)
+  png_add_test(NAME pngvalid-progressive-standard
+               COMMAND pngvalid OPTIONS --standard --progressive-read)
+  png_add_test(NAME pngvalid-standard
+               COMMAND pngvalid OPTIONS --standard)
+  png_add_test(NAME pngvalid-transform
+               COMMAND pngvalid OPTIONS --transform)
+
   add_executable(pngstest ${pngstest_sources})
-  target_link_libraries(pngstest ${PNG_LIB_NAME})
-  add_test(pngstest ./pngstest
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g01.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g02.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g04.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn0g16.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn2c08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn2c16.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p01.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p02.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p04.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn3p08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn4a08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn4a16.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn6a08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/basn6a16.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g01.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g02.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn0g04.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn2c16.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbbn3p08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbgn2c16.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbgn3p08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbrn2c08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbwn0g16.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbwn3p08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftbyn3p08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n0g08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n2c08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp0n3p08.png
-    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/ftp1n3p08.png
-  )
+  target_link_libraries(pngstest png)
+
+  foreach(gamma_type 1.8 linear none sRGB)
+    foreach(alpha_type none alpha)
+      set(PNGSTEST_FILES)
+      foreach(test_png ${TEST_PNGS})
+        string(REGEX MATCH ".*-linear[-.].*" TEST_PNG_LINEAR "${test_png}")
+        string(REGEX MATCH ".*-sRGB[-.].*" TEST_PNG_SRGB "${test_png}")
+        string(REGEX MATCH ".*-1.8[-.].*" TEST_PNG_G18 "${test_png}")
+        string(REGEX MATCH ".*-alpha-.*" TEST_PNG_ALPHA "${test_png}")
+
+        set(TEST_PNG_VALID TRUE)
+
+        if(TEST_PNG_ALPHA)
+          if(NOT "${alpha_type}" STREQUAL "alpha")
+            set(TEST_PNG_VALID FALSE)
+          endif()
+        else()
+          if("${alpha_type}" STREQUAL "alpha")
+            set(TEST_PNG_VALID FALSE)
+          endif()
+        endif()
+
+        if(TEST_PNG_LINEAR)
+          if(NOT "${gamma_type}" STREQUAL "linear")
+            set(TEST_PNG_VALID FALSE)
+          endif()
+        elseif(TEST_PNG_SRGB)
+          if(NOT "${gamma_type}" STREQUAL "sRGB")
+            set(TEST_PNG_VALID FALSE)
+          endif()
+        elseif(TEST_PNG_G18)
+          if(NOT "${gamma_type}" STREQUAL "1.8")
+            set(TEST_PNG_VALID FALSE)
+          endif()
+        else()
+          if(NOT "${gamma_type}" STREQUAL "none")
+            set(TEST_PNG_VALID FALSE)
+          endif()
+        endif()
+
+        if(TEST_PNG_VALID)
+          list(APPEND PNGSTEST_FILES "${test_png}")
+        endif()
+      endforeach()
+      # Should already be sorted, but sort anyway to be certain.
+      list(SORT PNGSTEST_FILES)
+      png_add_test(NAME pngstest-${gamma_type}-${alpha_type}
+                   COMMAND pngstest
+                   OPTIONS --tmpfile "${gamma_type}-${alpha_type}-" --log
+                   FILES ${PNGSTEST_FILES})
+    endforeach()
+  endforeach()
+
+  add_executable(pngunknown ${pngunknown_sources})
+  target_link_libraries(pngunknown png)
+
+  png_add_test(NAME pngunknown-discard COMMAND pngunknown OPTIONS --strict default=discard FILES "${PNGTEST_PNG}")
+  png_add_test(NAME pngunknown-IDAT COMMAND pngunknown OPTIONS --strict default=discard IDAT=save FILES "${PNGTEST_PNG}")
+  png_add_test(NAME pngunknown-if-safe COMMAND pngunknown OPTIONS --strict default=if-safe FILES "${PNGTEST_PNG}")
+  png_add_test(NAME pngunknown-sAPI COMMAND pngunknown OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save FILES "${PNGTEST_PNG}")
+  png_add_test(NAME pngunknown-save COMMAND pngunknown OPTIONS --strict default=save FILES "${PNGTEST_PNG}")
+  png_add_test(NAME pngunknown-sTER COMMAND pngunknown OPTIONS --strict sTER=if-safe FILES "${PNGTEST_PNG}")
+  png_add_test(NAME pngunknown-vpAg COMMAND pngunknown OPTIONS --strict vpAg=if-safe FILES "${PNGTEST_PNG}")
+
+  add_executable(pngimage ${pngimage_sources})
+  target_link_libraries(pngimage png)
+
+  png_add_test(NAME pngimage-quick COMMAND pngimage OPTIONS --list-combos --log FILES ${PNGSUITE_PNGS})
+  png_add_test(NAME pngimage-full COMMAND pngimage OPTIONS --exhaustive --list-combos --log FILES ${PNGSUITE_PNGS})
 endif()
 
-# Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set
-IF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
-  SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
-ENDIF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
+if(PNG_SHARED)
+  add_executable(pngfix ${pngfix_sources})
+  target_link_libraries(pngfix png)
+  set(PNG_BIN_TARGETS pngfix)
+
+  add_executable(png-fix-itxt ${png_fix_itxt_sources})
+  target_link_libraries(png-fix-itxt ${ZLIB_LIBRARY} ${M_LIBRARY})
+  list(APPEND PNG_BIN_TARGETS png-fix-itxt)
+endif()
 
 # Set a variable with CMake code which:
 # Creates a symlink from src to dest (if possible) or alternatively
 # copies if different.
-macro(CREATE_SYMLINK SRC_FILE DEST_FILE)
-  FILE(REMOVE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})
-  if(WIN32 AND NOT CYGWIN AND NOT MSYS)
-    ADD_CUSTOM_COMMAND(
-        OUTPUT ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}   ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE}
-        COMMAND ${CMAKE_COMMAND} -E copy_if_different  "${SRC_FILE}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}
-        COMMAND ${CMAKE_COMMAND} -E copy_if_different  "${SRC_FILE}" ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE}
-        DEPENDS ${PNG_LIB_TARGETS}
-        )
-    ADD_CUSTOM_TARGET(${DEST_FILE}_COPY ALL DEPENDS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})
-  else(WIN32 AND NOT CYGWIN AND NOT MSYS)
-    get_filename_component(LINK_TARGET "${SRC_FILE}" NAME)
-    execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
-    execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-    execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-  endif(WIN32 AND NOT CYGWIN AND NOT MSYS)
-endmacro()
+include(CMakeParseArguments)
+
+function(create_symlink DEST_FILE)
+
+  cmake_parse_arguments(S "" "FILE;TARGET" "" ${ARGN})
+
+  if(NOT S_TARGET AND NOT S_FILE)
+    message(FATAL_ERROR "create_symlink: Missing TARGET or FILE argument")
+  endif()
+
+  if(S_TARGET AND S_FILE)
+    message(FATAL_ERROR "create_symlink: Both source file ${S_FILE} and build target ${S_TARGET} arguments are present; can only have one.")
+  endif()
+
+  if(S_FILE)
+    # If we don't need to symlink something that's coming from a build target,
+    # we can go ahead and symlink/copy at configure time.
+    if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
+      execute_process(
+        COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${S_FILE} ${DEST_FILE}
+        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+    else()
+      execute_process(
+        COMMAND ${CMAKE_COMMAND} -E create_symlink ${S_FILE} ${DEST_FILE}
+        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+    endif()
+  endif()
+
+  if(S_TARGET)
+    # We need to use generator expressions, which can be a bit tricky, so for
+    # simplicity make the symlink a POST_BUILD step and use the TARGET
+    # signature of add_custom_command.
+    if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
+      add_custom_command(TARGET ${S_TARGET} POST_BUILD
+        COMMAND "${CMAKE_COMMAND}" -E copy_if_different $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE})
+    else()
+      add_custom_command(TARGET ${S_TARGET} POST_BUILD
+        COMMAND "${CMAKE_COMMAND}" -E create_symlink $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE})
+    endif()
+  endif()
+
+endfunction()
+
+# Create source generation scripts.
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in
+               ${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake @ONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genout.cmake.in
+               ${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake @ONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/gensrc.cmake.in
+               ${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake @ONLY)
 
 # libpng is a library so default to 'lib'
 if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
   set(CMAKE_INSTALL_LIBDIR lib)
-endif(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+endif()
 
 # CREATE PKGCONFIG FILES
-# we use the same files like ./configure, so we have to set its vars
+# We use the same files like ./configure, so we have to set its vars.
 # Only do this on Windows for Cygwin - the files don't make much sense outside
-# a UNIX look alike
+# of a UNIX look-alike.
 if(NOT WIN32 OR CYGWIN OR MINGW)
   set(prefix      ${CMAKE_INSTALL_PREFIX})
   set(exec_prefix ${CMAKE_INSTALL_PREFIX})
-  set(libdir      ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
-  set(includedir  ${CMAKE_INSTALL_PREFIX}/include)
+  set(libdir      ${CMAKE_INSTALL_FULL_LIBDIR})
+  set(includedir  ${CMAKE_INSTALL_FULL_INCLUDEDIR})
   set(LIBS        "-lz -lm")
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
     ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY)
-  CREATE_SYMLINK(${PNGLIB_NAME}.pc libpng.pc)
+  create_symlink(libpng.pc FILE ${PNGLIB_NAME}.pc)
 
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in
     ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)
-  CREATE_SYMLINK(${PNGLIB_NAME}-config libpng-config)
-endif(NOT WIN32 OR CYGWIN OR MINGW)
+  create_symlink(libpng-config FILE ${PNGLIB_NAME}-config)
+endif()
 
 # SET UP LINKS
 if(PNG_SHARED)
-  set_target_properties(${PNG_LIB_NAME} PROPERTIES
-#   VERSION 16.${PNGLIB_RELEASE}.1.6.21
+  set_target_properties(png PROPERTIES
+#   VERSION 16.${PNGLIB_RELEASE}.1.6.36
     VERSION 16.${PNGLIB_RELEASE}.0
     SOVERSION 16
     CLEAN_DIRECT_OUTPUT 1)
 endif()
-if(PNG_STATIC)
-  # MSVC doesn't use a different file extension for shared vs. static
-  # libs.  We are able to change OUTPUT_NAME to remove the _static
-  # for all other platforms.
-  if(NOT MSVC)
-    set_target_properties(${PNG_LIB_NAME_STATIC} PROPERTIES
-      OUTPUT_NAME ${PNG_LIB_NAME}
-      CLEAN_DIRECT_OUTPUT 1)
-  endif()
-endif()
-
-# If CMake > 2.4.x, we set a variable used below to export
-# targets to an export file.
-# TODO: Use VERSION_GREATER after our cmake_minimum_required >= 2.6.2
-if(CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 4)
-  set(PNG_EXPORT_RULE EXPORT libpng)
-elseif(CMAKE_MAJOR_VERSION GREATER 2) # future proof
-  set(PNG_EXPORT_RULE EXPORT libpng)
-endif()
 
 # INSTALL
-if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
   install(TARGETS ${PNG_LIB_TARGETS}
-      ${PNG_EXPORT_RULE}
-      RUNTIME DESTINATION bin
-      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
+          EXPORT libpng
+          RUNTIME DESTINATION bin
+          LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+          ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+          FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
   if(PNG_SHARED)
     # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
     if(CYGWIN OR MINGW)
-       get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME} LOCATION_${CMAKE_BUILD_TYPE})
-       CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_IMPORT_LIBRARY_SUFFIX})
-       install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}
-         DESTINATION ${CMAKE_INSTALL_LIBDIR})
-    endif(CYGWIN OR MINGW)
+      create_symlink(libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} TARGET png)
+      install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}
+              DESTINATION ${CMAKE_INSTALL_LIBDIR})
+    endif()
 
     if(NOT WIN32)
-      get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME} LOCATION_${CMAKE_BUILD_TYPE})
-      CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_SHARED_LIBRARY_SUFFIX})
-      install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}
-         DESTINATION ${CMAKE_INSTALL_LIBDIR})
-    endif(NOT WIN32)
-  endif(PNG_SHARED)
+      create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png)
+      install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}
+              DESTINATION ${CMAKE_INSTALL_LIBDIR})
+    endif()
+  endif()
 
   if(PNG_STATIC)
     if(NOT WIN32 OR CYGWIN OR MINGW)
-      get_target_property(BUILD_TARGET_LOCATION ${PNG_LIB_NAME_STATIC} LOCATION_${CMAKE_BUILD_TYPE})
-      CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_STATIC_LIBRARY_SUFFIX})
-      install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}
-         DESTINATION ${CMAKE_INSTALL_LIBDIR})
-    endif(NOT WIN32 OR CYGWIN OR MINGW)
- endif()
+      create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static)
+      install(FILES $<TARGET_LINKER_FILE_DIR:png_static>/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}
+              DESTINATION ${CMAKE_INSTALL_LIBDIR})
+    endif()
+  endif()
 endif()
 
-if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
-  install(FILES ${libpng_public_hdrs}   DESTINATION include)
-  install(FILES ${libpng_public_hdrs}   DESTINATION include/${PNGLIB_NAME})
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
+  install(FILES ${libpng_public_hdrs} DESTINATION include)
+  install(FILES ${libpng_public_hdrs} DESTINATION include/${PNGLIB_NAME})
 endif()
-if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL )
+if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL)
   if(NOT WIN32 OR CYGWIN OR MINGW)
     install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin)
-    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
-            DESTINATION bin)
-  endif(NOT WIN32 OR CYGWIN OR MINGW)
+    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config DESTINATION bin)
+  endif()
+endif()
+
+if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL)
+  install(TARGETS ${PNG_BIN_TARGETS}
+          RUNTIME DESTINATION bin)
 endif()
 
-if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL)
   # Install man pages
   if(NOT PNG_MAN_DIR)
     set(PNG_MAN_DIR "share/man")
   endif()
-  install(FILES libpng.3 libpngpf.3      DESTINATION ${PNG_MAN_DIR}/man3)
-  install(FILES png.5                    DESTINATION ${PNG_MAN_DIR}/man5)
+  install(FILES libpng.3 libpngpf.3 DESTINATION ${PNG_MAN_DIR}/man3)
+  install(FILES png.5 DESTINATION ${PNG_MAN_DIR}/man5)
   # Install pkg-config files
-  if(NOT WIN32 OR CYGWIN OR MINGW)
+  if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
     install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
             DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
     install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
@@ -351,12 +910,11 @@ if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
             DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
     install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
             DESTINATION bin)
-  endif(NOT WIN32 OR CYGWIN OR MINGW)
+  endif()
 endif()
 
-# On versions of CMake that support it, create an export file CMake
-# users can include() to import our targets
-if(PNG_EXPORT_RULE AND NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL )
+# Create an export file that CMake users can include() to import our targets.
+if(NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL)
   install(EXPORT libpng DESTINATION lib/libpng FILE lib${PNG_LIB_NAME}.cmake)
 endif()
 
@@ -371,4 +929,3 @@ endif()
 # to create msvc import lib for mingw compiled shared lib
 # pexports libpng.dll > libpng.def
 # lib /def:libpng.def /machine:x86
-
diff --git a/INSTALL b/INSTALL
index a294ffe..4c17022 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,24 +1,26 @@
 
-Installing libpng
+    Installing libpng
 
 Contents
 
-   I. Simple installation
-  II. Rebuilding the configure scripts
- III. Using scripts/makefile*
-  IV. Using cmake
-   V. Directory structure
-  VI. Building with project files
- VII. Building with makefiles
-VIII. Configuring libpng for 16-bit platforms
-  IX. Configuring for DOS
-   X. Configuring for Medium Model
-  XI. Prepending a prefix to exported symbols
- XII. Configuring for compiler xxx:
-XIII. Removing unwanted object code
- XIV. Changes to the build and configuration of libpng in libpng-1.5.x
-  XV. Setjmp/longjmp issues
- XVI. Other sources of information about libpng
+       I. Simple installation
+      II. Rebuilding the configure scripts
+     III. Using scripts/makefile*
+      IV. Using cmake
+       V. Directory structure
+      VI. Building with project files
+     VII. Building with makefiles
+    VIII. Configuring libpng for 16-bit platforms
+      IX. Configuring for DOS
+       X. Configuring for Medium Model
+      XI. Prepending a prefix to exported symbols
+     XII. Configuring for compiler xxx:
+    XIII. Removing unwanted object code
+     XIV. Enabling or disabling hardware optimizations
+      XV. Changes to the build and configuration of libpng in libpng-1.5.x
+     XVI. Setjmp/longjmp issues
+    XVII. Common linking failures
+   XVIII. Other sources of information about libpng
 
 I. Simple installation
 
@@ -47,7 +49,9 @@ If configure does not work on your system, or if you have a need to
 change configure.ac or Makefile.am, and you have a reasonably
 up-to-date set of tools, running ./autogen.sh in a git clone before
 running ./configure may fix the problem.  To be really sure that you
-aren't using any of the included pre-built scripts, you can do this:
+aren't using any of the included pre-built scripts, especially if you
+are building from a tar distribution instead of a git distribution,
+do this:
 
     ./configure --enable-maintainer-mode
     make maintainer-clean
@@ -75,8 +79,8 @@ Or you can use one of the "projects" in the "projects" directory.
 
 Before installing libpng, you must first install zlib, if it
 is not already on your system.  zlib can usually be found
-wherever you got libpng; otherwise go to http://zlib.net.  You can place
-zlib in in the same directory as libpng or in another directory.
+wherever you got libpng; otherwise go to https://zlib.net/.  You can
+place zlib in the same directory as libpng or in another directory.
 
 If your system already has a preinstalled zlib you will still need
 to have access to the zlib.h and zconf.h include files that
@@ -87,22 +91,24 @@ standard library search path, put ZLIBLIB, ZLIBINC, CPPFLAGS, LDFLAGS,
 and LD_LIBRARY_PATH in your environment before running "make test"
 or "make distcheck":
 
-ZLIBLIB=/path/to/lib export ZLIBLIB
-ZLIBINC=/path/to/include export ZLIBINC
-CPPFLAGS="-I$ZLIBINC" export CPPFLAGS
-LDFLAGS="-L$ZLIBLIB" export LDFLAGS
-LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH
+    ZLIBLIB=/path/to/lib export ZLIBLIB
+    ZLIBINC=/path/to/include export ZLIBINC
+    CPPFLAGS="-I$ZLIBINC" export CPPFLAGS
+    LDFLAGS="-L$ZLIBLIB" export LDFLAGS
+    LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH
 
 If you are using one of the makefile scripts, put ZLIBLIB and ZLIBINC
-in your environment and type "make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test".
+in your environment and type
+
+    make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test
 
 IV. Using cmake
 
 If you want to use "cmake" (see www.cmake.org), type
 
-   cmake . -DCMAKE_INSTALL_PREFIX=/path
-   make
-   make install
+    cmake . -DCMAKE_INSTALL_PREFIX=/path
+    make
+    make install
 
 As when using the simple configure method described above, "/path" points to
 the installation directory where you want to put the libpng "lib", "include",
@@ -116,8 +122,8 @@ or "zlib128") so that you have directories called "zlib" and "libpng".
 
 Your directory structure should look like this:
 
-   ..       (the parent directory)
-      libpng  (this directory)
+    .. (the parent directory)
+      libpng (this directory)
           INSTALL (this file)
           README
           *.h, *.c  => libpng source files
@@ -160,10 +166,15 @@ VII. Building with makefiles
 Copy the file (or files) that you need from the
 scripts directory into this directory, for example
 
-   MSDOS example: copy scripts\makefile.msc makefile
-                  copy scripts\pnglibconf.h.prebuilt pnglibconf.h
-   UNIX example:  cp scripts/makefile.std makefile
-                  cp scripts/pnglibconf.h.prebuilt pnglibconf.h
+MSDOS example:
+
+    copy scripts\makefile.msc makefile
+    copy scripts\pnglibconf.h.prebuilt pnglibconf.h
+
+UNIX example:
+
+    cp scripts/makefile.std makefile
+    cp scripts/pnglibconf.h.prebuilt pnglibconf.h
 
 Read the makefile to see if you need to change any source or
 target directories to match your preferences.
@@ -239,7 +250,7 @@ libpng are compiled.  All the defines end in _SUPPORTED.  If you are
 never going to use a capability, you can change the #define to #undef
 before recompiling libpng and save yourself code and data space, or
 you can turn off individual capabilities with defines that begin with
-PNG_NO_.
+"PNG_NO_".
 
 In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead.
 
@@ -271,7 +282,57 @@ library to fail if they call functions not available in your library.
 The size of the library itself should not be an issue, because only
 those sections that are actually used will be loaded into memory.
 
-XIV. Changes to the build and configuration of libpng in libpng-1.5.x
+XIV. Enabling or disabling hardware optimizations
+
+Certain hardware capabilities, such as the Intel SSE instructions,
+are normally detected at run time. Enable them with configure options
+such as one of
+
+   --enable-arm-neon=yes
+   --enable-mips-msa=yes
+   --enable-intel-sse=yes
+   --enable-powerpc-vsx=yes
+
+or enable them all at once with
+
+   --enable-hardware-optimizations=yes
+
+or, if you are not using "configure", you can use one
+or more of
+
+   CPPFLAGS += "-DPNG_ARM_NEON"
+   CPPFLAGS += "-DPNG_MIPS_MSA"
+   CPPFLAGS += "-DPNG_INTEL_SSE"
+   CPPFLAGS += "-DPNG_POWERPC_VSX"
+
+See for example scripts/makefile.linux-opt
+
+If you wish to avoid using them,
+you can disable them via the configure option
+
+   --disable-hardware-optimizations
+
+to disable them all, or
+
+   --enable-intel-sse=no
+
+to disable a particular one,
+or via compiler-command options such as
+
+   CPPFLAGS += "-DPNG_ARM_NEON_OPT=0, -DPNG_MIPS_MSA_OPT=0,
+   -DPNG_INTEL_SSE_OPT=0, -DPNG_POWERPC_VSX_OPT=0"
+
+If you are using cmake, hardware optimizations are "on"
+by default. To disable them, use
+
+    cmake . -DPNG_ARM_NEON=no -DPNG_INTEL_SSE=no \
+            -DPNG_MIPS_MSA=no -DPNG_POWERPC_VSX=no
+
+or disable them all at once with
+
+    cmake . -DPNG_HARDWARE_OPTIMIZATIONS=no
+
+XV. Changes to the build and configuration of libpng in libpng-1.5.x
 
 Details of internal changes to the library code can be found in the CHANGES
 file and in the GIT repository logs.  These will be of no concern to the vast
@@ -307,7 +368,7 @@ only png_longjmp_ptr, which must match the C longjmp function.)  The new
 approach is documented in pngconf.h
 
 Despite these changes, libpng 1.5.0 only supports the native C function
-calling standard on those platforms tested so far (__cdecl on Microsoft
+calling standard on those platforms tested so far ("__cdecl" on Microsoft
 Windows).  This is because the support requirements for alternative
 calling conventions seem to no longer exist.  Developers who find it
 necessary to set PNG_API_RULE to 1 should advise the mailing list
@@ -362,7 +423,7 @@ $PREFIX/include directory).  Do not edit pnglibconf.h after you have built
 libpng, because than the settings would not accurately reflect the settings
 that were used to build libpng.
 
-XV. Setjmp/longjmp issues
+XVI. Setjmp/longjmp issues
 
 Libpng uses setjmp()/longjmp() for error handling.  Unfortunately setjmp()
 is known to be not thread-safe on some platforms and we don't know of
@@ -371,7 +432,7 @@ your application is going to be using multiple threads, you should
 configure libpng with PNG_NO_SETJMP in your pngusr.dfa file, with
 -DPNG_NO_SETJMP on your compile line, or with
 
-  #undef PNG_SETJMP_SUPPORTED
+    #undef PNG_SETJMP_SUPPORTED
 
 in your pnglibconf.h or pngusr.h.
 
@@ -380,28 +441,25 @@ This requires setjmp/longjmp, so you must either build the library
 with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED
 and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined.
 
-XVI. Other sources of information about libpng:
+XVII. Common linking failures
 
-Further information can be found in the README and libpng-manual.txt
-files, in the individual makefiles, in png.h, and the manual pages
-libpng.3 and png.5.
+If your application fails to find libpng or zlib entries while linking:
 
-Using the ./configure script -- 16 December 2002.
-=================================================
+  Be sure "-lz" appears after "-lpng" on your linking command.
 
-The ./configure script should work compatibly with what scripts/makefile.*
-did, however there are some options you might need to add to configure
-explicitly, which previously was done semi-automatically (if you didn't edit
-scripts/makefile.* yourself, that is)
+  Be sure you have built libpng, zlib, and your application for the
+  same platform (e.g., 32-bit or 64-bit).
 
-CFLAGS="-Wall -O -funroll-loops \
--malign-loops=2 -malign-functions=2" ./configure --prefix=/usr/include \
---with-pkgconfigdir=/usr/lib/pkgconfig --includedir=/usr/include
+  If you are using the vstudio project, observe the WARNING in
+  project/vstudio/README.txt.
 
-You can alternatively specify --includedir=/usr/include, /usr/local/include,
-/usr/include/libpng16, or whatever.
+XVIII. Other sources of information about libpng:
 
-If you find that the configure script is out-of-date or is not supporting
-your platform properly, try running autogen.sh to regenerate "configure",
-"Makefile.in", and the other configuration files. Then try configure again.
+Further information can be found in the README and libpng-manual.txt
+files, in the individual makefiles, in png.h, and the manual pages
+libpng.3 and png.5.
 
+Copyright (c) 1998-2002,2006-2016 Glenn Randers-Pehrson
+This document is released under the libpng license.
+For conditions of distribution and use, see the disclaimer
+and license in png.h.
diff --git a/LICENSE b/LICENSE
index fd93b1b..62ab8e4 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,46 +1,82 @@
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
+=========================================
 
-This copy of the libpng notices is provided for your convenience.  In case of
-any discrepancy between this copy and the notices in the file png.h that is
-included in the libpng distribution, the latter shall prevail.
+PNG Reference Library License version 2
+---------------------------------------
 
-COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ * Copyright (c) 1995-2018 The PNG Reference Library Authors.
+ * Copyright (c) 2018 Cosmin Truta.
+ * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
+ * Copyright (c) 1996-1997 Andreas Dilger.
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
 
-If you modify libpng you may insert additional notices immediately following
-this sentence.
+The software is supplied "as is", without warranty of any kind,
+express or implied, including, without limitation, the warranties
+of merchantability, fitness for a particular purpose, title, and
+non-infringement.  In no even shall the Copyright owners, or
+anyone distributing the software, be liable for any damages or
+other liability, whether in contract, tort or otherwise, arising
+from, out of, or in connection with the software, or the use or
+other dealings in the software, even if advised of the possibility
+of such damage.
 
-This code is released under the libpng license.
+Permission is hereby granted to use, copy, modify, and distribute
+this software, or portions hereof, for any purpose, without fee,
+subject to the following restrictions:
 
-libpng versions 1.0.7, July 1, 2000, through 1.6.21, January 15, 2016, are
-Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+ 1. The origin of this software must not be misrepresented; you
+    must not claim that you wrote the original software.  If you
+    use this software in a product, an acknowledgment in the product
+    documentation would be appreciated, but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must
+    not be misrepresented as being the original software.
+
+ 3. This Copyright notice may not be removed or altered from any
+    source or altered source distribution.
+
+
+PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
+-----------------------------------------------------------------------
+
+libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are
+Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
 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
 added to the list of Contributing Authors:
 
-   Simon-Pierre Cadieux
-   Eric S. Raymond
-   Mans Rullgard
-   Cosmin Truta
-   Gilles Vollant
-   James Yu
+    Simon-Pierre Cadieux
+    Eric S. Raymond
+    Mans Rullgard
+    Cosmin Truta
+    Gilles Vollant
+    James Yu
+    Mandar Sahastrabuddhe
+    Google Inc.
+    Vadim Barkov
 
 and with the following additions to the disclaimer:
 
-   There is no warranty against interference with your enjoyment of the
-   library or against infringement.  There is no warranty that our
-   efforts or the library will fulfill any of your particular purposes
-   or needs.  This library is provided with all faults, and the entire
-   risk of satisfactory quality, performance, accuracy, and effort is with
-   the user.
+    There is no warranty against interference with your enjoyment of
+    the library or against infringement.  There is no warranty that our
+    efforts or the library will fulfill any of your particular purposes
+    or needs.  This library is provided with all faults, and the entire
+    risk of satisfactory quality, performance, accuracy, and effort is
+    with the user.
+
+Some files in the "contrib" directory and some configure-generated
+files that are distributed with libpng have other copyright owners, and
+are released under other open source licenses.
 
 libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
 Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
 libpng-0.96, and are distributed according to the same disclaimer and
-license as libpng-0.96, with the following individuals added to the list
-of Contributing Authors:
+license as libpng-0.96, with the following individuals added to the
+list of Contributing Authors:
 
-   Tom Lane
-   Glenn Randers-Pehrson
-   Willem van Schaik
+    Tom Lane
+    Glenn Randers-Pehrson
+    Willem van Schaik
 
 libpng versions 0.89, June 1996, through 0.96, May 1997, are
 Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
@@ -48,12 +84,15 @@ and are distributed according to the same disclaimer and license as
 libpng-0.88, with the following individuals added to the list of
 Contributing Authors:
 
-   John Bowler
-   Kevin Bracey
-   Sam Bushell
-   Magnus Holmgren
-   Greg Roelofs
-   Tom Tanner
+    John Bowler
+    Kevin Bracey
+    Sam Bushell
+    Magnus Holmgren
+    Greg Roelofs
+    Tom Tanner
+
+Some files in the "scripts" directory have other copyright owners,
+but are released under this license.
 
 libpng versions 0.5, May 1995, through 0.88, January 1996, are
 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -61,52 +100,35 @@ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
 For the purposes of this copyright and license, "Contributing Authors"
 is defined as the following set of individuals:
 
-   Andreas Dilger
-   Dave Martindale
-   Guy Eric Schalnat
-   Paul Schmidt
-   Tim Wegner
-
-The PNG Reference Library is supplied "AS IS".  The Contributing Authors
-and Group 42, Inc. disclaim all warranties, expressed or implied,
-including, without limitation, the warranties of merchantability and of
-fitness for any purpose.  The Contributing Authors and Group 42, Inc.
-assume no liability for direct, indirect, incidental, special, exemplary,
-or consequential damages, which may result from the use of the PNG
-Reference Library, even if advised of the possibility of such damage.
+    Andreas Dilger
+    Dave Martindale
+    Guy Eric Schalnat
+    Paul Schmidt
+    Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing
+Authors and Group 42, Inc. disclaim all warranties, expressed or
+implied, including, without limitation, the warranties of
+merchantability and of fitness for any purpose.  The Contributing
+Authors and Group 42, Inc. assume no liability for direct, indirect,
+incidental, special, exemplary, or consequential damages, which may
+result from the use of the PNG Reference Library, even if advised of
+the possibility of such damage.
 
 Permission is hereby granted to use, copy, modify, and distribute this
 source code, or portions hereof, for any purpose, without fee, subject
 to the following restrictions:
 
-  1. The origin of this source code must not be misrepresented.
-
-  2. Altered versions must be plainly marked as such and must not
-     be misrepresented as being the original source.
-
-  3. This Copyright notice may not be removed or altered from any
-     source or altered source distribution.
-
-The Contributing Authors and Group 42, Inc. specifically permit, without
-fee, and encourage the use of this source code as a component to
-supporting the PNG file format in commercial products.  If you use this
-source code in a product, acknowledgment is not required but would be
-appreciated.
-
-END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
-
-A "png_get_copyright" function is available, for convenient use in "about"
-boxes and the like:
-
-   printf("%s", png_get_copyright(NULL));
+ 1. The origin of this source code must not be misrepresented.
 
-Also, the PNG logo (in PNG format, of course) is supplied in the
-files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ 2. Altered versions must be plainly marked as such and must not
+    be misrepresented as being the original source.
 
-Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is
-a certification mark of the Open Source Initiative. OSI has not addressed
-the additional disclaimers inserted at version 1.0.7.
+ 3. This Copyright notice may not be removed or altered from any
+    source or altered source distribution.
 
-Glenn Randers-Pehrson
-glennrp at users.sourceforge.net
-January 15, 2016
+The Contributing Authors and Group 42, Inc. specifically permit,
+without fee, and encourage the use of this source code as a component
+to supporting the PNG file format in commercial products.  If you use
+this source code in a product, acknowledgment is not required but would
+be appreciated.
index 73097db..4f621aa 100644 (file)
@@ -1,13 +1,21 @@
-# Makefile.am:
-#   Source file for Makefile.in (and hence Makefile)
+# Makefile.am, the source file for Makefile.in (and hence Makefile), is
 #
+# Copyright (c) 2018 Cosmin Truta
+# Copyright (c) 2004-2016 Glenn Randers-Pehrson
+#
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
 
 PNGLIB_BASENAME= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
 
 ACLOCAL_AMFLAGS = -I scripts
 
 # test programs - run on make check, make distcheck
-check_PROGRAMS= pngtest pngunknown pngstest pngvalid pngimage
+check_PROGRAMS= pngtest pngunknown pngstest pngvalid pngimage pngcp
+if HAVE_CLOCK_GETTIME
+check_PROGRAMS += timepng
+endif
 
 # Utilities - installed
 bin_PROGRAMS= pngfix png-fix-itxt
@@ -37,15 +45,22 @@ pngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 pngimage_SOURCES = contrib/libtests/pngimage.c
 pngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 
+timepng_SOURCES = contrib/libtests/timepng.c
+timepng_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
+
 pngfix_SOURCES = contrib/tools/pngfix.c
 pngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 
 png_fix_itxt_SOURCES = contrib/tools/png-fix-itxt.c
 
+pngcp_SOURCES = contrib/tools/pngcp.c
+pngcp_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
+
 # Generally these are single line shell scripts to run a test with a particular
 # set of parameters:
 TESTS =\
    tests/pngtest\
+   tests/pngtest-badpngs\
    tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\
    tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\
    tests/pngvalid-gamma-expand16-background\
@@ -80,7 +95,23 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c\
 
 if PNG_ARM_NEON
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += arm/arm_init.c\
-       arm/filter_neon.S arm/filter_neon_intrinsics.c
+       arm/filter_neon.S arm/filter_neon_intrinsics.c \
+       arm/palette_neon_intrinsics.c
+endif
+
+if PNG_MIPS_MSA
+libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += mips/mips_init.c\
+       mips/filter_msa_intrinsics.c
+endif
+
+if PNG_INTEL_SSE
+libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += intel/intel_init.c\
+       intel/filter_sse2_intrinsics.c
+endif
+
+if PNG_POWERPC_VSX
+libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += powerpc/powerpc_init.c\
+        powerpc/filter_vsx_intrinsics.c
 endif
 
 nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h
@@ -117,7 +148,7 @@ pkgconfig_DATA = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc
 # from those directories being included.  This only works if the configure is
 # not done in the source directory!
 EXTRA_DIST= \
-       ANNOUNCE CHANGES INSTALL LICENSE README TODO \
+       ANNOUNCE AUTHORS CHANGES INSTALL LICENSE README TODO TRADEMARK \
        pngtest.png pngbar.png pngnow.png pngbar.jpg autogen.sh \
        ${srcdir}/contrib ${srcdir}/projects ${srcdir}/scripts \
        $(TESTS) $(XFAIL_TESTS) tests/pngstest \
@@ -219,6 +250,7 @@ contrib/libtests/timepng.o: pnglibconf.h
 
 contrib/tools/makesRGB.o: pnglibconf.h
 contrib/tools/pngfix.o: pnglibconf.h
+contrib/tools/pngcp.o: pnglibconf.h
 
 # We must use -DPNG_NO_USE_READ_MACROS here even when the library may actually
 # be built with PNG_USE_READ_MACROS; this prevents the read macros from
index e4f3562..81ac1c8 100644 (file)
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 
 @SET_MAKE@
 
-# Makefile.am:
-#   Source file for Makefile.in (and hence Makefile)
+# Makefile.am, the source file for Makefile.in (and hence Makefile), is
 #
+# Copyright (c) 2018 Cosmin Truta
+# Copyright (c) 2004-2016 Glenn Randers-Pehrson
+#
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
 
 
 
@@ -96,18 +101,30 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = pngtest$(EXEEXT) pngunknown$(EXEEXT) \
-       pngstest$(EXEEXT) pngvalid$(EXEEXT) pngimage$(EXEEXT)
+       pngstest$(EXEEXT) pngvalid$(EXEEXT) pngimage$(EXEEXT) \
+       pngcp$(EXEEXT) $(am__EXEEXT_1)
+@HAVE_CLOCK_GETTIME_TRUE@am__append_1 = timepng
 bin_PROGRAMS = pngfix$(EXEEXT) png-fix-itxt$(EXEEXT)
-@PNG_ARM_NEON_TRUE@am__append_1 = arm/arm_init.c\
-@PNG_ARM_NEON_TRUE@    arm/filter_neon.S arm/filter_neon_intrinsics.c
+@PNG_ARM_NEON_TRUE@am__append_2 = arm/arm_init.c\
+@PNG_ARM_NEON_TRUE@    arm/filter_neon.S arm/filter_neon_intrinsics.c \
+@PNG_ARM_NEON_TRUE@    arm/palette_neon_intrinsics.c
+
+@PNG_MIPS_MSA_TRUE@am__append_3 = mips/mips_init.c\
+@PNG_MIPS_MSA_TRUE@    mips/filter_msa_intrinsics.c
+
+@PNG_INTEL_SSE_TRUE@am__append_4 = intel/intel_init.c\
+@PNG_INTEL_SSE_TRUE@   intel/filter_sse2_intrinsics.c
+
+@PNG_POWERPC_VSX_TRUE@am__append_5 = powerpc/powerpc_init.c\
+@PNG_POWERPC_VSX_TRUE@        powerpc/filter_vsx_intrinsics.c
 
 
 #   Versioned symbols and restricted exports
-@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_TRUE@am__append_2 = -Wl,-M -Wl,libpng.vers
-@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_FALSE@am__append_3 = -Wl,--version-script=libpng.vers
+@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_TRUE@am__append_6 = -Wl,-M -Wl,libpng.vers
+@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_FALSE@am__append_7 = -Wl,--version-script=libpng.vers
 #   Only restricted exports when possible
-@HAVE_LD_VERSION_SCRIPT_FALSE@am__append_4 = -export-symbols libpng.sym
-@DO_PNG_PREFIX_TRUE@am__append_5 = -DPNG_PREFIX='@PNG_PREFIX@'
+@HAVE_LD_VERSION_SCRIPT_FALSE@am__append_8 = -export-symbols libpng.sym
+@DO_PNG_PREFIX_TRUE@am__append_9 = -DPNG_PREFIX='@PNG_PREFIX@'
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/scripts/libtool.m4 \
@@ -126,6 +143,12 @@ mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = config.h
 CONFIG_CLEAN_FILES = libpng.pc libpng-config
 CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \
+       "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man3dir)" \
+       "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" \
+       "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"
+@HAVE_CLOCK_GETTIME_TRUE@am__EXEEXT_1 = timepng$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -153,10 +176,6 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
-       "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man3dir)" \
-       "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" \
-       "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD =
 am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST = png.c \
@@ -164,14 +183,26 @@ am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST = png.c \
        pngrtran.c pngrutil.c 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 arm/arm_init.c \
-       arm/filter_neon.S arm/filter_neon_intrinsics.c
+       arm/filter_neon.S arm/filter_neon_intrinsics.c \
+       arm/palette_neon_intrinsics.c mips/mips_init.c \
+       mips/filter_msa_intrinsics.c intel/intel_init.c \
+       intel/filter_sse2_intrinsics.c powerpc/powerpc_init.c \
+       powerpc/filter_vsx_intrinsics.c
 am__dirstamp = $(am__leading_dot)dirstamp
 @PNG_ARM_NEON_TRUE@am__objects_1 = arm/arm_init.lo arm/filter_neon.lo \
-@PNG_ARM_NEON_TRUE@    arm/filter_neon_intrinsics.lo
+@PNG_ARM_NEON_TRUE@    arm/filter_neon_intrinsics.lo \
+@PNG_ARM_NEON_TRUE@    arm/palette_neon_intrinsics.lo
+@PNG_MIPS_MSA_TRUE@am__objects_2 = mips/mips_init.lo \
+@PNG_MIPS_MSA_TRUE@    mips/filter_msa_intrinsics.lo
+@PNG_INTEL_SSE_TRUE@am__objects_3 = intel/intel_init.lo \
+@PNG_INTEL_SSE_TRUE@   intel/filter_sse2_intrinsics.lo
+@PNG_POWERPC_VSX_TRUE@am__objects_4 = powerpc/powerpc_init.lo \
+@PNG_POWERPC_VSX_TRUE@ powerpc/filter_vsx_intrinsics.lo
 am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = png.lo pngerror.lo \
        pngget.lo pngmem.lo pngpread.lo pngread.lo pngrio.lo \
        pngrtran.lo pngrutil.lo pngset.lo pngtrans.lo pngwio.lo \
-       pngwrite.lo pngwtran.lo pngwutil.lo $(am__objects_1)
+       pngwrite.lo pngwtran.lo pngwutil.lo $(am__objects_1) \
+       $(am__objects_2) $(am__objects_3) $(am__objects_4)
 nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS =
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS =  \
        $(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) \
@@ -185,10 +216,12 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK = $(LIBTOOL) $(AM_V_lt) \
        $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS) $(LDFLAGS) -o \
        $@
-PROGRAMS = $(bin_PROGRAMS)
 am_png_fix_itxt_OBJECTS = contrib/tools/png-fix-itxt.$(OBJEXT)
 png_fix_itxt_OBJECTS = $(am_png_fix_itxt_OBJECTS)
 png_fix_itxt_LDADD = $(LDADD)
+am_pngcp_OBJECTS = contrib/tools/pngcp.$(OBJEXT)
+pngcp_OBJECTS = $(am_pngcp_OBJECTS)
+pngcp_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 am_pngfix_OBJECTS = contrib/tools/pngfix.$(OBJEXT)
 pngfix_OBJECTS = $(am_pngfix_OBJECTS)
 pngfix_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
@@ -207,6 +240,9 @@ pngunknown_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 am_pngvalid_OBJECTS = contrib/libtests/pngvalid.$(OBJEXT)
 pngvalid_OBJECTS = $(am_pngvalid_OBJECTS)
 pngvalid_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
+am_timepng_OBJECTS = contrib/libtests/timepng.$(OBJEXT)
+timepng_OBJECTS = $(am_timepng_OBJECTS)
+timepng_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 SCRIPTS = $(bin_SCRIPTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -222,11 +258,36 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/png.Plo ./$(DEPDIR)/pngerror.Plo \
+       ./$(DEPDIR)/pngget.Plo ./$(DEPDIR)/pngmem.Plo \
+       ./$(DEPDIR)/pngpread.Plo ./$(DEPDIR)/pngread.Plo \
+       ./$(DEPDIR)/pngrio.Plo ./$(DEPDIR)/pngrtran.Plo \
+       ./$(DEPDIR)/pngrutil.Plo ./$(DEPDIR)/pngset.Plo \
+       ./$(DEPDIR)/pngtest.Po ./$(DEPDIR)/pngtrans.Plo \
+       ./$(DEPDIR)/pngwio.Plo ./$(DEPDIR)/pngwrite.Plo \
+       ./$(DEPDIR)/pngwtran.Plo ./$(DEPDIR)/pngwutil.Plo \
+       arm/$(DEPDIR)/arm_init.Plo arm/$(DEPDIR)/filter_neon.Plo \
+       arm/$(DEPDIR)/filter_neon_intrinsics.Plo \
+       arm/$(DEPDIR)/palette_neon_intrinsics.Plo \
+       contrib/libtests/$(DEPDIR)/pngimage.Po \
+       contrib/libtests/$(DEPDIR)/pngstest.Po \
+       contrib/libtests/$(DEPDIR)/pngunknown.Po \
+       contrib/libtests/$(DEPDIR)/pngvalid.Po \
+       contrib/libtests/$(DEPDIR)/timepng.Po \
+       contrib/tools/$(DEPDIR)/png-fix-itxt.Po \
+       contrib/tools/$(DEPDIR)/pngcp.Po \
+       contrib/tools/$(DEPDIR)/pngfix.Po \
+       intel/$(DEPDIR)/filter_sse2_intrinsics.Plo \
+       intel/$(DEPDIR)/intel_init.Plo \
+       mips/$(DEPDIR)/filter_msa_intrinsics.Plo \
+       mips/$(DEPDIR)/mips_init.Plo \
+       powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo \
+       powerpc/$(DEPDIR)/powerpc_init.Plo
 am__mv = mv -f
 CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
-LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
        $(AM_CCASFLAGS) $(CCASFLAGS)
@@ -254,14 +315,14 @@ am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \
        $(nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \
-       $(png_fix_itxt_SOURCES) $(pngfix_SOURCES) $(pngimage_SOURCES) \
-       $(pngstest_SOURCES) $(pngtest_SOURCES) $(pngunknown_SOURCES) \
-       $(pngvalid_SOURCES)
+       $(png_fix_itxt_SOURCES) $(pngcp_SOURCES) $(pngfix_SOURCES) \
+       $(pngimage_SOURCES) $(pngstest_SOURCES) $(pngtest_SOURCES) \
+       $(pngunknown_SOURCES) $(pngvalid_SOURCES) $(timepng_SOURCES)
 DIST_SOURCES =  \
        $(am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST) \
-       $(png_fix_itxt_SOURCES) $(pngfix_SOURCES) $(pngimage_SOURCES) \
-       $(pngstest_SOURCES) $(pngtest_SOURCES) $(pngunknown_SOURCES) \
-       $(pngvalid_SOURCES)
+       $(png_fix_itxt_SOURCES) $(pngcp_SOURCES) $(pngfix_SOURCES) \
+       $(pngimage_SOURCES) $(pngstest_SOURCES) $(pngtest_SOURCES) \
+       $(pngunknown_SOURCES) $(pngvalid_SOURCES) $(timepng_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -473,7 +534,7 @@ TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
        $(TEST_LOG_FLAGS)
 am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
        $(srcdir)/config.h.in $(srcdir)/libpng-config.in \
-       $(srcdir)/libpng.pc.in INSTALL README TODO compile \
+       $(srcdir)/libpng.pc.in AUTHORS INSTALL README TODO compile \
        config.guess config.sub depcomp install-sh ltmain.sh missing \
        test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -664,14 +725,19 @@ pngunknown_SOURCES = contrib/libtests/pngunknown.c
 pngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 pngimage_SOURCES = contrib/libtests/pngimage.c
 pngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
+timepng_SOURCES = contrib/libtests/timepng.c
+timepng_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 pngfix_SOURCES = contrib/tools/pngfix.c
 pngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 png_fix_itxt_SOURCES = contrib/tools/png-fix-itxt.c
+pngcp_SOURCES = contrib/tools/pngcp.c
+pngcp_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la
 
 # Generally these are single line shell scripts to run a test with a particular
 # set of parameters:
 TESTS = \
    tests/pngtest\
+   tests/pngtest-badpngs\
    tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\
    tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\
    tests/pngvalid-gamma-expand16-background\
@@ -701,12 +767,13 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c \
        pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c \
        pngrutil.c 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 $(am__append_1)
+       pngstruct.h pngusr.dfa $(am__append_2) $(am__append_3) \
+       $(am__append_4) $(am__append_5)
 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 \
-       $(am__append_2) $(am__append_3) $(am__append_4)
+       $(am__append_6) $(am__append_7) $(am__append_8)
 @HAVE_LD_VERSION_SCRIPT_FALSE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.sym
 @HAVE_LD_VERSION_SCRIPT_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.vers
 pkginclude_HEADERS = png.h pngconf.h
@@ -717,7 +784,7 @@ pkgconfig_DATA = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc
 # from those directories being included.  This only works if the configure is
 # not done in the source directory!
 EXTRA_DIST = \
-       ANNOUNCE CHANGES INSTALL LICENSE README TODO \
+       ANNOUNCE AUTHORS CHANGES INSTALL LICENSE README TODO TRADEMARK \
        pngtest.png pngbar.png pngnow.png pngbar.jpg autogen.sh \
        ${srcdir}/contrib ${srcdir}/projects ${srcdir}/scripts \
        $(TESTS) $(XFAIL_TESTS) tests/pngstest \
@@ -742,7 +809,7 @@ SUFFIXES = .chk .out
 SYMBOL_CFLAGS = -DPNGLIB_LIBNAME='PNG@PNGLIB_MAJOR@@PNGLIB_MINOR@_0' \
        -DPNGLIB_VERSION='@PNGLIB_VERSION@' \
        -DSYMBOL_PREFIX='$(SYMBOL_PREFIX)' -DPNG_NO_USE_READ_MACROS \
-       -DPNG_BUILDING_SYMBOL_TABLE $(am__append_5)
+       -DPNG_BUILDING_SYMBOL_TABLE $(am__append_9)
 
 # EXT_LIST is a list of the possibly library directory extensions, this exists
 # because we can't find a good way of discovering the file extensions that are
@@ -775,8 +842,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
            echo ' $(SHELL) ./config.status'; \
            $(SHELL) ./config.status;; \
          *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
        esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -806,54 +873,6 @@ libpng.pc: $(top_builddir)/config.status $(srcdir)/libpng.pc.in
        cd $(top_builddir) && $(SHELL) ./config.status $@
 libpng-config: $(top_builddir)/config.status $(srcdir)/libpng-config.in
        cd $(top_builddir) && $(SHELL) ./config.status $@
-
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-       @$(NORMAL_INSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       list2=; for p in $$list; do \
-         if test -f $$p; then \
-           list2="$$list2 $$p"; \
-         else :; fi; \
-       done; \
-       test -z "$$list2" || { \
-         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
-         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
-       }
-
-uninstall-libLTLIBRARIES:
-       @$(NORMAL_UNINSTALL)
-       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
-       for p in $$list; do \
-         $(am__strip_dir) \
-         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
-         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
-       done
-
-clean-libLTLIBRARIES:
-       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-       @list='$(lib_LTLIBRARIES)'; \
-       locs=`for p in $$list; do echo $$p; done | \
-             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-             sort -u`; \
-       test -z "$$locs" || { \
-         echo rm -f $${locs}; \
-         rm -f $${locs}; \
-       }
-arm/$(am__dirstamp):
-       @$(MKDIR_P) arm
-       @: > arm/$(am__dirstamp)
-arm/$(DEPDIR)/$(am__dirstamp):
-       @$(MKDIR_P) arm/$(DEPDIR)
-       @: > arm/$(DEPDIR)/$(am__dirstamp)
-arm/arm_init.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp)
-arm/filter_neon.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp)
-arm/filter_neon_intrinsics.lo: arm/$(am__dirstamp) \
-       arm/$(DEPDIR)/$(am__dirstamp)
-
-libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la: $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) $(EXTRA_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) 
-       $(AM_V_CCLD)$(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK) -rpath $(libdir) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
        @$(NORMAL_INSTALL)
        @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
@@ -912,6 +931,85 @@ clean-checkPROGRAMS:
        list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
        echo " rm -f" $$list; \
        rm -f $$list
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       list2=; for p in $$list; do \
+         if test -f $$p; then \
+           list2="$$list2 $$p"; \
+         else :; fi; \
+       done; \
+       test -z "$$list2" || { \
+         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+       }
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+       for p in $$list; do \
+         $(am__strip_dir) \
+         echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+         $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; \
+       locs=`for p in $$list; do echo $$p; done | \
+             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+             sort -u`; \
+       test -z "$$locs" || { \
+         echo rm -f $${locs}; \
+         rm -f $${locs}; \
+       }
+arm/$(am__dirstamp):
+       @$(MKDIR_P) arm
+       @: > arm/$(am__dirstamp)
+arm/$(DEPDIR)/$(am__dirstamp):
+       @$(MKDIR_P) arm/$(DEPDIR)
+       @: > arm/$(DEPDIR)/$(am__dirstamp)
+arm/arm_init.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp)
+arm/filter_neon.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp)
+arm/filter_neon_intrinsics.lo: arm/$(am__dirstamp) \
+       arm/$(DEPDIR)/$(am__dirstamp)
+arm/palette_neon_intrinsics.lo: arm/$(am__dirstamp) \
+       arm/$(DEPDIR)/$(am__dirstamp)
+mips/$(am__dirstamp):
+       @$(MKDIR_P) mips
+       @: > mips/$(am__dirstamp)
+mips/$(DEPDIR)/$(am__dirstamp):
+       @$(MKDIR_P) mips/$(DEPDIR)
+       @: > mips/$(DEPDIR)/$(am__dirstamp)
+mips/mips_init.lo: mips/$(am__dirstamp) mips/$(DEPDIR)/$(am__dirstamp)
+mips/filter_msa_intrinsics.lo: mips/$(am__dirstamp) \
+       mips/$(DEPDIR)/$(am__dirstamp)
+intel/$(am__dirstamp):
+       @$(MKDIR_P) intel
+       @: > intel/$(am__dirstamp)
+intel/$(DEPDIR)/$(am__dirstamp):
+       @$(MKDIR_P) intel/$(DEPDIR)
+       @: > intel/$(DEPDIR)/$(am__dirstamp)
+intel/intel_init.lo: intel/$(am__dirstamp) \
+       intel/$(DEPDIR)/$(am__dirstamp)
+intel/filter_sse2_intrinsics.lo: intel/$(am__dirstamp) \
+       intel/$(DEPDIR)/$(am__dirstamp)
+powerpc/$(am__dirstamp):
+       @$(MKDIR_P) powerpc
+       @: > powerpc/$(am__dirstamp)
+powerpc/$(DEPDIR)/$(am__dirstamp):
+       @$(MKDIR_P) powerpc/$(DEPDIR)
+       @: > powerpc/$(DEPDIR)/$(am__dirstamp)
+powerpc/powerpc_init.lo: powerpc/$(am__dirstamp) \
+       powerpc/$(DEPDIR)/$(am__dirstamp)
+powerpc/filter_vsx_intrinsics.lo: powerpc/$(am__dirstamp) \
+       powerpc/$(DEPDIR)/$(am__dirstamp)
+
+libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la: $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) $(EXTRA_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) 
+       $(AM_V_CCLD)$(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK) -rpath $(libdir) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD) $(LIBS)
 contrib/tools/$(am__dirstamp):
        @$(MKDIR_P) contrib/tools
        @: > contrib/tools/$(am__dirstamp)
@@ -924,6 +1022,12 @@ contrib/tools/png-fix-itxt.$(OBJEXT): contrib/tools/$(am__dirstamp) \
 png-fix-itxt$(EXEEXT): $(png_fix_itxt_OBJECTS) $(png_fix_itxt_DEPENDENCIES) $(EXTRA_png_fix_itxt_DEPENDENCIES) 
        @rm -f png-fix-itxt$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(png_fix_itxt_OBJECTS) $(png_fix_itxt_LDADD) $(LIBS)
+contrib/tools/pngcp.$(OBJEXT): contrib/tools/$(am__dirstamp) \
+       contrib/tools/$(DEPDIR)/$(am__dirstamp)
+
+pngcp$(EXEEXT): $(pngcp_OBJECTS) $(pngcp_DEPENDENCIES) $(EXTRA_pngcp_DEPENDENCIES) 
+       @rm -f pngcp$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(pngcp_OBJECTS) $(pngcp_LDADD) $(LIBS)
 contrib/tools/pngfix.$(OBJEXT): contrib/tools/$(am__dirstamp) \
        contrib/tools/$(DEPDIR)/$(am__dirstamp)
 
@@ -965,6 +1069,12 @@ contrib/libtests/pngvalid.$(OBJEXT): contrib/libtests/$(am__dirstamp) \
 pngvalid$(EXEEXT): $(pngvalid_OBJECTS) $(pngvalid_DEPENDENCIES) $(EXTRA_pngvalid_DEPENDENCIES) 
        @rm -f pngvalid$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(pngvalid_OBJECTS) $(pngvalid_LDADD) $(LIBS)
+contrib/libtests/timepng.$(OBJEXT): contrib/libtests/$(am__dirstamp) \
+       contrib/libtests/$(DEPDIR)/$(am__dirstamp)
+
+timepng$(EXEEXT): $(timepng_OBJECTS) $(timepng_DEPENDENCIES) $(EXTRA_timepng_DEPENDENCIES) 
+       @rm -f timepng$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(timepng_OBJECTS) $(timepng_LDADD) $(LIBS)
 install-binSCRIPTS: $(bin_SCRIPTS)
        @$(NORMAL_INSTALL)
        @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
@@ -1007,35 +1117,56 @@ mostlyclean-compile:
        -rm -f arm/*.lo
        -rm -f contrib/libtests/*.$(OBJEXT)
        -rm -f contrib/tools/*.$(OBJEXT)
+       -rm -f intel/*.$(OBJEXT)
+       -rm -f intel/*.lo
+       -rm -f mips/*.$(OBJEXT)
+       -rm -f mips/*.lo
+       -rm -f powerpc/*.$(OBJEXT)
+       -rm -f powerpc/*.lo
 
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/png.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngerror.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngget.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngmem.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngpread.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngread.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrio.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrtran.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrutil.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngset.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngtest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngtrans.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwio.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwrite.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwtran.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwutil.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/arm_init.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/filter_neon.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/filter_neon_intrinsics.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngimage.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngstest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngunknown.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngvalid.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/png-fix-itxt.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngfix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/png.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngerror.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngget.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngmem.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngpread.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngread.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrio.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrtran.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrutil.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngset.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngtest.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngtrans.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwio.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwrite.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwtran.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwutil.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/arm_init.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/filter_neon.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/filter_neon_intrinsics.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/palette_neon_intrinsics.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngimage.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngstest.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngunknown.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngvalid.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/timepng.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/png-fix-itxt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngcp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngfix.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/filter_sse2_intrinsics.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/intel_init.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/filter_msa_intrinsics.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/mips_init.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/powerpc_init.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+       @$(MKDIR_P) $(@D)
+       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .S.o:
 @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -1091,6 +1222,9 @@ mostlyclean-libtool:
 clean-libtool:
        -rm -rf .libs _libs
        -rm -rf arm/.libs arm/_libs
+       -rm -rf intel/.libs intel/_libs
+       -rm -rf mips/.libs mips/_libs
+       -rm -rf powerpc/.libs powerpc/_libs
 
 distclean-libtool:
        -rm -f libtool config.lt
@@ -1423,7 +1557,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
        fi;                                                             \
        $$success || exit 1
 
-check-TESTS:
+check-TESTS: $(check_PROGRAMS)
        @list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
        @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
        @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@@ -1451,6 +1585,13 @@ tests/pngtest.log: tests/pngtest
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/pngtest-badpngs.log: tests/pngtest-badpngs
+       @p='tests/pngtest-badpngs'; \
+       b='tests/pngtest-badpngs'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 tests/pngvalid-gamma-16-to-8.log: tests/pngvalid-gamma-16-to-8
        @p='tests/pngvalid-gamma-16-to-8'; \
        b='tests/pngvalid-gamma-16-to-8'; \
@@ -1683,7 +1824,10 @@ tests/pngimage-full.log: tests/pngimage-full
 @am__EXEEXT_TRUE@      $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
 @am__EXEEXT_TRUE@      "$$tst" $(AM_TESTS_FD_REDIRECT)
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
        $(am__remove_distdir)
        test -d "$(distdir)" || mkdir "$(distdir)"
        @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -1726,7 +1870,7 @@ distdir: $(DISTFILES)
          ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
        || chmod -R a+r "$(distdir)"
 dist-gzip: distdir
-       tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
        $(am__post_remove_distdir)
 
 dist-bzip2: distdir
@@ -1751,7 +1895,7 @@ dist-shar: distdir
        @echo WARNING: "Support for shar distribution archives is" \
                       "deprecated." >&2
        @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
-       shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+       shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
        $(am__post_remove_distdir)
 
 dist-zip: distdir
@@ -1769,7 +1913,7 @@ dist dist-all:
 distcheck: dist
        case '$(DIST_ARCHIVES)' in \
        *.tar.gz*) \
-         GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+         eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
        *.tar.bz2*) \
          bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
        *.tar.lz*) \
@@ -1779,7 +1923,7 @@ distcheck: dist
        *.tar.Z*) \
          uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
        *.shar.gz*) \
-         GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+         eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
        *.zip*) \
          unzip $(distdir).zip ;;\
        esac
@@ -1853,12 +1997,12 @@ check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) \
                $(HEADERS) config.h
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \
+       for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: $(BUILT_SOURCES)
@@ -1898,6 +2042,12 @@ distclean-generic:
        -rm -f contrib/libtests/$(am__dirstamp)
        -rm -f contrib/tools/$(DEPDIR)/$(am__dirstamp)
        -rm -f contrib/tools/$(am__dirstamp)
+       -rm -f intel/$(DEPDIR)/$(am__dirstamp)
+       -rm -f intel/$(am__dirstamp)
+       -rm -f mips/$(DEPDIR)/$(am__dirstamp)
+       -rm -f mips/$(am__dirstamp)
+       -rm -f powerpc/$(DEPDIR)/$(am__dirstamp)
+       -rm -f powerpc/$(am__dirstamp)
 
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
@@ -1914,7 +2064,40 @@ clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
 
 distclean: distclean-am
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
-       -rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR)
+               -rm -f ./$(DEPDIR)/png.Plo
+       -rm -f ./$(DEPDIR)/pngerror.Plo
+       -rm -f ./$(DEPDIR)/pngget.Plo
+       -rm -f ./$(DEPDIR)/pngmem.Plo
+       -rm -f ./$(DEPDIR)/pngpread.Plo
+       -rm -f ./$(DEPDIR)/pngread.Plo
+       -rm -f ./$(DEPDIR)/pngrio.Plo
+       -rm -f ./$(DEPDIR)/pngrtran.Plo
+       -rm -f ./$(DEPDIR)/pngrutil.Plo
+       -rm -f ./$(DEPDIR)/pngset.Plo
+       -rm -f ./$(DEPDIR)/pngtest.Po
+       -rm -f ./$(DEPDIR)/pngtrans.Plo
+       -rm -f ./$(DEPDIR)/pngwio.Plo
+       -rm -f ./$(DEPDIR)/pngwrite.Plo
+       -rm -f ./$(DEPDIR)/pngwtran.Plo
+       -rm -f ./$(DEPDIR)/pngwutil.Plo
+       -rm -f arm/$(DEPDIR)/arm_init.Plo
+       -rm -f arm/$(DEPDIR)/filter_neon.Plo
+       -rm -f arm/$(DEPDIR)/filter_neon_intrinsics.Plo
+       -rm -f arm/$(DEPDIR)/palette_neon_intrinsics.Plo
+       -rm -f contrib/libtests/$(DEPDIR)/pngimage.Po
+       -rm -f contrib/libtests/$(DEPDIR)/pngstest.Po
+       -rm -f contrib/libtests/$(DEPDIR)/pngunknown.Po
+       -rm -f contrib/libtests/$(DEPDIR)/pngvalid.Po
+       -rm -f contrib/libtests/$(DEPDIR)/timepng.Po
+       -rm -f contrib/tools/$(DEPDIR)/png-fix-itxt.Po
+       -rm -f contrib/tools/$(DEPDIR)/pngcp.Po
+       -rm -f contrib/tools/$(DEPDIR)/pngfix.Po
+       -rm -f intel/$(DEPDIR)/filter_sse2_intrinsics.Plo
+       -rm -f intel/$(DEPDIR)/intel_init.Plo
+       -rm -f mips/$(DEPDIR)/filter_msa_intrinsics.Plo
+       -rm -f mips/$(DEPDIR)/mips_init.Plo
+       -rm -f powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo
+       -rm -f powerpc/$(DEPDIR)/powerpc_init.Plo
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-hdr distclean-libtool distclean-tags
@@ -1966,7 +2149,40 @@ installcheck-am:
 maintainer-clean: maintainer-clean-am
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
        -rm -rf $(top_srcdir)/autom4te.cache
-       -rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR)
+               -rm -f ./$(DEPDIR)/png.Plo
+       -rm -f ./$(DEPDIR)/pngerror.Plo
+       -rm -f ./$(DEPDIR)/pngget.Plo
+       -rm -f ./$(DEPDIR)/pngmem.Plo
+       -rm -f ./$(DEPDIR)/pngpread.Plo
+       -rm -f ./$(DEPDIR)/pngread.Plo
+       -rm -f ./$(DEPDIR)/pngrio.Plo
+       -rm -f ./$(DEPDIR)/pngrtran.Plo
+       -rm -f ./$(DEPDIR)/pngrutil.Plo
+       -rm -f ./$(DEPDIR)/pngset.Plo
+       -rm -f ./$(DEPDIR)/pngtest.Po
+       -rm -f ./$(DEPDIR)/pngtrans.Plo
+       -rm -f ./$(DEPDIR)/pngwio.Plo
+       -rm -f ./$(DEPDIR)/pngwrite.Plo
+       -rm -f ./$(DEPDIR)/pngwtran.Plo
+       -rm -f ./$(DEPDIR)/pngwutil.Plo
+       -rm -f arm/$(DEPDIR)/arm_init.Plo
+       -rm -f arm/$(DEPDIR)/filter_neon.Plo
+       -rm -f arm/$(DEPDIR)/filter_neon_intrinsics.Plo
+       -rm -f arm/$(DEPDIR)/palette_neon_intrinsics.Plo
+       -rm -f contrib/libtests/$(DEPDIR)/pngimage.Po
+       -rm -f contrib/libtests/$(DEPDIR)/pngstest.Po
+       -rm -f contrib/libtests/$(DEPDIR)/pngunknown.Po
+       -rm -f contrib/libtests/$(DEPDIR)/pngvalid.Po
+       -rm -f contrib/libtests/$(DEPDIR)/timepng.Po
+       -rm -f contrib/tools/$(DEPDIR)/png-fix-itxt.Po
+       -rm -f contrib/tools/$(DEPDIR)/pngcp.Po
+       -rm -f contrib/tools/$(DEPDIR)/pngfix.Po
+       -rm -f intel/$(DEPDIR)/filter_sse2_intrinsics.Plo
+       -rm -f intel/$(DEPDIR)/intel_init.Plo
+       -rm -f mips/$(DEPDIR)/filter_msa_intrinsics.Plo
+       -rm -f mips/$(DEPDIR)/mips_init.Plo
+       -rm -f powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo
+       -rm -f powerpc/$(DEPDIR)/powerpc_init.Plo
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -1994,19 +2210,19 @@ uninstall-man: uninstall-man3 uninstall-man5
 .MAKE: all check check-am install install-am install-data-am \
        install-exec-am install-strip uninstall-am
 
-.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \
-       check-am clean clean-binPROGRAMS clean-checkPROGRAMS \
-       clean-cscope clean-generic clean-libLTLIBRARIES clean-libtool \
-       cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
-       dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \
-       dist-zip distcheck distclean distclean-compile \
-       distclean-generic distclean-hdr distclean-libtool \
-       distclean-tags distcleancheck distdir distuninstallcheck dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-binPROGRAMS install-binSCRIPTS install-data \
-       install-data-am install-data-hook install-dvi install-dvi-am \
-       install-exec install-exec-am install-exec-hook install-html \
-       install-html-am install-info install-info-am \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \
+       check-TESTS check-am clean clean-binPROGRAMS \
+       clean-checkPROGRAMS clean-cscope clean-generic \
+       clean-libLTLIBRARIES clean-libtool cscope cscopelist-am ctags \
+       ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \
+       dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \
+       distclean distclean-compile distclean-generic distclean-hdr \
+       distclean-libtool distclean-tags distcleancheck distdir \
+       distuninstallcheck dvi dvi-am html html-am info info-am \
+       install install-am install-binPROGRAMS install-binSCRIPTS \
+       install-data install-data-am install-data-hook install-dvi \
+       install-dvi-am install-exec install-exec-am install-exec-hook \
+       install-html install-html-am install-info install-info-am \
        install-libLTLIBRARIES install-man install-man3 install-man5 \
        install-nodist_pkgincludeHEADERS install-pdf install-pdf-am \
        install-pkgconfigDATA install-pkgincludeHEADERS install-ps \
@@ -2090,6 +2306,7 @@ contrib/libtests/timepng.o: pnglibconf.h
 
 contrib/tools/makesRGB.o: pnglibconf.h
 contrib/tools/pngfix.o: pnglibconf.h
+contrib/tools/pngcp.o: pnglibconf.h
 
 .c.out:
        rm -f $@ $*.tf[12]
diff --git a/README b/README
index 176928f..e41e0f5 100644 (file)
--- a/README
+++ b/README
@@ -1,15 +1,16 @@
-README for libpng version 1.6.21 - January 15, 2016 (shared library 16.0)
-See the note about version numbers near the top of png.h
+README for libpng version 1.6.36 - December 1, 2018
+===================================================
 
+See the note about version numbers near the top of png.h.
 See INSTALL for instructions on how to install libpng.
 
 Libpng comes in several distribution formats.  Get libpng-*.tar.gz or
-libpng-*.tar.xz or if you want UNIX-style line endings in the text files,
-or lpng*.7z or lpng*.zip if you want DOS-style line endings.
+libpng-*.tar.xz or if you want UNIX-style line endings in the text
+files, or lpng*.7z or lpng*.zip if you want DOS-style line endings.
 
 Version 0.89 was the first official release of libpng.  Don't let the
-fact that it's the first release fool you.  The libpng library has been in
-extensive use and testing since mid-1995.  By late 1997 it had
+fact that it's the first release fool you.  The libpng library has been
+in extensive use and testing since mid-1995.  By late 1997 it had
 finally gotten to the stage where there hadn't been significant
 changes to the API in some time, and people have a bad feeling about
 libraries with versions < 1.0.  Version 1.0.0 was released in
@@ -23,7 +24,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
 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
 access to info_ptr.  These functions are the png_set_<chunk> and
 png_get_<chunk> functions.  These functions should be used when
@@ -60,94 +61,59 @@ the library action on the detection of chunk CRC errors.  It is possible
 to set different actions based on whether the CRC error occurred in a
 critical or an ancillary chunk.
 
-The changes made to the library, and bugs fixed are based on discussions
-on the PNG-implement mailing list and not on material submitted
-privately to Guy, Andreas, or Glenn.  They will forward any good
-suggestions to the list.
-
-For a detailed description on using libpng, read libpng-manual.txt.  For
-examples of libpng in a program, see example.c and pngtest.c.  For usage
-information and restrictions (what little they are) on libpng, see
-png.h.  For a description on using zlib (the compression library used by
-libpng) and zlib's restrictions, see zlib.h
+For a detailed description on using libpng, read libpng-manual.txt.
+For examples of libpng in a program, see example.c and pngtest.c.  For
+usage information and restrictions (what little they are) on libpng,
+see png.h.  For a description on using zlib (the compression library
+used by libpng) and zlib's restrictions, see zlib.h
 
 I have included a general makefile, as well as several machine and
-compiler specific ones, but you may have to modify one for your own needs.
+compiler specific ones, but you may have to modify one for your own
+needs.
 
 You should use zlib 1.0.4 or later to run this, but it MAY work with
 versions as old as zlib 0.95.  Even so, there are bugs in older zlib
 versions which can cause the output of invalid compression streams for
-some images.  You will definitely need zlib 1.0.4 or later if you are
-taking advantage of the MS-DOS "far" structure allocation for the small
-and medium memory models.  You should also note that zlib is a
-compression library that is useful for more things than just PNG files.
-You can use zlib as a drop-in replacement for fread() and fwrite() if
-you are so inclined.
+some images.
+
+You should also note that zlib is a compression library that is useful
+for more things than just PNG files.  You can use zlib as a drop-in
+replacement for fread() and fwrite(), if you are so inclined.
 
-zlib should be available at the same place that libpng is, or at zlib.net.
+zlib should be available at the same place that libpng is, or at
+https://zlib.net.
 
 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
-these at http://www.libpng.org/pub/png/documents/
-
-This code is currently being archived at libpng.sf.net in the
-[DOWNLOAD] area, and at ftp://ftp.simplesystems.org.  If you 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
-Number (ECCN) for libpng is EAR99, which means not subject to export
-controls or International Traffic in Arms Regulations (ITAR) because it
-is open source, publicly available software, that does not contain any
-encryption software.  See the EAR, paragraphs 734.3(b)(3) and 734.7(b).
-
-If you have any code changes, requests, problems, etc., please e-mail
-them to me.  Also, I'd appreciate any make files or project files,
-and any modifications you needed to make to get libpng to compile,
-along with a #define variable to tell what compiler/system you are on.
-If you needed to add transformations to libpng, or wish libpng would
-provide the image in a different way, drop me a note (and code, if
-possible), so I can consider supporting the transformation.
-Finally, if you get any warning messages when compiling libpng
-(note: not zlib), and they are easy to fix, I'd appreciate the
-fix.  Please mention "libpng" somewhere in the subject line.  Thanks.
-
-This release was created and will be supported by myself (of course
-based in a large way on Guy's and Andreas' earlier work), and the PNG
+these at http://www.libpng.org/pub/png/pngdocs.html .
+
+This code is currently being archived at libpng.sourceforge.io in the
+[DOWNLOAD] area, and at http://libpng.download/src .
+
+This release, based in a large way on Glenn's, Guy's and Andreas'
+earlier work, was created and will be supported by myself and the PNG
 development group.
 
 Send comments/corrections/commendations to png-mng-implement at
 lists.sourceforge.net (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
-to subscribe) or to glennrp at users.sourceforge.net
+to subscribe).
 
-You can't reach Guy, the original libpng author, at the addresses
-given in previous versions of this document.  He and Andreas will
-read mail addressed to the png-implement list, however.
-
-Please do not send general questions about PNG.  Send them to
-png-mng-misc at lists.sf.net (subscription required; visit
+Send general questions about the PNG specification to png-mng-misc
+at lists.sourceforge.net (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
-subscribe).  If you have a question about something
-in the PNG specification that is related to using libpng, send it
-to me.  Send me any questions that start with "I was using libpng,
-and ...".  If in doubt, send questions to me.  I'll bounce them
-to others, if necessary.
-
-Please do not send suggestions on how to change PNG.  We have
-been discussing PNG for twenty years now, and it is official and
-finished.  If you have suggestions for libpng, however, I'll
-gladly listen.  Even if your suggestion is not used immediately,
-it may be used later.
+subscribe).
 
 Files in this distribution:
 
       ANNOUNCE      =>  Announcement of this version, with recent changes
+      AUTHORS       =>  List of contributing authors
       CHANGES       =>  Description of changes between libpng versions
       KNOWNBUG      =>  List of known bugs and deficiencies
       LICENSE       =>  License to use and redistribute libpng
       README        =>  This file
       TODO          =>  Things not implemented in the current library
-      Y2KINFO       =>  Statement of Y2K compliance
+      TRADEMARK     =>  Trademark information
       example.c     =>  Example code for using libpng functions
       libpng.3      =>  manual page for libpng (includes libpng-manual.txt)
       libpng-manual.txt  =>  Description of libpng and its functions
@@ -179,18 +145,25 @@ Files in this distribution:
       pngwtran.c    =>  Write data transformations
       pngwutil.c    =>  Write utility functions
       arm           =>  Contains optimized code for the ARM platform
+      powerpc       =>  Contains optimized code for the PowerPC platform
       contrib       =>  Contributions
+       arm-neon         =>  Optimized code for ARM-NEON platform
+       powerpc-vsx      =>  Optimized code for POWERPC-VSX platform
        examples         =>  Example programs
        gregbook         =>  source code for PNG reading and writing, from
                             Greg Roelofs' "PNG: The Definitive Guide",
                             O'Reilly, 1999
        libtests         =>  Test programs
+       mips-msa         =>  Optimized code for MIPS-MSA platform
        pngminim         =>  Minimal decoder, encoder, and progressive decoder
                             programs demonstrating use of pngusr.dfa
        pngminus         =>  Simple pnm2png and png2pnm programs
        pngsuite         =>  Test images
+       testpngs
        tools            =>  Various tools
        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
                         building a DLL
        owatcom          =>  Contains a WATCOM project for building libpng
@@ -201,15 +174,10 @@ Files in this distribution:
       scripts       =>  Directory containing scripts for building libpng:
                             (see scripts/README.txt for the list of scripts)
 
-Good luck, and happy coding.
-
--Glenn Randers-Pehrson (current maintainer, since 1998)
- Internet: glennrp at users.sourceforge.net
-
--Andreas Eric Dilger (former maintainer, 1996-1997)
- Internet: adilger at enel.ucalgary.ca
- Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
+Good luck, and happy coding!
 
--Guy Eric Schalnat (original author and former maintainer, 1995-1996)
- (formerly of Group 42, Inc)
- Internet: gschal at infinet.com
+ * Cosmin Truta (current maintainer, since 2018)
+ * Glenn Randers-Pehrson (former maintainer, 1998-2018)
+ * Andreas Eric Dilger (former maintainer, 1996-1997)
+ * Guy Eric Schalnat (original author and former maintainer, 1995-1996)
+   (formerly of Group 42, Inc.)
diff --git a/TODO b/TODO
index 7263377..562dab0 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,29 +1,23 @@
-/*
 TODO - list of things to do for libpng:
 
-Final bug fixes.
-Better C++ wrapper/full C++ implementation?
-Fix problem with C++ and EXTERN "C".
-cHRM transformation.
-Remove setjmp/longjmp usage in favor of returning error codes.
-Palette creation.
-Add "grayscale->palette" transformation and "palette->grayscale" detection.
-Improved dithering.
-Multi-lingual error and warning message support.
-Complete sRGB transformation (presently it simply uses gamma=0.45455).
-Make profile checking optional via a png_set_something() call.
-Man pages for function calls.
-Better documentation.
-Better filter selection
-   (counting huffman bits/precompression?  filter inertia?  filter costs?).
-Histogram creation.
-Text conversion between different code pages (Latin-1 -> Mac and DOS).
-Avoid building gamma tables whenever possible.
-Use greater precision when changing to linear gamma for compositing against
-  background and doing rgb-to-gray transformation.
-Investigate pre-incremented loop counters and other loop constructions.
-Add interpolated method of handling interlacing.
-Switch to the simpler zlib (zlib/libpng) license if legally possible.
-Extend pngvalid.c to validate more of the libpng transformations.
-
-*/
+* Fix all defects (duh!)
+* Better C++ wrapper / full C++ implementation (?)
+* Fix the problems with C++ and 'extern "C"'.
+* cHRM transformation.
+* Palette creation.
+* "grayscale->palette" transformation and "palette->grayscale" detection.
+* Improved dithering.
+* Multi-lingual error and warning message support.
+* Complete sRGB transformation.  (Currently it simply uses gamma=0.45455.)
+* Man pages for function calls.
+* Better documentation.
+* Better filter selection
+  (e.g., counting huffman bits/precompression; filter inertia; filter costs).
+* Histogram creation.
+* Text conversion between different code pages (e.g., Latin-1 -> Mac).
+* Avoid building gamma tables whenever possible.
+* Greater precision in changing to linear gamma for compositing against
+  background, and in doing rgb-to-gray transformations.
+* Investigate pre-incremented loop counters and other loop constructions.
+* Interpolated method of handling interlacing.
+* More validations for libpng transformations.
diff --git a/TRADEMARK b/TRADEMARK
new file mode 100644 (file)
index 0000000..ac66718
--- /dev/null
+++ b/TRADEMARK
@@ -0,0 +1,8 @@
+TRADEMARK
+=========
+
+The name "libpng" has not been registered by the Copyright owners
+as a trademark in any jurisdiction.  However, because libpng has
+been distributed and maintained world-wide, continually since 1995,
+the Copyright owners claim "common-law trademark protection" in any
+jurisdiction where common-law trademark is recognized.
index 0ea1ad3..bc18c34 100644 (file)
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.16.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.16.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # Figure out how to run the assembler.                      -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -78,7 +78,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -130,7 +130,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -161,7 +161,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -352,13 +352,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@@ -366,49 +365,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  AS_CASE([$CONFIG_FILES],
+          [*\'*], [eval set x "$CONFIG_FILES"],
+          [*], [set x $CONFIG_FILES])
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`AS_DIRNAME("$mf")`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`AS_DIRNAME(["$file"])`
-      AS_MKDIR_P([$dirpart/$fdir])
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`AS_DIRNAME(["$am_mf"])`
+    am_filepart=`AS_BASENAME(["$am_mf"])`
+    AM_RUN_LOG([cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles]) || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).])
+  fi
+  AS_UNSET([am_dirpart])
+  AS_UNSET([am_filepart])
+  AS_UNSET([am_mf])
+  AS_UNSET([am_rc])
+  rm -f conftest-deps.mk
 }
 ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
 
@@ -417,18 +408,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 # -----------------------------
 # This macro should only be invoked once -- use via AC_REQUIRE.
 #
-# This code is only required when automatic dependency tracking
-# is enabled.  FIXME.  This creates each '.P' file that we will
-# need in order to bootstrap the dependency handling code.
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
 AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 [AC_CONFIG_COMMANDS([depfiles],
      [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
-     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
+     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -515,8 +505,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
 AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
 # We need awk for the "check" target (and possibly the TAP driver).  The
 # system "awk" is bad on some platforms.
@@ -583,7 +573,7 @@ END
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -625,7 +615,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -646,7 +636,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -668,7 +658,7 @@ AC_SUBST([am__leading_dot])])
 # Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -703,7 +693,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
 
 # Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -711,49 +701,42 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
 
 # AM_MAKE_INCLUDE()
 # -----------------
-# Check to see how make treats includes.
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
 AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
 am__doit:
-       @echo this is the am__doit target
+       @echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+  AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+      ['0:this is the am__doit target'],
+      [AS_CASE([$s],
+          [BSD], [am__include='.include' am__quote='"'],
+          [am__include='include' am__quote=''])])
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -792,7 +775,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -821,7 +804,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -868,7 +851,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -887,7 +870,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -968,7 +951,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1028,7 +1011,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1056,7 +1039,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1075,7 +1058,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
index fb3d50d..a34ecdb 100644 (file)
@@ -1,14 +1,15 @@
 
 /* arm_init.c - NEON optimised filter functions
  *
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2014,2016 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.16 [December 22, 2014]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
+
 /* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
  * called.
  */
@@ -66,6 +67,7 @@ png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
     * wrong order of the 'ON' and 'default' cases.  UNSET now defaults to OFF,
     * as documented in png.h
     */
+   png_debug(1, "in png_init_filter_functions_neon");
 #ifdef PNG_ARM_NEON_API_SUPPORTED
    switch ((pp->options >> PNG_ARM_NEON) & 3)
    {
index 3b061d6..2308aad 100644 (file)
@@ -1,9 +1,9 @@
 
 /* filter_neon.S - NEON optimised filter functions
  *
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2014,2017 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.16 [December 22, 2014]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -16,7 +16,7 @@
 #define PNG_VERSION_INFO_ONLY
 #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 */
 #endif
 
index d42c788..553c0be 100644 (file)
@@ -1,12 +1,11 @@
 
 /* filter_neon_intrinsics.c - NEON optimised filter functions
  *
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2014,2016 Glenn Randers-Pehrson
  * Written by James Yu <james.yu at linaro.org>, October 2013.
  * Based on filter_neon.S, written by Mans Rullgard, 2011.
  *
- * Last changed in libpng 1.6.16 [December 22, 2014]
- *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
 /* This code requires -mfpu=neon on the command line: */
 #if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
 
-#include <arm_neon.h>
+#if defined(_MSC_VER) && defined(_M_ARM64)
+#  include <arm64_neon.h>
+#else
+#  include <arm_neon.h>
+#endif
 
 /* libpng row pointers are not necessarily aligned to any particular boundary,
  * however this code will only work with appropriate alignment.  arm/arm_init.c
  * 'type'.  This is written this way just to hide the GCC strict aliasing
  * warning; note that the code is safe because there never is an alias between
  * the input and output pointers.
+ *
+ * When compiling with MSVC ARM64, the png_ldr macro can't be passed directly
+ * to vst4_lane_u32, because of an internal compiler error inside MSVC.
+ * To avoid this compiler bug, we use a temporary variable (vdest_val) to store
+ * the result of png_ldr.
  */
 #define png_ldr(type,pointer)\
    (temp_pointer = png_ptr(type,pointer), *temp_pointer)
@@ -47,6 +55,8 @@ png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,
    png_bytep rp_stop = row + row_info->rowbytes;
    png_const_bytep pp = prev_row;
 
+   png_debug(1, "in png_read_filter_row_up_neon");
+
    for (; rp < rp_stop; rp += 16, pp += 16)
    {
       uint8x16_t qrp, qpp;
@@ -72,6 +82,8 @@ png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
    uint8x8x4_t vdest;
    vdest.val[3] = vdup_n_u8(0);
 
+   png_debug(1, "in png_read_filter_row_sub3_neon");
+
    for (; rp < rp_stop;)
    {
       uint8x8_t vtmp1, vtmp2;
@@ -113,18 +125,23 @@ png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,
    uint8x8x4_t vdest;
    vdest.val[3] = vdup_n_u8(0);
 
+   png_debug(1, "in png_read_filter_row_sub4_neon");
+
    for (; rp < rp_stop; rp += 16)
    {
       uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
       uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
       uint8x8x4_t vrp = *vrpt;
       uint32x2x4_t *temp_pointer;
+      uint32x2x4_t vdest_val;
 
       vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
       vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
       vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
       vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
-      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+
+      vdest_val = png_ldr(uint32x2x4_t, &vdest);
+      vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
    }
 
    PNG_UNUSED(prev_row)
@@ -148,6 +165,8 @@ png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,
    vrpt = png_ptr(uint8x8x2_t,&vtmp);
    vrp = *vrpt;
 
+   png_debug(1, "in png_read_filter_row_avg3_neon");
+
    for (; rp < rp_stop; pp += 12)
    {
       uint8x8_t vtmp1, vtmp2, vtmp3;
@@ -207,12 +226,15 @@ png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
    uint8x8x4_t vdest;
    vdest.val[3] = vdup_n_u8(0);
 
+   png_debug(1, "in png_read_filter_row_avg4_neon");
+
    for (; rp < rp_stop; rp += 16, pp += 16)
    {
       uint32x2x4_t vtmp;
       uint8x8x4_t *vrpt, *vppt;
       uint8x8x4_t vrp, vpp;
       uint32x2x4_t *temp_pointer;
+      uint32x2x4_t vdest_val;
 
       vtmp = vld4_u32(png_ptr(uint32_t,rp));
       vrpt = png_ptr(uint8x8x4_t,&vtmp);
@@ -230,7 +252,8 @@ png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
       vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
       vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
 
-      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+      vdest_val = png_ldr(uint32x2x4_t, &vdest);
+      vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
    }
 }
 
@@ -280,6 +303,8 @@ png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,
    vrpt = png_ptr(uint8x8x2_t,&vtmp);
    vrp = *vrpt;
 
+   png_debug(1, "in png_read_filter_row_paeth3_neon");
+
    for (; rp < rp_stop; pp += 12)
    {
       uint8x8x2_t *vppt;
@@ -339,12 +364,15 @@ png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
    uint8x8x4_t vdest;
    vdest.val[3] = vdup_n_u8(0);
 
+   png_debug(1, "in png_read_filter_row_paeth4_neon");
+
    for (; rp < rp_stop; rp += 16, pp += 16)
    {
       uint32x2x4_t vtmp;
       uint8x8x4_t *vrpt, *vppt;
       uint8x8x4_t vrp, vpp;
       uint32x2x4_t *temp_pointer;
+      uint32x2x4_t vdest_val;
 
       vtmp = vld4_u32(png_ptr(uint32_t,rp));
       vrpt = png_ptr(uint8x8x4_t,&vtmp);
@@ -364,7 +392,8 @@ png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
 
       vlast = vpp.val[3];
 
-      vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+      vdest_val = png_ldr(uint32x2x4_t, &vdest);
+      vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
    }
 }
 
diff --git a/arm/palette_neon_intrinsics.c b/arm/palette_neon_intrinsics.c
new file mode 100644 (file)
index 0000000..fa02d6a
--- /dev/null
@@ -0,0 +1,149 @@
+
+/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2017-2018 Arm Holdings. All rights reserved.
+ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#if PNG_ARM_NEON_IMPLEMENTATION == 1
+
+#if defined(_MSC_VER) && defined(_M_ARM64)
+#  include <arm64_neon.h>
+#else
+#  include <arm_neon.h>
+#endif
+
+/* Build an RGBA palette from the RGB and separate alpha palettes. */
+void
+png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info)
+{
+   png_const_colorp palette = png_ptr->palette;
+   png_bytep riffled_palette = png_ptr->riffled_palette;
+   png_const_bytep trans_alpha = png_ptr->trans_alpha;
+   int num_trans = png_ptr->num_trans;
+   int i;
+
+   /* Initially black, opaque. */
+   uint8x16x4_t w = {{
+      vdupq_n_u8(0x00),
+      vdupq_n_u8(0x00),
+      vdupq_n_u8(0x00),
+      vdupq_n_u8(0xff),
+   }};
+
+   if (row_info->bit_depth != 8)
+   {
+      png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba");
+      return;
+   }
+
+   /* First, riffle the RGB colours into a RGBA palette, the A value is
+    * set to opaque for now.
+    */
+   for (i = 0; i < (1 << row_info->bit_depth); i += 16)
+   {
+      uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
+      w.val[0] = v.val[0];
+      w.val[1] = v.val[1];
+      w.val[2] = v.val[2];
+      vst4q_u8(riffled_palette + (i << 2), w);
+   }
+
+   /* Fix up the missing transparency values. */
+   for (i = 0; i < num_trans; i++)
+      riffled_palette[(i << 2) + 3] = trans_alpha[i];
+}
+
+/* Expands a palettized row into RGBA. */
+int
+png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info,
+    png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
+{
+   png_uint_32 row_width = row_info->width;
+   const png_uint_32 *riffled_palette =
+      (const png_uint_32 *)png_ptr->riffled_palette;
+   const png_int_32 pixels_per_chunk = 4;
+   int i;
+
+   if (row_width < pixels_per_chunk)
+      return 0;
+
+   /* This function originally gets the last byte of the output row.
+    * The NEON part writes forward from a given position, so we have
+    * to seek this back by 4 pixels x 4 bytes.
+    */
+   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
+
+   for (i = 0; i < row_width; i += pixels_per_chunk)
+   {
+      uint32x4_t cur;
+      png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
+      cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
+      cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
+      cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
+      cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
+      vst1q_u32((void *)dp, cur);
+   }
+   if (i != row_width)
+   {
+      /* Remove the amount that wasn't processed. */
+      i -= pixels_per_chunk;
+   }
+
+   /* Decrement output pointers. */
+   *ssp = *ssp - i;
+   *ddp = *ddp - (i << 2);
+   return i;
+}
+
+/* Expands a palettized row into RGB format. */
+int
+png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info,
+    png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
+{
+   png_uint_32 row_width = row_info->width;
+   png_const_bytep palette = (png_const_bytep)png_ptr->palette;
+   const png_uint_32 pixels_per_chunk = 8;
+   int i;
+
+   if (row_width <= pixels_per_chunk)
+      return 0;
+
+   /* Seeking this back by 8 pixels x 3 bytes. */
+   *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
+
+   for (i = 0; i < row_width; i += pixels_per_chunk)
+   {
+      uint8x8x3_t cur;
+      png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
+      cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
+      cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
+      vst3_u8((void *)dp, cur);
+   }
+
+   if (i != row_width)
+   {
+      /* Remove the amount that wasn't processed. */
+      i -= pixels_per_chunk;
+   }
+
+   /* Decrement output pointers. */
+   *ssp = *ssp - i;
+   *ddp = *ddp - ((i << 1) + i);
+   return i;
+}
+
+#endif /* PNG_ARM_NEON_IMPLEMENTATION */
index 9160717..a46daf6 100755 (executable)
@@ -194,7 +194,7 @@ case "$mode" in
       if test -d .git
       then
          exec >&2
-         echo "ERROR: running autoreconf on an initialized sytem"
+         echo "ERROR: running autoreconf on an initialized system"
          echo "  This is not necessary; it is only necessary to remake the"
          echo "  autotools generated files if Makefile.am or configure.ac"
          echo "  change and make does the right thing with:"
diff --git a/compile b/compile
index a85b723..99e5052 100755 (executable)
--- a/compile
+++ b/compile
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand '-c -o'.
 
-scriptversion=2012-10-14.11; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -255,7 +255,8 @@ EOF
     echo "compile $scriptversion"
     exit $?
     ;;
-  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
+  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
     func_cl_wrapper "$@"      # Doesn't return...
     ;;
 esac
@@ -339,9 +340,9 @@ exit $ret
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
index 6c32c86..256083a 100755 (executable)
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2014 Free Software Foundation, Inc.
+#   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2014-11-04'
+timestamp='2018-03-08'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2014-11-04'
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -27,7 +27,7 @@ timestamp='2014-11-04'
 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 #
 # Please send patches to <config-patches@gnu.org>.
 
@@ -39,7 +39,7 @@ Usage: $0 [OPTION]
 
 Output the configuration name of the system \`$me' is run on.
 
-Operation modes:
+Options:
   -h, --help         print this help, then exit
   -t, --time-stamp   print date of last modification, then exit
   -v, --version      print version number, then exit
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -107,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
 dummy=$tmp/dummy ;
 tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
 case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > $dummy.c ;
+ ,,)    echo "int x;" > "$dummy.c" ;
        for c in cc gcc c89 c99 ; do
-         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+         if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
             CC_FOR_BUILD="$c"; break ;
          fi ;
        done ;
@@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
 UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-case "${UNAME_SYSTEM}" in
+case "$UNAME_SYSTEM" in
 Linux|GNU|GNU/*)
        # If the system lacks a compiler, then just pick glibc.
        # We could probably try harder.
        LIBC=gnu
 
-       eval $set_cc_for_build
-       cat <<-EOF > $dummy.c
+       eval "$set_cc_for_build"
+       cat <<-EOF > "$dummy.c"
        #include <features.h>
        #if defined(__UCLIBC__)
        LIBC=uclibc
@@ -149,13 +149,20 @@ Linux|GNU|GNU/*)
        LIBC=gnu
        #endif
        EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+       eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+
+       # If ldd exists, use it to detect musl libc.
+       if command -v ldd >/dev/null && \
+               ldd --version 2>&1 | grep -q ^musl
+       then
+           LIBC=musl
+       fi
        ;;
 esac
 
 # Note: order is significant - the case branches are not exclusive.
 
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *:NetBSD:*:*)
        # NetBSD (nbsd) targets should (where applicable) match one or
        # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -168,21 +175,31 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # Note: NetBSD doesn't particularly care about the vendor
        # portion of the name.  We always set it to "unknown".
        sysctl="sysctl -n hw.machine_arch"
-       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
-           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
-       case "${UNAME_MACHINE_ARCH}" in
+       UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+           "/sbin/$sysctl" 2>/dev/null || \
+           "/usr/sbin/$sysctl" 2>/dev/null || \
+           echo unknown)`
+       case "$UNAME_MACHINE_ARCH" in
            armeb) machine=armeb-unknown ;;
            arm*) machine=arm-unknown ;;
            sh3el) machine=shl-unknown ;;
            sh3eb) machine=sh-unknown ;;
            sh5el) machine=sh5le-unknown ;;
-           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+           earmv*)
+               arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+               endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+               machine="${arch}${endian}"-unknown
+               ;;
+           *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
        esac
        # The Operating System including object format, if it has switched
-       # to ELF recently, or will in the future.
-       case "${UNAME_MACHINE_ARCH}" in
+       # to ELF recently (or will in the future) and ABI.
+       case "$UNAME_MACHINE_ARCH" in
+           earm*)
+               os=netbsdelf
+               ;;
            arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-               eval $set_cc_for_build
+               eval "$set_cc_for_build"
                if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
                        | grep -q __ELF__
                then
@@ -197,44 +214,67 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                os=netbsd
                ;;
        esac
+       # Determine ABI tags.
+       case "$UNAME_MACHINE_ARCH" in
+           earm*)
+               expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+               abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+               ;;
+       esac
        # The OS release
        # Debian GNU/NetBSD machines have a different userland, and
        # thus, need a distinct triplet. However, they do not need
        # kernel version information, so it can be replaced with a
        # suitable tag, in the style of linux-gnu.
-       case "${UNAME_VERSION}" in
+       case "$UNAME_VERSION" in
            Debian*)
                release='-gnu'
                ;;
            *)
-               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+               release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
                ;;
        esac
        # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
        # contains redundant information, the shorter form:
        # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-       echo "${machine}-${os}${release}"
+       echo "$machine-${os}${release}${abi}"
        exit ;;
     *:Bitrig:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-       echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+       echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
        exit ;;
     *:OpenBSD:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-       echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
+       exit ;;
+    *:LibertyBSD:*:*)
+       UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+       echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+       exit ;;
+    *:MidnightBSD:*:*)
+       echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
        exit ;;
     *:ekkoBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
        exit ;;
     *:SolidBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
        exit ;;
     macppc:MirBSD:*:*)
-       echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+       echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
        exit ;;
     *:MirBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
        exit ;;
+    *:Sortix:*:*)
+       echo "$UNAME_MACHINE"-unknown-sortix
+       exit ;;
+    *:Redox:*:*)
+       echo "$UNAME_MACHINE"-unknown-redox
+       exit ;;
+    mips:OSF1:*.*)
+        echo mips-dec-osf1
+        exit ;;
     alpha:OSF1:*:*)
        case $UNAME_RELEASE in
        *4.0)
@@ -251,63 +291,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
        case "$ALPHA_CPU_TYPE" in
            "EV4 (21064)")
-               UNAME_MACHINE="alpha" ;;
+               UNAME_MACHINE=alpha ;;
            "EV4.5 (21064)")
-               UNAME_MACHINE="alpha" ;;
+               UNAME_MACHINE=alpha ;;
            "LCA4 (21066/21068)")
-               UNAME_MACHINE="alpha" ;;
+               UNAME_MACHINE=alpha ;;
            "EV5 (21164)")
-               UNAME_MACHINE="alphaev5" ;;
+               UNAME_MACHINE=alphaev5 ;;
            "EV5.6 (21164A)")
-               UNAME_MACHINE="alphaev56" ;;
+               UNAME_MACHINE=alphaev56 ;;
            "EV5.6 (21164PC)")
-               UNAME_MACHINE="alphapca56" ;;
+               UNAME_MACHINE=alphapca56 ;;
            "EV5.7 (21164PC)")
-               UNAME_MACHINE="alphapca57" ;;
+               UNAME_MACHINE=alphapca57 ;;
            "EV6 (21264)")
-               UNAME_MACHINE="alphaev6" ;;
+               UNAME_MACHINE=alphaev6 ;;
            "EV6.7 (21264A)")
-               UNAME_MACHINE="alphaev67" ;;
+               UNAME_MACHINE=alphaev67 ;;
            "EV6.8CB (21264C)")
-               UNAME_MACHINE="alphaev68" ;;
+               UNAME_MACHINE=alphaev68 ;;
            "EV6.8AL (21264B)")
-               UNAME_MACHINE="alphaev68" ;;
+               UNAME_MACHINE=alphaev68 ;;
            "EV6.8CX (21264D)")
-               UNAME_MACHINE="alphaev68" ;;
+               UNAME_MACHINE=alphaev68 ;;
            "EV6.9A (21264/EV69A)")
-               UNAME_MACHINE="alphaev69" ;;
+               UNAME_MACHINE=alphaev69 ;;
            "EV7 (21364)")
-               UNAME_MACHINE="alphaev7" ;;
+               UNAME_MACHINE=alphaev7 ;;
            "EV7.9 (21364A)")
-               UNAME_MACHINE="alphaev79" ;;
+               UNAME_MACHINE=alphaev79 ;;
        esac
        # A Pn.n version is a patched version.
        # A Vn.n version is a released version.
        # A Tn.n version is a released field test version.
        # A Xn.n version is an unreleased experimental baselevel.
        # 1.2 uses "1.2" for uname -r.
-       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
        # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
        exitcode=$?
        trap '' 0
        exit $exitcode ;;
-    Alpha\ *:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # Should we change UNAME_MACHINE based on the output of uname instead
-       # of the specific Alpha model?
-       echo alpha-pc-interix
-       exit ;;
-    21064:Windows_NT:50:3)
-       echo alpha-dec-winnt3.5
-       exit ;;
     Amiga*:UNIX_System_V:4.0:*)
        echo m68k-unknown-sysv4
        exit ;;
     *:[Aa]miga[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-amigaos
+       echo "$UNAME_MACHINE"-unknown-amigaos
        exit ;;
     *:[Mm]orph[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-morphos
+       echo "$UNAME_MACHINE"-unknown-morphos
        exit ;;
     *:OS/390:*:*)
        echo i370-ibm-openedition
@@ -319,7 +350,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        echo powerpc-ibm-os400
        exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-       echo arm-acorn-riscix${UNAME_RELEASE}
+       echo arm-acorn-riscix"$UNAME_RELEASE"
        exit ;;
     arm*:riscos:*:*|arm*:RISCOS:*:*)
        echo arm-unknown-riscos
@@ -346,38 +377,38 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
            sparc) echo sparc-icl-nx7; exit ;;
        esac ;;
     s390x:SunOS:*:*)
-       echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
        exit ;;
     sun4H:SunOS:5.*:*)
-       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
        exit ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-       echo i386-pc-auroraux${UNAME_RELEASE}
+       echo i386-pc-auroraux"$UNAME_RELEASE"
        exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-       eval $set_cc_for_build
-       SUN_ARCH="i386"
+       eval "$set_cc_for_build"
+       SUN_ARCH=i386
        # If there is a compiler, see if it is configured for 64-bit objects.
        # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
        # This test works for both compilers.
-       if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+       if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
            if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-               (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+               (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
                grep IS_64BIT_ARCH >/dev/null
            then
-               SUN_ARCH="x86_64"
+               SUN_ARCH=x86_64
            fi
        fi
-       echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     sun4*:SunOS:6*:*)
        # According to config.sub, this is the proper way to canonicalize
        # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
        # it's likely to be more like Solaris than SunOS4.
-       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     sun4*:SunOS:*:*)
        case "`/usr/bin/arch -k`" in
@@ -386,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                ;;
        esac
        # Japanese Language versions have a version number like `4.1.3-JL'.
-       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
        exit ;;
     sun3*:SunOS:*:*)
-       echo m68k-sun-sunos${UNAME_RELEASE}
+       echo m68k-sun-sunos"$UNAME_RELEASE"
        exit ;;
     sun*:*:4.2BSD:*)
        UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
        case "`/bin/arch`" in
            sun3)
-               echo m68k-sun-sunos${UNAME_RELEASE}
+               echo m68k-sun-sunos"$UNAME_RELEASE"
                ;;
            sun4)
-               echo sparc-sun-sunos${UNAME_RELEASE}
+               echo sparc-sun-sunos"$UNAME_RELEASE"
                ;;
        esac
        exit ;;
     aushp:SunOS:*:*)
-       echo sparc-auspex-sunos${UNAME_RELEASE}
+       echo sparc-auspex-sunos"$UNAME_RELEASE"
        exit ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
@@ -415,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint"$UNAME_RELEASE"
        exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint"$UNAME_RELEASE"
        exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint"$UNAME_RELEASE"
        exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-       echo m68k-milan-mint${UNAME_RELEASE}
+       echo m68k-milan-mint"$UNAME_RELEASE"
        exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-       echo m68k-hades-mint${UNAME_RELEASE}
+       echo m68k-hades-mint"$UNAME_RELEASE"
        exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-       echo m68k-unknown-mint${UNAME_RELEASE}
+       echo m68k-unknown-mint"$UNAME_RELEASE"
        exit ;;
     m68k:machten:*:*)
-       echo m68k-apple-machten${UNAME_RELEASE}
+       echo m68k-apple-machten"$UNAME_RELEASE"
        exit ;;
     powerpc:machten:*:*)
-       echo powerpc-apple-machten${UNAME_RELEASE}
+       echo powerpc-apple-machten"$UNAME_RELEASE"
        exit ;;
     RISC*:Mach:*:*)
        echo mips-dec-mach_bsd4.3
        exit ;;
     RISC*:ULTRIX:*:*)
-       echo mips-dec-ultrix${UNAME_RELEASE}
+       echo mips-dec-ultrix"$UNAME_RELEASE"
        exit ;;
     VAX*:ULTRIX*:*:*)
-       echo vax-dec-ultrix${UNAME_RELEASE}
+       echo vax-dec-ultrix"$UNAME_RELEASE"
        exit ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
-       echo clipper-intergraph-clix${UNAME_RELEASE}
+       echo clipper-intergraph-clix"$UNAME_RELEASE"
        exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
+       eval "$set_cc_for_build"
+       sed 's/^        //' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
        int main (int argc, char *argv[]) {
@@ -461,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 #endif
        #if defined (host_mips) && defined (MIPSEB)
        #if defined (SYSTYPE_SYSV)
-         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+         printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
        #endif
        #if defined (SYSTYPE_SVR4)
-         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+         printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
        #endif
        #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
-         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+         printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
        #endif
        #endif
          exit (-1);
        }
 EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c &&
-         dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-         SYSTEM_NAME=`$dummy $dummyarg` &&
+       $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+         dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+         SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
            { echo "$SYSTEM_NAME"; exit; }
-       echo mips-mips-riscos${UNAME_RELEASE}
+       echo mips-mips-riscos"$UNAME_RELEASE"
        exit ;;
     Motorola:PowerMAX_OS:*:*)
        echo powerpc-motorola-powermax
@@ -503,17 +534,17 @@ EOF
     AViiON:dgux:*:*)
        # DG/UX returns AViiON for all architectures
        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
        then
-           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
-              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+              [ "$TARGET_BINARY_INTERFACE"x = x ]
            then
-               echo m88k-dg-dgux${UNAME_RELEASE}
+               echo m88k-dg-dgux"$UNAME_RELEASE"
            else
-               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+               echo m88k-dg-dguxbcs"$UNAME_RELEASE"
            fi
        else
-           echo i586-dg-dgux${UNAME_RELEASE}
+           echo i586-dg-dgux"$UNAME_RELEASE"
        fi
        exit ;;
     M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
@@ -530,7 +561,7 @@ EOF
        echo m68k-tektronix-bsd
        exit ;;
     *:IRIX*:*:*)
-       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
        exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
        echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
@@ -542,14 +573,14 @@ EOF
        if [ -x /usr/bin/oslevel ] ; then
                IBM_REV=`/usr/bin/oslevel`
        else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+               IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
        fi
-       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
        exit ;;
     *:AIX:2:3)
        if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-               eval $set_cc_for_build
-               sed 's/^                //' << EOF >$dummy.c
+               eval "$set_cc_for_build"
+               sed 's/^                //' << EOF > "$dummy.c"
                #include <sys/systemcfg.h>
 
                main()
@@ -560,7 +591,7 @@ EOF
                        exit(0);
                        }
 EOF
-               if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+               if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
                then
                        echo "$SYSTEM_NAME"
                else
@@ -574,7 +605,7 @@ EOF
        exit ;;
     *:AIX:*:[4567])
        IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
-       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+       if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
                IBM_ARCH=rs6000
        else
                IBM_ARCH=powerpc
@@ -583,18 +614,18 @@ EOF
                IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
                           awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
        else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+               IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
        fi
-       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
        exit ;;
     *:AIX:*:*)
        echo rs6000-ibm-aix
        exit ;;
-    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+    ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
        echo romp-ibm-bsd4.4
        exit ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to
        exit ;;                             # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
        echo rs6000-bull-bosx
@@ -609,28 +640,28 @@ EOF
        echo m68k-hp-bsd4.4
        exit ;;
     9000/[34678]??:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       case "${UNAME_MACHINE}" in
-           9000/31? )            HP_ARCH=m68000 ;;
-           9000/[34]?? )         HP_ARCH=m68k ;;
+       HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+       case "$UNAME_MACHINE" in
+           9000/31?)            HP_ARCH=m68000 ;;
+           9000/[34]??)         HP_ARCH=m68k ;;
            9000/[678][0-9][0-9])
                if [ -x /usr/bin/getconf ]; then
                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                   case "${sc_cpu_version}" in
-                     523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                     528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                   case "$sc_cpu_version" in
+                     523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+                     528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
                      532)                      # CPU_PA_RISC2_0
-                       case "${sc_kernel_bits}" in
-                         32) HP_ARCH="hppa2.0n" ;;
-                         64) HP_ARCH="hppa2.0w" ;;
-                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                       case "$sc_kernel_bits" in
+                         32) HP_ARCH=hppa2.0n ;;
+                         64) HP_ARCH=hppa2.0w ;;
+                         '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
                        esac ;;
                    esac
                fi
-               if [ "${HP_ARCH}" = "" ]; then
-                   eval $set_cc_for_build
-                   sed 's/^            //' << EOF >$dummy.c
+               if [ "$HP_ARCH" = "" ]; then
+                   eval "$set_cc_for_build"
+                   sed 's/^            //' << EOF > "$dummy.c"
 
                #define _HPUX_SOURCE
                #include <stdlib.h>
@@ -663,13 +694,13 @@ EOF
                    exit (0);
                }
 EOF
-                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
                    test -z "$HP_ARCH" && HP_ARCH=hppa
                fi ;;
        esac
-       if [ ${HP_ARCH} = "hppa2.0w" ]
+       if [ "$HP_ARCH" = hppa2.0w ]
        then
-           eval $set_cc_for_build
+           eval "$set_cc_for_build"
 
            # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
            # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -680,23 +711,23 @@ EOF
            # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
            # => hppa64-hp-hpux11.23
 
-           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+           if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
                grep -q __LP64__
            then
-               HP_ARCH="hppa2.0w"
+               HP_ARCH=hppa2.0w
            else
-               HP_ARCH="hppa64"
+               HP_ARCH=hppa64
            fi
        fi
-       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
        exit ;;
     ia64:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       echo ia64-hp-hpux${HPUX_REV}
+       HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux"$HPUX_REV"
        exit ;;
     3050*:HI-UX:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
+       eval "$set_cc_for_build"
+       sed 's/^        //' << EOF > "$dummy.c"
        #include <unistd.h>
        int
        main ()
@@ -721,11 +752,11 @@ EOF
          exit (0);
        }
 EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+       $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
                { echo "$SYSTEM_NAME"; exit; }
        echo unknown-hitachi-hiuxwe2
        exit ;;
-    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
        echo hppa1.1-hp-bsd
        exit ;;
     9000/8??:4.3bsd:*:*)
@@ -734,7 +765,7 @@ EOF
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
        echo hppa1.0-hp-mpeix
        exit ;;
-    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
        echo hppa1.1-hp-osf
        exit ;;
     hp8??:OSF1:*:*)
@@ -742,9 +773,9 @@ EOF
        exit ;;
     i*86:OSF1:*:*)
        if [ -x /usr/sbin/sysversion ] ; then
-           echo ${UNAME_MACHINE}-unknown-osf1mk
+           echo "$UNAME_MACHINE"-unknown-osf1mk
        else
-           echo ${UNAME_MACHINE}-unknown-osf1
+           echo "$UNAME_MACHINE"-unknown-osf1
        fi
        exit ;;
     parisc*:Lites*:*:*)
@@ -769,127 +800,109 @@ EOF
        echo c4-convex-bsd
        exit ;;
     CRAY*Y-MP:*:*:*)
-       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*[A-Z]90:*:*:*)
-       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
        | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
              -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
              -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*TS:*:*:*)
-       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*T3E:*:*:*)
-       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*SV1:*:*:*)
-       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     *:UNICOS/mp:*:*)
-       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-       FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+       FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+       FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+       FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        exit ;;
     5000:UNIX_System_V:4.*:*)
-       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-       FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+       FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+       FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
        exit ;;
     sparc*:BSD/OS:*:*)
-       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       echo sparc-unknown-bsdi"$UNAME_RELEASE"
        exit ;;
     *:BSD/OS:*:*)
-       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
        exit ;;
     *:FreeBSD:*:*)
        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       case ${UNAME_PROCESSOR} in
+       case "$UNAME_PROCESSOR" in
            amd64)
-               echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-           *)
-               echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+               UNAME_PROCESSOR=x86_64 ;;
+           i386)
+               UNAME_PROCESSOR=i586 ;;
        esac
+       echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
        exit ;;
     i*:CYGWIN*:*)
-       echo ${UNAME_MACHINE}-pc-cygwin
+       echo "$UNAME_MACHINE"-pc-cygwin
        exit ;;
     *:MINGW64*:*)
-       echo ${UNAME_MACHINE}-pc-mingw64
+       echo "$UNAME_MACHINE"-pc-mingw64
        exit ;;
     *:MINGW*:*)
-       echo ${UNAME_MACHINE}-pc-mingw32
+       echo "$UNAME_MACHINE"-pc-mingw32
        exit ;;
     *:MSYS*:*)
-       echo ${UNAME_MACHINE}-pc-msys
-       exit ;;
-    i*:windows32*:*)
-       # uname -m includes "-pc" on this system.
-       echo ${UNAME_MACHINE}-mingw32
+       echo "$UNAME_MACHINE"-pc-msys
        exit ;;
     i*:PW*:*)
-       echo ${UNAME_MACHINE}-pc-pw32
+       echo "$UNAME_MACHINE"-pc-pw32
        exit ;;
     *:Interix*:*)
-       case ${UNAME_MACHINE} in
+       case "$UNAME_MACHINE" in
            x86)
-               echo i586-pc-interix${UNAME_RELEASE}
+               echo i586-pc-interix"$UNAME_RELEASE"
                exit ;;
            authenticamd | genuineintel | EM64T)
-               echo x86_64-unknown-interix${UNAME_RELEASE}
+               echo x86_64-unknown-interix"$UNAME_RELEASE"
                exit ;;
            IA64)
-               echo ia64-unknown-interix${UNAME_RELEASE}
+               echo ia64-unknown-interix"$UNAME_RELEASE"
                exit ;;
        esac ;;
-    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
-       echo i${UNAME_MACHINE}-pc-mks
-       exit ;;
-    8664:Windows_NT:*)
-       echo x86_64-pc-mks
-       exit ;;
-    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
-       # UNAME_MACHINE based on the output of uname instead of i386?
-       echo i586-pc-interix
-       exit ;;
     i*:UWIN*:*)
-       echo ${UNAME_MACHINE}-pc-uwin
+       echo "$UNAME_MACHINE"-pc-uwin
        exit ;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
        echo x86_64-unknown-cygwin
        exit ;;
-    p*:CYGWIN*:*)
-       echo powerpcle-unknown-cygwin
-       exit ;;
     prep*:SunOS:5.*:*)
-       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     *:GNU:*:*)
        # the GNU system
-       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
        exit ;;
     *:GNU/*:*:*)
        # other systems with GNU libc and userland
-       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+       echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
        exit ;;
     i*86:Minix:*:*)
-       echo ${UNAME_MACHINE}-pc-minix
+       echo "$UNAME_MACHINE"-pc-minix
        exit ;;
     aarch64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     aarch64_be:Linux:*:*)
        UNAME_MACHINE=aarch64_be
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     alpha:Linux:*:*)
        case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -902,58 +915,64 @@ EOF
          EV68*) UNAME_MACHINE=alphaev68 ;;
        esac
        objdump --private-headers /bin/sh | grep -q ld.so.1
-       if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     arc:Linux:*:* | arceb:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     arm*:Linux:*:*)
-       eval $set_cc_for_build
+       eval "$set_cc_for_build"
        if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
            | grep -q __ARM_EABI__
        then
-           echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+           echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        else
            if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
                | grep -q __ARM_PCS_VFP
            then
-               echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+               echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
            else
-               echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+               echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
            fi
        fi
        exit ;;
     avr32*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     cris:Linux:*:*)
-       echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+       echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
        exit ;;
     crisv32:Linux:*:*)
-       echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+       echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+       exit ;;
+    e2k:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     frv:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     hexagon:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     i*86:Linux:*:*)
-       echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+       echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
        exit ;;
     ia64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+       exit ;;
+    k1om:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     m32r*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     m68*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
+       eval "$set_cc_for_build"
+       sed 's/^        //' << EOF > "$dummy.c"
        #undef CPU
        #undef ${UNAME_MACHINE}
        #undef ${UNAME_MACHINE}el
@@ -967,64 +986,70 @@ EOF
        #endif
        #endif
 EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
-       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+       eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
+       test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
        ;;
+    mips64el:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+       exit ;;
     openrisc*:Linux:*:*)
-       echo or1k-unknown-linux-${LIBC}
+       echo or1k-unknown-linux-"$LIBC"
        exit ;;
     or32:Linux:*:* | or1k*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     padre:Linux:*:*)
-       echo sparc-unknown-linux-${LIBC}
+       echo sparc-unknown-linux-"$LIBC"
        exit ;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-       echo hppa64-unknown-linux-${LIBC}
+       echo hppa64-unknown-linux-"$LIBC"
        exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
        # Look for CPU level
        case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-         PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
-         PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
-         *)    echo hppa-unknown-linux-${LIBC} ;;
+         PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+         PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+         *)    echo hppa-unknown-linux-"$LIBC" ;;
        esac
        exit ;;
     ppc64:Linux:*:*)
-       echo powerpc64-unknown-linux-${LIBC}
+       echo powerpc64-unknown-linux-"$LIBC"
        exit ;;
     ppc:Linux:*:*)
-       echo powerpc-unknown-linux-${LIBC}
+       echo powerpc-unknown-linux-"$LIBC"
        exit ;;
     ppc64le:Linux:*:*)
-       echo powerpc64le-unknown-linux-${LIBC}
+       echo powerpc64le-unknown-linux-"$LIBC"
        exit ;;
     ppcle:Linux:*:*)
-       echo powerpcle-unknown-linux-${LIBC}
+       echo powerpcle-unknown-linux-"$LIBC"
+       exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-       echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+       echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
        exit ;;
     sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     sh*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     tile*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     vax:Linux:*:*)
-       echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+       echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
        exit ;;
     x86_64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
        exit ;;
     xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     i*86:DYNIX/ptx:4*:*)
        # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1038,34 +1063,34 @@ EOF
        # I am not positive that other SVR4 systems won't match this,
        # I just have to hope.  -- rms.
        # Use sysv4.2uw... so that sysv4* matches it.
-       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
        exit ;;
     i*86:OS/2:*:*)
        # If we were able to find `uname', then EMX Unix compatibility
        # is probably installed.
-       echo ${UNAME_MACHINE}-pc-os2-emx
+       echo "$UNAME_MACHINE"-pc-os2-emx
        exit ;;
     i*86:XTS-300:*:STOP)
-       echo ${UNAME_MACHINE}-unknown-stop
+       echo "$UNAME_MACHINE"-unknown-stop
        exit ;;
     i*86:atheos:*:*)
-       echo ${UNAME_MACHINE}-unknown-atheos
+       echo "$UNAME_MACHINE"-unknown-atheos
        exit ;;
     i*86:syllable:*:*)
-       echo ${UNAME_MACHINE}-pc-syllable
+       echo "$UNAME_MACHINE"-pc-syllable
        exit ;;
     i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-       echo i386-unknown-lynxos${UNAME_RELEASE}
+       echo i386-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     i*86:*DOS:*:*)
-       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       echo "$UNAME_MACHINE"-pc-msdosdjgpp
        exit ;;
-    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
-       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+    i*86:*:4.*:*)
+       UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
        if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+               echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
        else
-               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+               echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
        fi
        exit ;;
     i*86:*:5:[678]*)
@@ -1075,12 +1100,12 @@ EOF
            *Pentium)        UNAME_MACHINE=i586 ;;
            *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
        esac
-       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
        exit ;;
     i*86:*:3.2:*)
        if test -f /usr/options/cb.name; then
                UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+               echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
        elif /bin/uname -X 2>/dev/null >/dev/null ; then
                UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
                (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1090,9 +1115,9 @@ EOF
                        && UNAME_MACHINE=i686
                (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
                        && UNAME_MACHINE=i686
-               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+               echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
        else
-               echo ${UNAME_MACHINE}-pc-sysv32
+               echo "$UNAME_MACHINE"-pc-sysv32
        fi
        exit ;;
     pc:*:*:*)
@@ -1100,7 +1125,7 @@ EOF
        # uname -m prints for DJGPP always 'pc', but it prints nothing about
        # the processor, so we play safe by assuming i586.
        # Note: whatever this is, it MUST be the same as what config.sub
-       # prints for the "djgpp" host, or else GDB configury will decide that
+       # prints for the "djgpp" host, or else GDB configure will decide that
        # this is a cross-build.
        echo i586-pc-msdosdjgpp
        exit ;;
@@ -1112,9 +1137,9 @@ EOF
        exit ;;
     i860:*:4.*:*) # i860-SVR4
        if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+         echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
        else # Add other i860-SVR4 vendors below as they are discovered.
-         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+         echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4
        fi
        exit ;;
     mini*:CTIX:SYS*5:*)
@@ -1134,9 +1159,9 @@ EOF
        test -r /etc/.relid \
        && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-         && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+         && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
        /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-         && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+         && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
          && { echo i486-ncr-sysv4; exit; } ;;
@@ -1145,28 +1170,28 @@ EOF
        test -r /etc/.relid \
            && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-           && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+           && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
        /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+           && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
        /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+           && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       echo m68k-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     mc68030:UNIX_System_V:4.*:*)
        echo m68k-atari-sysv4
        exit ;;
     TSUNAMI:LynxOS:2.*:*)
-       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       echo sparc-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     rs6000:LynxOS:2.*:*)
-       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       echo rs6000-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       echo powerpc-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     SM[BE]S:UNIX_SV:*:*)
-       echo mips-dde-sysv${UNAME_RELEASE}
+       echo mips-dde-sysv"$UNAME_RELEASE"
        exit ;;
     RM*:ReliantUNIX-*:*:*)
        echo mips-sni-sysv4
@@ -1177,7 +1202,7 @@ EOF
     *:SINIX-*:*:*)
        if uname -p 2>/dev/null >/dev/null ; then
                UNAME_MACHINE=`(uname -p) 2>/dev/null`
-               echo ${UNAME_MACHINE}-sni-sysv4
+               echo "$UNAME_MACHINE"-sni-sysv4
        else
                echo ns32k-sni-sysv
        fi
@@ -1197,23 +1222,23 @@ EOF
        exit ;;
     i*86:VOS:*:*)
        # From Paul.Green@stratus.com.
-       echo ${UNAME_MACHINE}-stratus-vos
+       echo "$UNAME_MACHINE"-stratus-vos
        exit ;;
     *:VOS:*:*)
        # From Paul.Green@stratus.com.
        echo hppa1.1-stratus-vos
        exit ;;
     mc68*:A/UX:*:*)
-       echo m68k-apple-aux${UNAME_RELEASE}
+       echo m68k-apple-aux"$UNAME_RELEASE"
        exit ;;
     news*:NEWS-OS:6*:*)
        echo mips-sony-newsos6
        exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
        if [ -d /usr/nec ]; then
-               echo mips-nec-sysv${UNAME_RELEASE}
+               echo mips-nec-sysv"$UNAME_RELEASE"
        else
-               echo mips-unknown-sysv${UNAME_RELEASE}
+               echo mips-unknown-sysv"$UNAME_RELEASE"
        fi
        exit ;;
     BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
@@ -1232,46 +1257,56 @@ EOF
        echo x86_64-unknown-haiku
        exit ;;
     SX-4:SUPER-UX:*:*)
-       echo sx4-nec-superux${UNAME_RELEASE}
+       echo sx4-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-5:SUPER-UX:*:*)
-       echo sx5-nec-superux${UNAME_RELEASE}
+       echo sx5-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-6:SUPER-UX:*:*)
-       echo sx6-nec-superux${UNAME_RELEASE}
+       echo sx6-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-7:SUPER-UX:*:*)
-       echo sx7-nec-superux${UNAME_RELEASE}
+       echo sx7-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-8:SUPER-UX:*:*)
-       echo sx8-nec-superux${UNAME_RELEASE}
+       echo sx8-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-8R:SUPER-UX:*:*)
-       echo sx8r-nec-superux${UNAME_RELEASE}
+       echo sx8r-nec-superux"$UNAME_RELEASE"
+       exit ;;
+    SX-ACE:SUPER-UX:*:*)
+       echo sxace-nec-superux"$UNAME_RELEASE"
        exit ;;
     Power*:Rhapsody:*:*)
-       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       echo powerpc-apple-rhapsody"$UNAME_RELEASE"
        exit ;;
     *:Rhapsody:*:*)
-       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
        exit ;;
     *:Darwin:*:*)
        UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       eval $set_cc_for_build
+       eval "$set_cc_for_build"
        if test "$UNAME_PROCESSOR" = unknown ; then
            UNAME_PROCESSOR=powerpc
        fi
-       if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-           if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+       if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
+           if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
                if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-                   (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-                   grep IS_64BIT_ARCH >/dev/null
+                      (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+                      grep IS_64BIT_ARCH >/dev/null
                then
                    case $UNAME_PROCESSOR in
                        i386) UNAME_PROCESSOR=x86_64 ;;
                        powerpc) UNAME_PROCESSOR=powerpc64 ;;
                    esac
                fi
+               # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+               if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+                      (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+                      grep IS_PPC >/dev/null
+               then
+                   UNAME_PROCESSOR=powerpc
+               fi
            fi
        elif test "$UNAME_PROCESSOR" = i386 ; then
            # Avoid executing cc on OS X 10.9, as it ships with a stub
@@ -1282,27 +1317,33 @@ EOF
            # that Apple uses in portable devices.
            UNAME_PROCESSOR=x86_64
        fi
-       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
        exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
        UNAME_PROCESSOR=`uname -p`
-       if test "$UNAME_PROCESSOR" = "x86"; then
+       if test "$UNAME_PROCESSOR" = x86; then
                UNAME_PROCESSOR=i386
                UNAME_MACHINE=pc
        fi
-       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
        exit ;;
     *:QNX:*:4*)
        echo i386-pc-qnx
        exit ;;
-    NEO-?:NONSTOP_KERNEL:*:*)
-       echo neo-tandem-nsk${UNAME_RELEASE}
+    NEO-*:NONSTOP_KERNEL:*:*)
+       echo neo-tandem-nsk"$UNAME_RELEASE"
        exit ;;
     NSE-*:NONSTOP_KERNEL:*:*)
-       echo nse-tandem-nsk${UNAME_RELEASE}
+       echo nse-tandem-nsk"$UNAME_RELEASE"
+       exit ;;
+    NSR-*:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk"$UNAME_RELEASE"
        exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
-       echo nsr-tandem-nsk${UNAME_RELEASE}
+    NSV-*:NONSTOP_KERNEL:*:*)
+       echo nsv-tandem-nsk"$UNAME_RELEASE"
+       exit ;;
+    NSX-*:NONSTOP_KERNEL:*:*)
+       echo nsx-tandem-nsk"$UNAME_RELEASE"
        exit ;;
     *:NonStop-UX:*:*)
        echo mips-compaq-nonstopux
@@ -1311,18 +1352,18 @@ EOF
        echo bs2000-siemens-sysv
        exit ;;
     DS/*:UNIX_System_V:*:*)
-       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
        exit ;;
     *:Plan9:*:*)
        # "uname -m" is not consistent, so use $cputype instead. 386
        # is converted to i386 for consistency with other x86
        # operating systems.
-       if test "$cputype" = "386"; then
+       if test "$cputype" = 386; then
            UNAME_MACHINE=i386
        else
            UNAME_MACHINE="$cputype"
        fi
-       echo ${UNAME_MACHINE}-unknown-plan9
+       echo "$UNAME_MACHINE"-unknown-plan9
        exit ;;
     *:TOPS-10:*:*)
        echo pdp10-unknown-tops10
@@ -1343,14 +1384,14 @@ EOF
        echo pdp10-unknown-its
        exit ;;
     SEI:*:*:SEIUX)
-       echo mips-sei-seiux${UNAME_RELEASE}
+       echo mips-sei-seiux"$UNAME_RELEASE"
        exit ;;
     *:DragonFly:*:*)
-       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
        exit ;;
     *:*VMS:*:*)
        UNAME_MACHINE=`(uname -p) 2>/dev/null`
-       case "${UNAME_MACHINE}" in
+       case "$UNAME_MACHINE" in
            A*) echo alpha-dec-vms ; exit ;;
            I*) echo ia64-dec-vms ; exit ;;
            V*) echo vax-dec-vms ; exit ;;
@@ -1359,34 +1400,48 @@ EOF
        echo i386-pc-xenix
        exit ;;
     i*86:skyos:*:*)
-       echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+       echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
        exit ;;
     i*86:rdos:*:*)
-       echo ${UNAME_MACHINE}-pc-rdos
+       echo "$UNAME_MACHINE"-pc-rdos
        exit ;;
     i*86:AROS:*:*)
-       echo ${UNAME_MACHINE}-pc-aros
+       echo "$UNAME_MACHINE"-pc-aros
        exit ;;
     x86_64:VMkernel:*:*)
-       echo ${UNAME_MACHINE}-unknown-esx
+       echo "$UNAME_MACHINE"-unknown-esx
+       exit ;;
+    amd64:Isilon\ OneFS:*:*)
+       echo x86_64-unknown-onefs
        exit ;;
 esac
 
+echo "$0: unable to guess system type" >&2
+
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+    mips:Linux | mips64:Linux)
+       # If we got here on MIPS GNU/Linux, output extra information.
+       cat >&2 <<EOF
+
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
+EOF
+       ;;
+esac
+
 cat >&2 <<EOF
-$0: unable to guess system type
 
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
 
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
 
 config.guess timestamp = $timestamp
 
@@ -1405,16 +1460,16 @@ hostinfo               = `(hostinfo) 2>/dev/null`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
 
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM  = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM  = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
 EOF
 
 exit 1
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
index 898037e..2931048 100644 (file)
@@ -18,9 +18,6 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
-/* Define to 1 if you have the `memset' function. */
-#undef HAVE_MEMSET
-
 /* Define to 1 if you have the `pow' function. */
 #undef HAVE_POW
 
 /* Enable ARM Neon optimizations */
 #undef PNG_ARM_NEON_OPT
 
+/* Enable Intel SSE optimizations */
+#undef PNG_INTEL_SSE_OPT
+
+/* Turn on MIPS MSA optimizations at run-time */
+#undef PNG_MIPS_MSA_API_SUPPORTED
+
+/* Check for MIPS MSA support at run-time */
+#undef PNG_MIPS_MSA_CHECK_SUPPORTED
+
+/* Enable MIPS MSA optimizations */
+#undef PNG_MIPS_MSA_OPT
+
+/* Turn on POWERPC VSX optimizations at run-time */
+#undef PNG_POWERPC_VSX_API_SUPPORTED
+
+/* Check for POWERPC VSX support at run-time */
+#undef PNG_POWERPC_VSX_CHECK_SUPPORTED
+
+/* Enable POWERPC VSX optimizations */
+#undef PNG_POWERPC_VSX_OPT
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
index 7ffe373..9ccf09a 100755 (executable)
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2014 Free Software Foundation, Inc.
+#   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2014-12-03'
+timestamp='2018-03-08'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@ timestamp='2014-12-03'
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -33,7 +33,7 @@ timestamp='2014-12-03'
 # Otherwise, we print the canonical config type on stdout and succeed.
 
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
@@ -53,12 +53,11 @@ timestamp='2014-12-03'
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
 
 Canonicalize a configuration name.
 
-Operation modes:
+Options:
   -h, --help         print this help, then exit
   -t, --time-stamp   print date of last modification, then exit
   -v, --version      print version number, then exit
@@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -95,7 +94,7 @@ while test $# -gt 0 ; do
 
     *local*)
        # First pass through any local machine types.
-       echo $1
+       echo "$1"
        exit ;;
 
     * )
@@ -113,24 +112,24 @@ esac
 
 # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
 # Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  kopensolaris*-gnu* | cloudabi*-eabi* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
   android-linux)
     os=-linux-android
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
     ;;
   *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
+    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
+    if [ "$basic_machine" != "$1" ]
+    then os=`echo "$1" | sed 's/.*-/-/'`
     else os=; fi
     ;;
 esac
@@ -179,44 +178,44 @@ case $os in
                ;;
        -sco6)
                os=-sco5v6
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco5)
                os=-sco3.2v5
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco4)
                os=-sco3.2v4
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco3.2.[4-9]*)
                os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco3.2v[4-9]*)
                # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco5v6*)
                # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco*)
                os=-sco3.2v2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -udk*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -isc)
                os=-isc2.2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -clix*)
                basic_machine=clipper-intergraph
                ;;
        -isc*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -lynx*178)
                os=-lynxos178
@@ -228,10 +227,7 @@ case $os in
                os=-lynxos
                ;;
        -ptx*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-               ;;
-       -windowsnt*)
-               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
                ;;
        -psos*)
                os=-psos
@@ -255,15 +251,16 @@ case $basic_machine in
        | arc | arceb \
        | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
        | avr | avr32 \
+       | ba \
        | be32 | be64 \
        | bfin \
        | c4x | c8051 | clipper \
        | d10v | d30v | dlx | dsp16xx \
-       | epiphany \
-       | fido | fr30 | frv \
+       | e2k | epiphany \
+       | fido | fr30 | frv | ft32 \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
        | hexagon \
-       | i370 | i860 | i960 | ia64 \
+       | i370 | i860 | i960 | ia16 | ia64 \
        | ip2k | iq2000 \
        | k1om \
        | le32 | le64 \
@@ -299,13 +296,14 @@ case $basic_machine in
        | nios | nios2 | nios2eb | nios2el \
        | ns16k | ns32k \
        | open8 | or1k | or1knd | or32 \
-       | pdp10 | pdp11 | pj | pjl \
+       | pdp10 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle \
+       | pru \
        | pyramid \
        | riscv32 | riscv64 \
        | rl78 | rx \
        | score \
-       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
        | sh64 | sh64le \
        | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
        | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +312,7 @@ case $basic_machine in
        | ubicom32 \
        | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
        | visium \
-       | we32k \
+       | wasm32 \
        | x86 | xc16x | xstormy16 | xtensa \
        | z8k | z80)
                basic_machine=$basic_machine-unknown
@@ -335,7 +333,7 @@ case $basic_machine in
                basic_machine=$basic_machine-unknown
                os=-none
                ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
                ;;
        ms1)
                basic_machine=mt-unknown
@@ -364,7 +362,7 @@ case $basic_machine in
          ;;
        # Object if more than one company name word.
        *-*-*)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
                exit 1
                ;;
        # Recognize the basic CPU types with company name.
@@ -376,17 +374,18 @@ case $basic_machine in
        | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
        | avr-* | avr32-* \
+       | ba-* \
        | be32-* | be64-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* \
        | c8051-* | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
-       | elxsi-* \
+       | e2k-* | elxsi-* \
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
        | hexagon-* \
-       | i*86-* | i860-* | i960-* | ia64-* \
+       | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
        | ip2k-* | iq2000-* \
        | k1om-* \
        | le32-* | le64-* \
@@ -427,13 +426,15 @@ case $basic_machine in
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+       | pru-* \
        | pyramid-* \
+       | riscv32-* | riscv64-* \
        | rl78-* | romp-* | rs6000-* | rx-* \
        | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
        | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
        | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
        | tahoe-* \
        | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
        | tile*-* \
@@ -442,6 +443,7 @@ case $basic_machine in
        | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
        | vax-* \
        | visium-* \
+       | wasm32-* \
        | we32k-* \
        | x86-* | x86_64-* | xc16x-* | xps100-* \
        | xstormy16-* | xtensa*-* \
@@ -455,7 +457,7 @@ case $basic_machine in
        # Recognize the various machine names and aliases which stand
        # for a CPU type and a company and sometimes even an OS.
        386bsd)
-               basic_machine=i386-unknown
+               basic_machine=i386-pc
                os=-bsd
                ;;
        3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
@@ -489,7 +491,7 @@ case $basic_machine in
                basic_machine=x86_64-pc
                ;;
        amd64-*)
-               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        amdahl)
                basic_machine=580-amdahl
@@ -518,6 +520,9 @@ case $basic_machine in
                basic_machine=i386-pc
                os=-aros
                ;;
+       asmjs)
+               basic_machine=asmjs-unknown
+               ;;
        aux)
                basic_machine=m68k-apple
                os=-aux
@@ -531,7 +536,7 @@ case $basic_machine in
                os=-linux
                ;;
        blackfin-*)
-               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                os=-linux
                ;;
        bluegene*)
@@ -539,13 +544,13 @@ case $basic_machine in
                os=-cnk
                ;;
        c54x-*)
-               basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        c55x-*)
-               basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        c6x-*)
-               basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        c90)
                basic_machine=c90-cray
@@ -634,10 +639,18 @@ case $basic_machine in
                basic_machine=rs6000-bull
                os=-bosx
                ;;
-       dpx2* | dpx2*-bull)
+       dpx2*)
                basic_machine=m68k-bull
                os=-sysv3
                ;;
+       e500v[12])
+               basic_machine=powerpc-unknown
+               os=$os"spe"
+               ;;
+       e500v[12]-*)
+               basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+               os=$os"spe"
+               ;;
        ebmon29k)
                basic_machine=a29k-amd
                os=-ebmon
@@ -727,9 +740,6 @@ case $basic_machine in
        hp9k8[0-9][0-9] | hp8[0-9][0-9])
                basic_machine=hppa1.0-hp
                ;;
-       hppa-next)
-               os=-nextstep3
-               ;;
        hppaosf)
                basic_machine=hppa1.1-hp
                os=-osf
@@ -742,26 +752,26 @@ case $basic_machine in
                basic_machine=i370-ibm
                ;;
        i*86v32)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-sysv32
                ;;
        i*86v4*)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-sysv4
                ;;
        i*86v)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-sysv
                ;;
        i*86sol2)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-solaris2
                ;;
        i386mach)
                basic_machine=i386-mach
                os=-mach
                ;;
-       i386-vsta | vsta)
+       vsta)
                basic_machine=i386-unknown
                os=-vsta
                ;;
@@ -780,19 +790,16 @@ case $basic_machine in
                os=-sysv
                ;;
        leon-*|leon[3-9]-*)
-               basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+               basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
                ;;
        m68knommu)
                basic_machine=m68k-unknown
                os=-linux
                ;;
        m68knommu-*)
-               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                os=-linux
                ;;
-       m88k-omron*)
-               basic_machine=m88k-omron
-               ;;
        magnum | m3230)
                basic_machine=mips-mips
                os=-sysv
@@ -824,10 +831,10 @@ case $basic_machine in
                os=-mint
                ;;
        mips3*-*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
                ;;
        mips3*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
                ;;
        monitor)
                basic_machine=m68k-rom68k
@@ -846,7 +853,7 @@ case $basic_machine in
                os=-msdos
                ;;
        ms1-*)
-               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+               basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
                ;;
        msys)
                basic_machine=i686-pc
@@ -888,7 +895,7 @@ case $basic_machine in
                basic_machine=v70-nec
                os=-sysv
                ;;
-       next | m*-next )
+       next | m*-next)
                basic_machine=m68k-next
                case $os in
                    -nextstep* )
@@ -933,6 +940,12 @@ case $basic_machine in
        nsr-tandem)
                basic_machine=nsr-tandem
                ;;
+       nsv-tandem)
+               basic_machine=nsv-tandem
+               ;;
+       nsx-tandem)
+               basic_machine=nsx-tandem
+               ;;
        op50n-* | op60c-*)
                basic_machine=hppa1.1-oki
                os=-proelf
@@ -965,7 +978,7 @@ case $basic_machine in
                os=-linux
                ;;
        parisc-*)
-               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                os=-linux
                ;;
        pbd)
@@ -981,7 +994,7 @@ case $basic_machine in
                basic_machine=i386-pc
                ;;
        pc98-*)
-               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentium | p5 | k5 | k6 | nexgen | viac3)
                basic_machine=i586-pc
@@ -996,16 +1009,16 @@ case $basic_machine in
                basic_machine=i786-pc
                ;;
        pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentium4-*)
-               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pn)
                basic_machine=pn-gould
@@ -1015,23 +1028,23 @@ case $basic_machine in
        ppc | ppcbe)    basic_machine=powerpc-unknown
                ;;
        ppc-* | ppcbe-*)
-               basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
-       ppcle | powerpclittle | ppc-le | powerpc-little)
+       ppcle | powerpclittle)
                basic_machine=powerpcle-unknown
                ;;
        ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        ppc64)  basic_machine=powerpc64-unknown
                ;;
-       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+       ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
-       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+       ppc64le | powerpc64little)
                basic_machine=powerpc64le-unknown
                ;;
        ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        ps2)
                basic_machine=i386-ibm
@@ -1085,17 +1098,10 @@ case $basic_machine in
        sequent)
                basic_machine=i386-sequent
                ;;
-       sh)
-               basic_machine=sh-hitachi
-               os=-hms
-               ;;
        sh5el)
                basic_machine=sh5le-unknown
                ;;
-       sh64)
-               basic_machine=sh64-unknown
-               ;;
-       sparclite-wrs | simso-wrs)
+       simso-wrs)
                basic_machine=sparclite-wrs
                os=-vxworks
                ;;
@@ -1114,7 +1120,7 @@ case $basic_machine in
                os=-sysv4
                ;;
        strongarm-* | thumb-*)
-               basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        sun2)
                basic_machine=m68000-sun
@@ -1236,6 +1242,9 @@ case $basic_machine in
                basic_machine=hppa1.1-winbond
                os=-proelf
                ;;
+       x64)
+               basic_machine=x86_64-pc
+               ;;
        xbox)
                basic_machine=i686-pc
                os=-mingw32
@@ -1244,20 +1253,12 @@ case $basic_machine in
                basic_machine=xps100-honeywell
                ;;
        xscale-* | xscalee[bl]-*)
-               basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+               basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
                ;;
        ymp)
                basic_machine=ymp-cray
                os=-unicos
                ;;
-       z8k-*-coff)
-               basic_machine=z8k-unknown
-               os=-sim
-               ;;
-       z80-*-coff)
-               basic_machine=z80-unknown
-               os=-sim
-               ;;
        none)
                basic_machine=none-none
                os=-none
@@ -1286,10 +1287,6 @@ case $basic_machine in
        vax)
                basic_machine=vax-dec
                ;;
-       pdp10)
-               # there are many clones, so DEC is not a safe bet
-               basic_machine=pdp10-unknown
-               ;;
        pdp11)
                basic_machine=pdp11-dec
                ;;
@@ -1299,9 +1296,6 @@ case $basic_machine in
        sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
                basic_machine=sh-unknown
                ;;
-       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-               basic_machine=sparc-sun
-               ;;
        cydra)
                basic_machine=cydra-cydrome
                ;;
@@ -1321,7 +1315,7 @@ case $basic_machine in
                # Make sure to match an already-canonicalized machine name.
                ;;
        *)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
                exit 1
                ;;
 esac
@@ -1329,10 +1323,10 @@ esac
 # Here we canonicalize certain aliases for manufacturers.
 case $basic_machine in
        *-digital*)
-               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
                ;;
        *-commodore*)
-               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
                ;;
        *)
                ;;
@@ -1343,8 +1337,8 @@ esac
 if [ x"$os" != x"" ]
 then
 case $os in
-       # First match some system type aliases
-       # that might get confused with valid system types.
+       # First match some system type aliases that might get confused
+       # with valid system types.
        # -solaris* is a basic system type, with this one exception.
        -auroraux)
                os=-auroraux
@@ -1355,45 +1349,48 @@ case $os in
        -solaris)
                os=-solaris2
                ;;
-       -svr4*)
-               os=-sysv4
-               ;;
        -unixware*)
                os=-sysv4.2uw
                ;;
        -gnu/linux*)
                os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
                ;;
-       # First accept the basic system types.
+       # es1800 is here to avoid being matched by es* (a different OS)
+       -es1800*)
+               os=-ose
+               ;;
+       # Now accept the basic system types.
        # The portable systems comes first.
-       # Each alternative MUST END IN A *, to match a version number.
+       # Each alternative MUST end in a * to match a version number.
        # -sysv* is not here because it comes later, after sysvr4.
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
              | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
              | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
              | -sym* | -kopensolaris* | -plan9* \
              | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* | -aros* \
+             | -aos* | -aros* | -cloudabi* | -sortix* \
              | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
              | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -bitrig* | -openbsd* | -solidbsd* \
+             | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
+             | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
              | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
              | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* | -cegcc* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \
+             | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
              | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+             | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
              | -linux-newlib* | -linux-musl* | -linux-uclibc* \
              | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
-             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
              | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
              | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+             | -morphos* | -superux* | -rtmk* | -windiss* \
              | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+             | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
+             | -midnightbsd*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
        -qnx*)
@@ -1410,12 +1407,12 @@ case $os in
        -nto*)
                os=`echo $os | sed -e 's|nto|nto-qnx|'`
                ;;
-       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+       -sim | -xray | -os68k* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* \
              | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
                ;;
        -mac*)
-               os=`echo $os | sed -e 's|mac|macos|'`
+               os=`echo "$os" | sed -e 's|mac|macos|'`
                ;;
        -linux-dietlibc)
                os=-linux-dietlibc
@@ -1424,10 +1421,10 @@ case $os in
                os=`echo $os | sed -e 's|linux|linux-gnu|'`
                ;;
        -sunos5*)
-               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
                ;;
        -sunos6*)
-               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
                ;;
        -opened*)
                os=-openedition
@@ -1438,12 +1435,6 @@ case $os in
        -wince*)
                os=-wince
                ;;
-       -osfrose*)
-               os=-osfrose
-               ;;
-       -osf*)
-               os=-osf
-               ;;
        -utek*)
                os=-bsd
                ;;
@@ -1468,7 +1459,7 @@ case $os in
        -nova*)
                os=-rtmk-nova
                ;;
-       -ns2 )
+       -ns2)
                os=-nextstep2
                ;;
        -nsk*)
@@ -1490,7 +1481,7 @@ case $os in
        -oss*)
                os=-sysv3
                ;;
-       -svr4)
+       -svr4*)
                os=-sysv4
                ;;
        -svr3)
@@ -1505,32 +1496,38 @@ case $os in
        -ose*)
                os=-ose
                ;;
-       -es1800*)
-               os=-ose
-               ;;
-       -xenix)
-               os=-xenix
-               ;;
        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
                os=-mint
                ;;
-       -aros*)
-               os=-aros
-               ;;
        -zvmoe)
                os=-zvmoe
                ;;
        -dicos*)
                os=-dicos
                ;;
+       -pikeos*)
+               # Until real need of OS specific support for
+               # particular features comes up, bare metal
+               # configurations are quite functional.
+               case $basic_machine in
+                   arm*)
+                       os=-eabi
+                       ;;
+                   *)
+                       os=-elf
+                       ;;
+               esac
+               ;;
        -nacl*)
                ;;
+       -ios)
+               ;;
        -none)
                ;;
        *)
                # Get rid of the `-' at the beginning of $os.
                os=`echo $os | sed 's/[^-]*-//'`
-               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
                exit 1
                ;;
 esac
@@ -1620,12 +1617,12 @@ case $basic_machine in
        sparc-* | *-sun)
                os=-sunos4.1.1
                ;;
+       pru-*)
+               os=-elf
+               ;;
        *-be)
                os=-beos
                ;;
-       *-haiku)
-               os=-haiku
-               ;;
        *-ibm)
                os=-aix
                ;;
@@ -1665,7 +1662,7 @@ case $basic_machine in
        m88k-omron*)
                os=-luna
                ;;
-       *-next )
+       *-next)
                os=-nextstep
                ;;
        *-sequent)
@@ -1680,9 +1677,6 @@ case $basic_machine in
        i370-*)
                os=-mvs
                ;;
-       *-next)
-               os=-nextstep3
-               ;;
        *-gould)
                os=-sysv
                ;;
@@ -1792,15 +1786,15 @@ case $basic_machine in
                                vendor=stratus
                                ;;
                esac
-               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
                ;;
 esac
 
-echo $basic_machine$os
+echo "$basic_machine$os"
 exit
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
index 1c3e10e..4c8a35e 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libpng 1.6.21.
+# Generated by GNU Autoconf 2.69 for libpng 1.6.36.
 #
 # Report bugs to <png-mng-implement@lists.sourceforge.net>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libpng'
 PACKAGE_TARNAME='libpng'
-PACKAGE_VERSION='1.6.21'
-PACKAGE_STRING='libpng 1.6.21'
+PACKAGE_VERSION='1.6.36'
+PACKAGE_STRING='libpng 1.6.36'
 PACKAGE_BUGREPORT='png-mng-implement@lists.sourceforge.net'
 PACKAGE_URL=''
 
@@ -635,6 +635,12 @@ ac_includes_default="\
 ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
+PNG_POWERPC_VSX_FALSE
+PNG_POWERPC_VSX_TRUE
+PNG_INTEL_SSE_FALSE
+PNG_INTEL_SSE_TRUE
+PNG_MIPS_MSA_FALSE
+PNG_MIPS_MSA_TRUE
 PNG_ARM_NEON_FALSE
 PNG_ARM_NEON_TRUE
 DO_INSTALL_LIBPNG_CONFIG_FALSE
@@ -657,6 +663,8 @@ HAVE_LD_VERSION_SCRIPT_FALSE
 HAVE_LD_VERSION_SCRIPT_TRUE
 HAVE_SOLARIS_LD_FALSE
 HAVE_SOLARIS_LD_TRUE
+HAVE_CLOCK_GETTIME_FALSE
+HAVE_CLOCK_GETTIME_TRUE
 LIBOBJS
 POW_LIB
 PNG_COPTS
@@ -705,7 +713,6 @@ am__nodep
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
-am__quote
 am__include
 DEPDIR
 OBJEXT
@@ -782,7 +789,8 @@ PACKAGE_VERSION
 PACKAGE_TARNAME
 PACKAGE_NAME
 PATH_SEPARATOR
-SHELL'
+SHELL
+am__quote'
 ac_subst_files=''
 ac_user_opts='
 enable_option_checking
@@ -805,7 +813,11 @@ with_libpng_prefix
 enable_unversioned_links
 enable_unversioned_libpng_pc
 enable_unversioned_libpng_config
+enable_hardware_optimizations
 enable_arm_neon
+enable_mips_msa
+enable_intel_sse
+enable_powerpc_vsx
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1360,7 +1372,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libpng 1.6.21 to adapt to many kinds of systems.
+\`configure' configures libpng 1.6.36 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1430,7 +1442,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libpng 1.6.21:";;
+     short | recursive ) echo "Configuration of libpng 1.6.36:";;
    esac
   cat <<\_ACEOF
 
@@ -1482,6 +1494,8 @@ Optional Features:
                           link to the versioned version. This is done by
                           default - use --disable-unversioned-libpng-config to
                           change this.
+  --enable-hardware-optimizations
+                          Enable hardware optimizations: =no/off, yes/on:
   --enable-arm-neon     Enable ARM NEON optimizations: =no/off, check, api,
                           yes/on: no/off: disable the optimizations; check:
                           use internal checking code (deprecated and poorly
@@ -1489,6 +1503,23 @@ Optional Features:
                           call to png_set_option; yes/on: turn on
                           unconditionally. If not specified: determined by the
                           compiler.
+  --enable-mips-msa     Enable MIPS MSA optimizations: =no/off, check, api,
+                          yes/on: no/off: disable the optimizations; check:
+                          use internal checking code (deprecated and poorly
+                          supported); api: disable by default, enable by a
+                          call to png_set_option; yes/on: turn on
+                          unconditionally. If not specified: determined by the
+                          compiler.
+  --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.
+  --enable-powerpc-vsx  Enable POWERPC VSX optimizations: =no/off, check,
+                          api, yes/on: no/off: disable the optimizations;
+                          check: use internal checking code api: disable by
+                          default, enable by a call to png_set_option yes/on:
+                          turn on unconditionally. If not specified:
+                          determined by the compiler.
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1591,7 +1622,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libpng configure 1.6.21
+libpng configure 1.6.36
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1923,7 +1954,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libpng $as_me 1.6.21, which was
+It was created by libpng $as_me 1.6.36, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2279,7 +2310,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 # dist-xz requires automake 1.11 or later
 # 1.12.2 fixes a security issue in 1.11.2 and 1.12.1
 # 1.13 is required for parallel tests
-am__api_version='1.15'
+am__api_version='1.16'
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -2794,7 +2825,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libpng'
- VERSION='1.6.21'
+ VERSION='1.6.36'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2824,8 +2855,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
 # We need awk for the "check" target (and possibly the TAP driver).  The
@@ -2876,7 +2907,7 @@ END
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -2888,7 +2919,7 @@ END
 fi
 
 # The following line causes --disable-maintainer-mode to be the default to
-# configure, this is necessary because libpng distributions cannot rely on the
+# configure. This is necessary because libpng distributions cannot rely on the
 # time stamps of the autotools generated files being correct
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
@@ -2915,10 +2946,10 @@ fi
 
 
 
-PNGLIB_VERSION=1.6.21
+PNGLIB_VERSION=1.6.36
 PNGLIB_MAJOR=1
 PNGLIB_MINOR=6
-PNGLIB_RELEASE=21
+PNGLIB_RELEASE=36
 
 
 
@@ -3783,45 +3814,45 @@ DEPDIR="${am__leading_dot}deps"
 
 ac_config_commands="$ac_config_commands depfiles"
 
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
 am__doit:
-       @echo this is the am__doit target
+       @echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+   (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+  case $?:`cat confinc.out 2>/dev/null` in #(
+  '0:this is the am__doit target') :
+    case $s in #(
+  BSD) :
+    am__include='.include' am__quote='"' ;; #(
+  *) :
+    am__include='include' am__quote='' ;;
+esac ;; #(
+  *) :
      ;;
-   esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
+esac
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
 
 # Check whether --enable-dependency-tracking was given.
 if test "${enable_dependency_tracking+set}" = set; then :
@@ -12597,6 +12628,41 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 
 
+# For GCC 5 the default mode for C is -std=gnu11 instead of -std=gnu89
+# In pngpriv.h we request just the POSIX 1003.1 and C89 APIs by defining _POSIX_SOURCE to 1
+# This is incompatible with the new default mode, so we test for that and force the
+# "-std=c89" compiler option:
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we need to force back C standard to C89" >&5
+$as_echo_n "checking if we need to force back C standard to C89... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+      #define _POSIX_SOURCE 1
+      #include <stdio.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+
+      if test "x$GCC" != "xyes"; then
+         as_fn_error $? "Forcing back to C89 is required but the flags are only known for GCC" "$LINENO" 5
+      fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+   CFLAGS="$CFLAGS -std=c89"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 # Checks for header files.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
 
 fi
 
-for ac_func in memset
-do :
-  ac_fn_c_check_func "$LINENO" "memset" "ac_cv_func_memset"
-if test "x$ac_cv_func_memset" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_MEMSET 1
-_ACEOF
-
-else
-  as_fn_error $? "memset not found in libc" "$LINENO" 5
-fi
-done
-
 for ac_func in pow
 do :
   ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow"
 done
 
 
+# Some later POSIX 1003.1 functions are required for test programs, failure here
+# is soft (the corresponding test program is not built).
+ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: not building timepng" >&5
+$as_echo "$as_me: WARNING: not building timepng" >&2;}
+fi
+
+ if test "$ac_cv_func_clock_gettime" = "yes"; then
+  HAVE_CLOCK_GETTIME_TRUE=
+  HAVE_CLOCK_GETTIME_FALSE='#'
+else
+  HAVE_CLOCK_GETTIME_TRUE='#'
+  HAVE_CLOCK_GETTIME_FALSE=
+fi
+
+
+
 # Check whether --with-zlib-prefix was given.
 if test "${with_zlib_prefix+set}" = set; then :
   withval=$with_zlib_prefix; ZPREFIX=${withval}
 # HOST SPECIFIC OPTIONS
 # =====================
 #
+# DEFAULT
+# =======
+#
+# Check whether --enable-hardware-optimizations was given.
+if test "${enable_hardware_optimizations+set}" = set; then :
+  enableval=$enable_hardware_optimizations; case "$enableval" in
+      no|off)
+         # disable hardware optimization on all systems:
+         enable_arm_neon=no
+
+$as_echo "#define PNG_ARM_NEON_OPT 0" >>confdefs.h
+
+         enable_mips_msa=no
+
+$as_echo "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h
+
+         enable_powerpc_vsx=no
+
+$as_echo "#define PNG_POWERPC_VSX_OPT 0" >>confdefs.h
+
+         enable_intel_sse=no
+
+$as_echo "#define PNG_INTEL_SSE_OPT 0" >>confdefs.h
+
+         ;;
+      *)
+         # allow enabling hardware optimization on any system:
+         case "$host_cpu" in
+            arm*|aarch64*)
+              enable_arm_neon=yes
+
+$as_echo "#define PNG_ARM_NEON_OPT 0" >>confdefs.h
+
+              ;;
+            mipsel*|mips64el*)
+              enable_mips_msa=yes
+
+$as_echo "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h
+
+              ;;
+            i?86|x86_64)
+              enable_intel_sse=yes
+
+$as_echo "#define PNG_INTEL_SSE_OPT 1" >>confdefs.h
+
+              ;;
+            powerpc*|ppc64*)
+              enable_powerpc_vsx=yes
+
+$as_echo "#define PNG_POWERPC_VSX_OPT 2" >>confdefs.h
+
+              ;;
+         esac
+         ;;
+   esac
+fi
+
+
 # ARM
 # ===
 #
@@ -13476,6 +13607,162 @@ else
 fi
 
 
+# MIPS
+# ===
+#
+# MIPS MSA (SIMD) support.
+
+# Check whether --enable-mips-msa was given.
+if test "${enable_mips_msa+set}" = set; then :
+  enableval=$enable_mips_msa; case "$enableval" in
+      no|off)
+         # disable the default enabling on __mips_msa systems:
+
+$as_echo "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h
+
+         # Prevent inclusion of the assembler files below:
+         enable_mips_msa=no;;
+      check)
+
+$as_echo "#define PNG_MIPS_MSA_CHECK_SUPPORTED /**/" >>confdefs.h
+;;
+      api)
+
+$as_echo "#define PNG_MIPS_MSA_API_SUPPORTED /**/" >>confdefs.h
+;;
+      yes|on)
+
+$as_echo "#define PNG_MIPS_MSA_OPT 2" >>confdefs.h
+
+         { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-mips-msa: please specify 'check' or 'api', if
+            you want the optimizations unconditionally pass '-mmsa -mfp64'
+            to the compiler." >&5
+$as_echo "$as_me: WARNING: --enable-mips-msa: please specify 'check' or 'api', if
+            you want the optimizations unconditionally pass '-mmsa -mfp64'
+            to the compiler." >&2;};;
+      *)
+         as_fn_error $? "--enable-mips-msa=${enable_mips_msa}: invalid value" "$LINENO" 5
+   esac
+fi
+
+
+# Add MIPS specific files to all builds where the host_cpu is mips ('mips*') or
+# where MIPS optimizations were explicitly requested (this allows a fallback if a
+# future host CPU does not match 'mips*')
+
+ if test "$enable_mips_msa" != 'no' &&
+    case "$host_cpu" in
+      mipsel*|mips64el*) :;;
+    esac; then
+  PNG_MIPS_MSA_TRUE=
+  PNG_MIPS_MSA_FALSE='#'
+else
+  PNG_MIPS_MSA_TRUE='#'
+  PNG_MIPS_MSA_FALSE=
+fi
+
+
+# INTEL
+# =====
+#
+# INTEL SSE (SIMD) support.
+
+# Check whether --enable-intel-sse was given.
+if test "${enable_intel_sse+set}" = set; then :
+  enableval=$enable_intel_sse; case "$enableval" in
+      no|off)
+         # disable the default enabling:
+
+$as_echo "#define PNG_INTEL_SSE_OPT 0" >>confdefs.h
+
+         # Prevent inclusion of the assembler files below:
+         enable_intel_sse=no;;
+      yes|on)
+
+$as_echo "#define PNG_INTEL_SSE_OPT 1" >>confdefs.h
+;;
+      *)
+         as_fn_error $? "--enable-intel-sse=${enable_intel_sse}: invalid value" "$LINENO" 5
+   esac
+fi
+
+
+# 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*')
+ if test "$enable_intel_sse" != 'no' &&
+    case "$host_cpu" in
+      i?86|x86_64) :;;
+      *)    test "$enable_intel_sse" != '';;
+    esac; then
+  PNG_INTEL_SSE_TRUE=
+  PNG_INTEL_SSE_FALSE='#'
+else
+  PNG_INTEL_SSE_TRUE='#'
+  PNG_INTEL_SSE_FALSE=
+fi
+
+
+# PowerPC
+# ===
+#
+# PowerPC VSX (SIMD) support.
+
+# Check whether --enable-powerpc-vsx was given.
+if test "${enable_powerpc_vsx+set}" = set; then :
+  enableval=$enable_powerpc_vsx; case "$enableval" in
+      no|off)
+         # disable the default enabling on __ppc64__ systems:
+
+$as_echo "#define PNG_POWERPC_VSX_OPT 0" >>confdefs.h
+
+         # Prevent inclusion of the platform specific files below:
+         enable_powerpc_vsx=no;;
+      check)
+
+$as_echo "#define PNG_POWERPC_VSX_CHECK_SUPPORTED /**/" >>confdefs.h
+
+         { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-powerpc-vsx Please check contrib/powerpc/README file
+            for the list of supported OSes." >&5
+$as_echo "$as_me: WARNING: --enable-powerpc-vsx Please check contrib/powerpc/README file
+            for the list of supported OSes." >&2;};;
+      api)
+
+$as_echo "#define PNG_POWERPC_VSX_API_SUPPORTED /**/" >>confdefs.h
+;;
+      yes|on)
+
+$as_echo "#define PNG_POWERPC_VSX_OPT 2" >>confdefs.h
+
+         { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-powerpc-vsx: please specify 'check' or 'api', if
+            you want the optimizations unconditionally pass '-maltivec -mvsx'
+            or '-mcpu=power8'to the compiler." >&5
+$as_echo "$as_me: WARNING: --enable-powerpc-vsx: please specify 'check' or 'api', if
+            you want the optimizations unconditionally pass '-maltivec -mvsx'
+            or '-mcpu=power8'to the compiler." >&2;};;
+      *)
+         as_fn_error $? "--enable-powerpc-vsx=${enable_powerpc_vsx}: invalid value" "$LINENO" 5
+   esac
+fi
+
+
+# Add PowerPC specific files to all builds where the host_cpu is powerpc('powerpc*') or
+# where POWERPC optimizations were explicitly requested (this allows a fallback if a
+# future host CPU does not match 'powerpc*')
+
+ if test "$enable_powerpc_vsx" != 'no' &&
+    case "$host_cpu" in
+      powerpc*|ppc64*) :;;
+    esac; then
+  PNG_POWERPC_VSX_TRUE=
+  PNG_POWERPC_VSX_FALSE='#'
+else
+  PNG_POWERPC_VSX_TRUE='#'
+  PNG_POWERPC_VSX_FALSE=
+fi
+
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: Extra options for compiler: $PNG_COPTS" >&5
 $as_echo "$as_me: Extra options for compiler: $PNG_COPTS" >&6;}
 
@@ -13626,6 +13913,10 @@ if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then
   as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${HAVE_CLOCK_GETTIME_TRUE}" && test -z "${HAVE_CLOCK_GETTIME_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_CLOCK_GETTIME\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${HAVE_SOLARIS_LD_TRUE}" && test -z "${HAVE_SOLARIS_LD_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_SOLARIS_LD\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -13654,6 +13945,18 @@ if test -z "${PNG_ARM_NEON_TRUE}" && test -z "${PNG_ARM_NEON_FALSE}"; then
   as_fn_error $? "conditional \"PNG_ARM_NEON\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${PNG_MIPS_MSA_TRUE}" && test -z "${PNG_MIPS_MSA_FALSE}"; then
+  as_fn_error $? "conditional \"PNG_MIPS_MSA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PNG_INTEL_SSE_TRUE}" && test -z "${PNG_INTEL_SSE_FALSE}"; then
+  as_fn_error $? "conditional \"PNG_INTEL_SSE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PNG_POWERPC_VSX_TRUE}" && test -z "${PNG_POWERPC_VSX_FALSE}"; then
+  as_fn_error $? "conditional \"PNG_POWERPC_VSX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -14051,7 +14354,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libpng $as_me 1.6.21, which was
+This file was extended by libpng $as_me 1.6.36, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -14117,7 +14420,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-libpng config.status 1.6.21
+libpng config.status 1.6.36
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -14236,7 +14539,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 #
 # INIT-COMMANDS
 #
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
 
 
 # The HP-UX ksh and POSIX shell print the target directory to stdout
@@ -15136,29 +15439,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  case $CONFIG_FILES in #(
+  *\'*) :
+    eval set x "$CONFIG_FILES" ;; #(
+  *) :
+    set x $CONFIG_FILES ;; #(
+  *) :
+     ;;
+esac
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-        X"$mf" : 'X\(//\)[^/]' \| \
-        X"$mf" : 'X\(//\)$' \| \
-        X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$am_mf" : 'X\(//\)[^/]' \| \
+        X"$am_mf" : 'X\(//\)$' \| \
+        X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -15176,53 +15485,48 @@ $as_echo X"$mf" |
            q
          }
          s/.*/./; q'`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-        X"$file" : 'X\(//\)[^/]' \| \
-        X"$file" : 'X\(//\)$' \| \
-        X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-           s//\1/
-           q
-         }
-         /^X\(\/\/\)[^/].*/{
+    am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$am_mf" : 'X\(//\)$' \| \
+        X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
            s//\1/
            q
          }
-         /^X\(\/\/\)$/{
+         /^X\/\(\/\/\)$/{
            s//\1/
            q
          }
-         /^X\(\/\).*/{
+         /^X\/\(\/\).*/{
            s//\1/
            q
          }
          s/.*/./; q'`
-      as_dir=$dirpart/$fdir; as_fn_mkdir_p
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    { echo "$as_me:$LINENO: cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles" >&5
+   (cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+  { am_dirpart=; unset am_dirpart;}
+  { am_filepart=; unset am_filepart;}
+  { am_mf=; unset am_mf;}
+  { am_rc=; unset am_rc;}
+  rm -f conftest-deps.mk
 }
  ;;
     "libtool":C)
index 8af866d..1ed63ea 100644 (file)
@@ -1,5 +1,12 @@
 # configure.ac
 
+# Copyright (c) 2018 Cosmin Truta
+# Copyright (c) 2004-2016 Glenn Randers-Pehrson
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
 dnl Process this file with autoconf to produce a configure script.
 dnl
 dnl Minor upgrades (compatible ABI): increment the package version
@@ -18,7 +25,7 @@ AC_PREREQ([2.68])
 
 dnl Version number stuff here:
 
-AC_INIT([libpng],[1.6.21],[png-mng-implement@lists.sourceforge.net])
+AC_INIT([libpng],[1.6.36],[png-mng-implement@lists.sourceforge.net])
 AC_CONFIG_MACRO_DIR([scripts])
 
 # libpng does not follow GNU file name conventions (hence 'foreign')
@@ -29,7 +36,7 @@ AC_CONFIG_MACRO_DIR([scripts])
 # 1.13 is required for parallel tests
 AM_INIT_AUTOMAKE([1.13 foreign dist-xz color-tests silent-rules subdir-objects])
 # The following line causes --disable-maintainer-mode to be the default to
-# configure, this is necessary because libpng distributions cannot rely on the
+# configure. This is necessary because libpng distributions cannot rely on the
 # time stamps of the autotools generated files being correct
 AM_MAINTAINER_MODE
 
@@ -39,10 +46,10 @@ dnl automake, so the following is not necessary (and is not defined anyway):
 dnl AM_PREREQ([1.11.2])
 dnl stop configure from automagically running automake
 
-PNGLIB_VERSION=1.6.21
+PNGLIB_VERSION=1.6.36
 PNGLIB_MAJOR=1
 PNGLIB_MINOR=6
-PNGLIB_RELEASE=21
+PNGLIB_RELEASE=36
 
 dnl End of version number stuff
 
@@ -60,7 +67,7 @@ AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
 
-dnl libtool/libtoolize; version 2.4.2 is the tested version, this or any
+dnl libtool/libtoolize; version 2.4.2 is the tested version. This or any
 dnl compatible later version may be used
 LT_INIT([win32-dll])
 LT_PREREQ([2.4.2])
@@ -107,6 +114,25 @@ AC_ARG_ENABLE(werror,
       CFLAGS="$sav_CFLAGS"
     fi],)
 
+# For GCC 5 the default mode for C is -std=gnu11 instead of -std=gnu89
+# In pngpriv.h we request just the POSIX 1003.1 and C89 APIs by defining _POSIX_SOURCE to 1
+# This is incompatible with the new default mode, so we test for that and force the 
+# "-std=c89" compiler option:
+AC_MSG_CHECKING([if we need to force back C standard to C89])
+AC_COMPILE_IFELSE(
+   [AC_LANG_PROGRAM([
+      [#define _POSIX_SOURCE 1]
+      [#include <stdio.h>]
+   ])],
+   AC_MSG_RESULT(no),[
+      if test "x$GCC" != "xyes"; then
+         AC_MSG_ERROR(
+            [Forcing back to C89 is required but the flags are only known for GCC])
+      fi
+   AC_MSG_RESULT(yes)
+   CFLAGS="$CFLAGS -std=c89"
+])
+
 # Checks for header files.
 AC_HEADER_STDC
 
@@ -118,8 +144,13 @@ AC_C_RESTRICT
 
 # Checks for library functions.
 AC_FUNC_STRTOD
-AC_CHECK_FUNCS([memset], , AC_MSG_ERROR(memset not found in libc))
 AC_CHECK_FUNCS([pow], , AC_CHECK_LIB(m, pow, , AC_MSG_ERROR(cannot find pow)) )
+
+# Some later POSIX 1003.1 functions are required for test programs, failure here
+# is soft (the corresponding test program is not built).
+AC_CHECK_FUNC([clock_gettime],,[AC_MSG_WARN([not building timepng])])
+AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "$ac_cv_func_clock_gettime" = "yes"])
+
 AC_ARG_WITH(zlib-prefix,
    AS_HELP_STRING([[[--with-zlib-prefix]]],
       [prefix that may have been used in installed zlib]),
@@ -268,6 +299,55 @@ AM_CONDITIONAL([DO_INSTALL_LIBPNG_CONFIG],
 # HOST SPECIFIC OPTIONS
 # =====================
 #
+# DEFAULT
+# =======
+#
+AC_ARG_ENABLE([hardware-optimizations],
+   AS_HELP_STRING([[[--enable-hardware-optimizations]]],
+      [Enable hardware optimizations: =no/off, yes/on:]),
+   [case "$enableval" in
+      no|off)
+         # disable hardware optimization on all systems:
+         enable_arm_neon=no
+         AC_DEFINE([PNG_ARM_NEON_OPT], [0],
+           [Disable ARM_NEON optimizations])
+         enable_mips_msa=no
+         AC_DEFINE([PNG_MIPS_MSA_OPT], [0],
+           [Disable MIPS_MSA optimizations])
+         enable_powerpc_vsx=no
+         AC_DEFINE([PNG_POWERPC_VSX_OPT], [0],
+           [Disable POWERPC VSX optimizations])
+         enable_intel_sse=no
+         AC_DEFINE([PNG_INTEL_SSE_OPT], [0],
+           [Disable INTEL_SSE optimizations])
+         ;;
+      *)
+         # allow enabling hardware optimization on any system:
+         case "$host_cpu" in
+            arm*|aarch64*)
+              enable_arm_neon=yes
+              AC_DEFINE([PNG_ARM_NEON_OPT], [0],
+                [Enable ARM_NEON optimizations])
+              ;;
+            mipsel*|mips64el*)
+              enable_mips_msa=yes
+              AC_DEFINE([PNG_MIPS_MSA_OPT], [0],
+                [Enable MIPS_MSA optimizations])
+              ;;
+            i?86|x86_64)
+              enable_intel_sse=yes
+              AC_DEFINE([PNG_INTEL_SSE_OPT], [1],
+                [Enable Intel SSE optimizations])
+              ;;
+            powerpc*|ppc64*)
+              enable_powerpc_vsx=yes
+              AC_DEFINE([PNG_POWERPC_VSX_OPT], [2],
+                [Enable POWERPC VSX optimizations])
+              ;;
+         esac
+         ;;
+   esac])
+
 # ARM
 # ===
 #
@@ -314,6 +394,134 @@ AM_CONDITIONAL([PNG_ARM_NEON],
       *)    test "$enable_arm_neon" != '';;
     esac])
 
+# MIPS
+# ===
+#
+# MIPS MSA (SIMD) support.
+
+AC_ARG_ENABLE([mips-msa],
+   AS_HELP_STRING([[[--enable-mips-msa]]],
+      [Enable MIPS MSA optimizations: =no/off, check, api, yes/on:]
+      [no/off: disable the optimizations; check: use internal checking code]
+      [(deprecated and poorly supported); api: disable by default, enable by]
+      [a call to png_set_option; yes/on: turn on unconditionally.]
+      [If not specified: determined by the compiler.]),
+   [case "$enableval" in
+      no|off)
+         # disable the default enabling on __mips_msa systems:
+         AC_DEFINE([PNG_MIPS_MSA_OPT], [0],
+                   [Disable MIPS MSA optimizations])
+         # Prevent inclusion of the assembler files below:
+         enable_mips_msa=no;;
+      check)
+         AC_DEFINE([PNG_MIPS_MSA_CHECK_SUPPORTED], [],
+                   [Check for MIPS MSA support at run-time]);;
+      api)
+         AC_DEFINE([PNG_MIPS_MSA_API_SUPPORTED], [],
+                   [Turn on MIPS MSA optimizations at run-time]);;
+      yes|on)
+         AC_DEFINE([PNG_MIPS_MSA_OPT], [2],
+                   [Enable MIPS MSA optimizations])
+         AC_MSG_WARN([--enable-mips-msa: please specify 'check' or 'api', if]
+            [you want the optimizations unconditionally pass '-mmsa -mfp64']
+            [to the compiler.]);;
+      *)
+         AC_MSG_ERROR([--enable-mips-msa=${enable_mips_msa}: invalid value])
+   esac])
+
+# Add MIPS specific files to all builds where the host_cpu is mips ('mips*') or
+# where MIPS optimizations were explicitly requested (this allows a fallback if a
+# future host CPU does not match 'mips*')
+
+AM_CONDITIONAL([PNG_MIPS_MSA],
+   [test "$enable_mips_msa" != 'no' &&
+    case "$host_cpu" in
+      mipsel*|mips64el*) :;;
+    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])
+
+# PowerPC
+# ===
+#
+# PowerPC VSX (SIMD) support.
+
+AC_ARG_ENABLE([powerpc-vsx],
+AS_HELP_STRING([[[--enable-powerpc-vsx]]],
+      [Enable POWERPC VSX optimizations: =no/off, check, api, yes/on:]
+      [no/off: disable the optimizations; check: use internal checking code]
+      [api: disable by default, enable by a call to png_set_option]
+      [yes/on: turn on unconditionally.]
+      [If not specified: determined by the compiler.]),
+   [case "$enableval" in
+      no|off)
+         # disable the default enabling on __ppc64__ systems:
+         AC_DEFINE([PNG_POWERPC_VSX_OPT], [0],
+                   [Disable POWERPC VSX optimizations])
+         # Prevent inclusion of the platform specific files below:
+         enable_powerpc_vsx=no;;
+      check)
+         AC_DEFINE([PNG_POWERPC_VSX_CHECK_SUPPORTED], [],
+                   [Check for POWERPC VSX support at run-time])
+         AC_MSG_WARN([--enable-powerpc-vsx Please check contrib/powerpc/README file]
+            [for the list of supported OSes.]);;
+      api)
+         AC_DEFINE([PNG_POWERPC_VSX_API_SUPPORTED], [],
+                   [Turn on POWERPC VSX optimizations at run-time]);;
+      yes|on)
+         AC_DEFINE([PNG_POWERPC_VSX_OPT], [2],
+                   [Enable POWERPC VSX optimizations])
+         AC_MSG_WARN([--enable-powerpc-vsx: please specify 'check' or 'api', if]
+            [you want the optimizations unconditionally pass '-maltivec -mvsx']
+            [or '-mcpu=power8'to the compiler.]);;
+      *)
+         AC_MSG_ERROR([--enable-powerpc-vsx=${enable_powerpc_vsx}: invalid value])
+   esac])
+
+# Add PowerPC specific files to all builds where the host_cpu is powerpc('powerpc*') or
+# where POWERPC optimizations were explicitly requested (this allows a fallback if a
+# future host CPU does not match 'powerpc*')
+
+AM_CONDITIONAL([PNG_POWERPC_VSX],
+   [test "$enable_powerpc_vsx" != 'no' &&
+    case "$host_cpu" in
+      powerpc*|ppc64*) :;;
+    esac])
+
+
 AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]])
 
 # Config files, substituting as above
index 7240123..fb3a489 100644 (file)
@@ -17,7 +17,7 @@
  *
  * Documentation:
  *    http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
- *    http://code.google.com/p/android/issues/detail?id=49065
+ *    https://code.google.com/p/android/issues/detail?id=49065
  *
  * NOTE: this requires that libpng is built against the Android NDK and linked
  * with an implementation of the Android ARM 'cpu-features' library.  The code
index 94f9bb1..a9bc360 100644 (file)
@@ -1,8 +1,8 @@
 /* contrib/arm-neon/linux.c
  *
- * Copyright (c) 2014 Glenn Randers-Pehrson
- * Written by John Bowler, 2014.
- * Last changed in libpng 1.6.16 [December 22, 2014]
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Copyright (c) 2014, 2017 Glenn Randers-Pehrson
+ * Written by John Bowler, 2014, 2017.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -62,7 +62,7 @@ png_have_neon(png_structp png_ptr)
 
                counter=0;
                state = Feature;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case Feature:
                /* Match 'FEATURE', ASCII case insensitive. */
@@ -75,7 +75,7 @@ png_have_neon(png_structp png_ptr)
 
                /* did not match 'feature' */
                state = SkipLine;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case SkipLine:
             skipLine:
@@ -110,7 +110,7 @@ png_have_neon(png_structp png_ptr)
 
                state = Neon;
                counter = 0;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case Neon:
                /* Look for 'neon' tag */
@@ -122,7 +122,7 @@ png_have_neon(png_structp png_ptr)
                }
 
                state = SkipTag;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case SkipTag:
                /* Skip non-space characters */
diff --git a/contrib/conftest/pngcp.dfa b/contrib/conftest/pngcp.dfa
new file mode 100644 (file)
index 0000000..31c411d
--- /dev/null
@@ -0,0 +1,57 @@
+# pngcp.dfa
+#  Build time configuration of libpng
+#
+# Author: John Bowler
+# Copyright: (c) John Bowler, 2016
+# Usage rights:
+#  To the extent possible under law, the author has waived all copyright and
+#  related or neighboring rights to this work.  This work is published from:
+#  United States.
+#
+# Build libpng with support for pngcp.  This means just png_read_png,
+# png_write_png and small number of configuration settings.
+#
+everything = off
+
+# This option is specific to this configuration; it adds a #define to the
+# generated pnglibconf.h which turns on the (not portable) timing option for
+# pngcp.  Note that any option is automatically preceded by PNG_; there is no
+# way round this and this is deliberate.
+option PNGCP_TIMING
+
+# Because of the everything off above the option must also be turned on.  This
+# may not be done in one step because it is safer and avoids mis-spelled options
+# in user .dfa files to error out if an unrecognized option is turned on.
+option PNGCP_TIMING on
+
+# Options to turn on png_read_png and png_write_png:
+option INFO_IMAGE on
+option SEQUENTIAL_READ on
+option EASY_ACCESS on
+option WRITE on
+option WRITE_16BIT on
+option WRITE_FILTER on
+
+# pngcp needs this to preserve unknown chunks, switching all these on means that
+# pngcp can work without explicit known chunk reading support
+option UNKNOWN_CHUNKS on
+option SET_UNKNOWN_CHUNKS on
+option HANDLE_AS_UNKNOWN on
+option SAVE_UNKNOWN_CHUNKS on
+option WRITE_UNKNOWN_CHUNKS on
+
+# pngcp needs this to handle palette files with invalid indices:
+option CHECK_FOR_INVALID_INDEX on
+option GET_PALETTE_MAX on
+
+# Pre-libpng 1.7 pngcp has to stash text chunks manually, post 1.7 without this
+# text chunks should be handled as unknown ok.
+option TEXT on
+
+# this is used to turn off limits:
+option USER_LIMITS on
+option SET_USER_LIMITS on
+
+# these are just required for specific customizations
+option WRITE_CUSTOMIZE_ZTXT_COMPRESSION on
+option WRITE_CUSTOMIZE_COMPRESSION on
index 0525c9d..48dab4f 100644 (file)
@@ -21,4 +21,4 @@ ORIGINAL AUTHORS
     of the people below claim any rights with regard to the contents of this
     directory.
 
-    John Bowler <jbowler@acm.org>
+    John Bowler <jbowler at acm.org>
index 603037e..00056ab 100644 (file)
@@ -10,7 +10,7 @@
  * without processing the image.  Notice that some header information may occur
  * after the image data. Textual data and comments are an example; the approach
  * in this file won't work reliably for such data because it only looks for the
- * information in the section of the file that preceeds the image data.
+ * information in the section of the file that precedes the image data.
  *
  * Compile and link against libpng and zlib, plus anything else required on the
  * system you use.
index f762379..9185d51 100644 (file)
@@ -42,7 +42,7 @@ component(png_const_bytep row, png_uint_32 x, unsigned int c,
    png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels);
    png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c);
 
-   row = (png_const_bytep)(((PNG_CONST png_byte (*)[8])row) + bit_offset_hi);
+   row = (png_const_bytep)(((const png_byte (*)[8])row) + bit_offset_hi);
    row += bit_offset_lo >> 3;
    bit_offset_lo &= 0x07;
 
@@ -73,7 +73,7 @@ static void
 print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
    png_uint_32 x)
 {
-   PNG_CONST unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
+   unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
 
    switch (png_get_color_type(png_ptr, info_ptr))
    {
@@ -87,7 +87,7 @@ print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row,
        */
       case PNG_COLOR_TYPE_PALETTE:
          {
-            PNG_CONST int index = component(row, x, 0, bit_depth, 1);
+            int index = component(row, x, 0, bit_depth, 1);
             png_colorp palette = NULL;
             int num_palette = 0;
 
index 4acf6b3..904b972 100644 (file)
@@ -1,10 +1,12 @@
 /*- pngtopng
  *
- * COPYRIGHT: Written by John Cunningham Bowler, 2011.
+ * COPYRIGHT: Written by John Cunningham Bowler, 2011, 2017.
  * To the extent possible under law, the author has waived all copyright and
  * related or neighboring rights to this work.  This work is published from:
  * United States.
  *
+ * Last changed in libpng 1.6.29 [March 16, 2017]
+ *
  * Read a PNG and write it out in a fixed format, using the 'simplified API'
  * that was introduced in libpng-1.6.0.
  *
@@ -59,26 +61,27 @@ int main(int argc, const char **argv)
                else
                   fprintf(stderr, "pngtopng: write %s: %s\n", argv[2],
                       image.message);
-
-               free(buffer);
             }
 
             else
-            {
                fprintf(stderr, "pngtopng: read %s: %s\n", argv[1],
                    image.message);
 
-               /* This is the only place where a 'free' is required; libpng does
-                * the cleanup on error and success, but in this case we couldn't
-                * complete the read because of running out of memory.
-                */
-               png_image_free(&image);
-            }
+            free(buffer);
          }
 
          else
+         {
             fprintf(stderr, "pngtopng: out of memory: %lu bytes\n",
                (unsigned long)PNG_IMAGE_SIZE(image));
+
+            /* This is the only place where a 'free' is required; libpng does
+             * the cleanup on error and success, but in this case we couldn't
+             * complete the read because of running out of memory and so libpng
+             * has not got to the point where it can do cleanup.
+             */
+            png_image_free(&image);
+         }
       }
 
       else
index 7b1f6a3..90e28f7 100644 (file)
@@ -15,7 +15,7 @@ of PBMPLUS/NetPBM) and converts them to PNG.
 
 The source code for all three demo programs currently compiles under
 Unix, OpenVMS, and 32-bit Windows.  (Special thanks to Martin Zinser,
-zinser@decus.de, for making the necessary changes for OpenVMS and for
+zinser at decus.de, for making the necessary changes for OpenVMS and for
 providing an appropriate build script.)  Build instructions can be found
 below.
 
@@ -55,7 +55,7 @@ mation and links to the latest version of the source code, and Chapters
 13-15 of the book for detailed discussion of the three programs.
 
 Greg Roelofs
-http://pobox.com/~newt/greg_contact.html
+https://pobox.com/~newt/greg_contact.html
 16 March 2008
 
 
@@ -63,7 +63,7 @@ BUILD INSTRUCTIONS
 
  - Prerequisites (in order of compilation):
 
-      - zlib            http://zlib.net/
+      - zlib            https://zlib.net/
       - libpng          http://www.libpng.org/pub/png/libpng.html
       - pngbook         http://www.libpng.org/pub/png/book/sources.html
 
index 9167403..fad9b53 100644 (file)
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2007,2017 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -264,6 +264,12 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
     *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
     *pChannels = (int)png_get_channels(png_ptr, info_ptr);
 
+    /* Guard against integer overflow */
+    if (height > ((size_t)(-1))/rowbytes) {
+        fprintf(stderr, "readpng:  image_data buffer would be too large\n",
+        return NULL;
+    }
+
     if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
         return NULL;
index a9e7ba5..610b3cd 100644 (file)
@@ -54,7 +54,8 @@
   ---------------------------------------------------------------------------
 
    Changelog:
-     %RDATE% - Check return value of png_get_bKGD() (Glenn R-P)
+     2015-11-12 - Check return value of png_get_bKGD() (Glenn R-P)
+     2017-04-22 - Guard against integer overflow (Glenn R-P)
 
   ---------------------------------------------------------------------------*/
 
@@ -145,7 +146,7 @@ int readpng2_init(mainprog_info *mainprog_ptr)
         /* These byte strings were copied from png.h.  If a future version
          * of readpng2.c recognizes more chunks, add them to this list.
          */
-        static PNG_CONST png_byte chunks_to_process[] = {
+        static const png_byte chunks_to_process[] = {
             98,  75,  71,  68, '\0',  /* bKGD */
            103,  65,  77,  65, '\0',  /* gAMA */
            115,  82,  71,  66, '\0',  /* sRGB */
index 7fefc39..52e7027 100644 (file)
@@ -9,7 +9,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2007,2017 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -154,12 +154,17 @@ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
     *pRowbytes = rowbytes = channels*width;
     *pChannels = channels;
 
-    if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
+    Trace((stderr, "readpng_get_image:  rowbytes = %ld, height = %ld\n", rowbytes, height));
+
+    /* Guard against integer overflow */
+    if (height > ((size_t)(-1))/rowbytes) {
+        fprintf(stderr, PROGNAME ":  image_data buffer would be too large\n",
         return NULL;
     }
 
-    Trace((stderr, "readpng_get_image:  rowbytes = %ld, height = %ld\n", rowbytes, height));
-
+    if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
+        return NULL;
+    }
 
     /* now we can go ahead and just read the whole image */
 
index f53ddc8..1a6f876 100644 (file)
     - 1.10:  enabled "message window"/console (thanks to David Geldreich)
     - 2.00:  dual-licensed (added GNU GPL)
     - 2.01:  fixed improper display of usage screen on PNG error(s)
+    - 2.02:  check for integer overflow (Glenn R-P)
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2008, 2017 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -182,7 +183,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
 #ifndef __CYGWIN__
     /* First reenable console output, which normally goes to the bit bucket
      * for windowed apps.  Closing the console window will terminate the
-     * app.  Thanks to David.Geldreich@realviz.com for supplying the magical
+     * app.  Thanks to David.Geldreich at realviz.com for supplying the magical
      * incantation. */
 
     AllocConsole();
@@ -496,6 +497,12 @@ static int rpng_win_create_window(HINSTANCE hInst, int showmode)
 
     wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2;
 
+    /* Guard against integer overflow */
+    if (image_height > ((size_t)(-1))/wimage_rowbytes) {
+        fprintf(stderr, PROGNAME ":  image_data buffer would be too large\n");
+        return 4;   /* fail */
+    }
+
     if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
                               wimage_rowbytes*image_height)))
     {
index ddd7c58..92effaa 100644 (file)
     - 2.01:  fixed improper display of usage screen on PNG error(s)
     - 2.02:  Added "void(argc);" statement to quiet pedantic compiler warnings
              about unused variable (GR-P)
+    - 2.03:  check for integer overflow (Glenn R-P)
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2008, 2017 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
index a7b9dfa..ed6b526 100644 (file)
     - 2.02:  fixed improper display of usage screen on PNG error(s); fixed
               unexpected-EOF and file-read-error cases
     - 2.03:  removed runtime MMX-enabling/disabling and obsolete -mmx* options
-    - 2.04:
-             (GR-P)
+    - 2.04:  check for integer overflow (Glenn R-P)
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2008 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2008, 2017 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -301,7 +300,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
 #ifndef __CYGWIN__
     /* Next reenable console output, which normally goes to the bit bucket
      * for windowed apps.  Closing the console window will terminate the
-     * app.  Thanks to David.Geldreich@realviz.com for supplying the magical
+     * app.  Thanks to David.Geldreich at realviz.com for supplying the magical
      * incantation. */
 
     AllocConsole();
@@ -650,6 +649,13 @@ static void rpng2_win_init()
     Trace((stderr, "  width  = %ld\n", rpng2_info.width))
     Trace((stderr, "  height = %ld\n", rpng2_info.height))
 
+    /* Guard against integer overflow */
+    if (rpng2_info.height > ((size_t)(-1))/rowbytes) {
+        fprintf(stderr, PROGNAME ":  image_data buffer would be too large\n",
+        readpng2_cleanup(&rpng2_info);
+        return;
+    }
+
     rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
     if (!rpng2_info.image_data) {
         readpng2_cleanup(&rpng2_info);
index 0c8ddeb..af944c0 100644 (file)
     - 2.04:  Added "void(foo);" statements to quiet pedantic compiler warnings
              about unused variables (GR-P)
     - 2.05:  Use nanosleep() instead of usleep(), which is deprecated (GR-P).
+    - 2.06:  check for integer overflow (Glenn R-P)
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2010, 2014-2015 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2010, 2014-2015, 2017 Greg Roelofs.  All rights
+      reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -780,6 +782,13 @@ static void rpng2_x_init(void)
     Trace((stderr, "  width  = %ld\n", rpng2_info.width))
     Trace((stderr, "  height = %ld\n", rpng2_info.height))
 
+    /* Guard against integer overflow */
+    if (rpng2_info.height > ((size_t)(-1))/rpng2_info.rowbytes) {
+        fprintf(stderr, PROGNAME ":  image_data buffer would be too large\n");
+        readpng2_cleanup(&rpng2_info);
+        return;
+    }
+
     rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height);
     if (!rpng2_info.image_data) {
         readpng2_cleanup(&rpng2_info);
index a06e352..a8f367f 100644 (file)
@@ -29,6 +29,7 @@
     - 1.04:  fixed DOS/OS2/Win32 detection, including partial Cygwin fix
               (see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff)
     - 2.00:  dual-licensed (added GNU GPL)
+    - 2.01:  check for integer overflow (Glenn R-P)
 
         [REPORTED BUG (win32 only):  "contrib/gregbook/wpng.c - cmd line
          dose not work!  In order to do something useful I needed to redirect
@@ -38,7 +39,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2007, 2017 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -702,7 +703,18 @@ int main(int argc, char **argv)
     if (wpng_info.interlaced) {
         long i;
         ulg bytes;
-        ulg image_bytes = rowbytes * wpng_info.height;   /* overflow? */
+        ulg image_bytes;
+
+        /* Guard against integer overflow */
+        if (wpng_info_height > ((size_t)(-1)/rowbytes ||
+            wpng_info_height > ((ulg)(-1)/rowbytes) {
+            fprintf(stderr, PROGNAME ":  image_data buffer too large\n");
+            writepng_cleanup(&wpng_info);
+            wpng_cleanup();
+            exit(5);
+        }
+
+        image_bytes = rowbytes * wpng_info.height;
 
         wpng_info.image_data = (uch *)malloc(image_bytes);
         wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *));
index c5c9534..055c743 100644 (file)
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2007, 2017 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
index 9dff048..312062b 100644 (file)
@@ -661,7 +661,7 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
       {
          case 1:
             {
-               const png_uint_32 luma = colors[1];
+               png_uint_32 luma = colors[1];
                png_uint_32 x;
 
                for (x=0; x<=size_max; ++x)
@@ -672,8 +672,8 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
 
          case 2:
             {
-               const png_uint_32 luma = colors[1];
-               const png_uint_32 alpha = colors[2];
+               png_uint_32 luma = colors[1];
+               png_uint_32 alpha = colors[2];
                png_uint_32 x;
 
                for (x=0; x<size_max; ++x)
@@ -688,9 +688,9 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
 
          case 3:
             {
-               const png_uint_32 red = colors[1];
-               const png_uint_32 green = colors[2];
-               const png_uint_32 blue = colors[3];
+               png_uint_32 red = colors[1];
+               png_uint_32 green = colors[2];
+               png_uint_32 blue = colors[3];
                png_uint_32 x;
 
                for (x=0; x<=size_max; ++x)
@@ -707,10 +707,10 @@ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type,
 
          case 4:
             {
-               const png_uint_32 red = colors[1];
-               const png_uint_32 green = colors[2];
-               const png_uint_32 blue = colors[3];
-               const png_uint_32 alpha = colors[4];
+               png_uint_32 red = colors[1];
+               png_uint_32 green = colors[2];
+               png_uint_32 blue = colors[3];
+               png_uint_32 alpha = colors[4];
                png_uint_32 x;
 
                for (x=0; x<=size_max; ++x)
@@ -812,7 +812,7 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth,
       png_error(png_ptr, "OOM allocating info structure");
 
    {
-      const unsigned int size =
+      unsigned int size =
          image_size_of_type(color_type, bit_depth, colors, small);
       unsigned int ysize;
       png_fixed_point real_gamma = 45455; /* For sRGB */
@@ -824,7 +824,7 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth,
        */
       if (small)
       {
-         const unsigned int pixel_depth =
+         unsigned int pixel_depth =
             pixel_depth_of_type(color_type, bit_depth);
 
          if (pixel_depth <= 8U)
@@ -950,7 +950,7 @@ write_png(const char **name, FILE *fp, int color_type, int bit_depth,
             int passes = 1;
 #        endif /* !WRITE_INTERLACING */
          int pass;
-         png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+         size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
          row = malloc(rowbytes);
 
@@ -1094,7 +1094,7 @@ load_file(png_const_charp name, png_bytepp result)
    return 0;
 }
 
-static png_size_t
+static size_t
 load_fake(png_charp param, png_bytepp profile)
 {
    char *endptr = NULL;
@@ -1164,7 +1164,7 @@ insert_iCCP(png_structp png_ptr, png_infop info_ptr, int nparams,
    {
       case '<':
          {
-            png_size_t filelen = load_file(params[1]+1, &profile);
+            size_t filelen = load_file(params[1]+1, &profile);
             if (filelen > 0xfffffffc) /* Maximum profile length */
             {
                fprintf(stderr, "%s: file too long (%lu) for an ICC profile\n",
@@ -1179,7 +1179,7 @@ insert_iCCP(png_structp png_ptr, png_infop info_ptr, int nparams,
       case '0': case '1': case '2': case '3': case '4':
       case '5': case '6': case '7': case '8': case '9':
          {
-            png_size_t fake_len = load_fake(params[1], &profile);
+            size_t fake_len = load_fake(params[1], &profile);
 
             if (fake_len > 0) /* else a simple parameter */
             {
@@ -1274,7 +1274,7 @@ set_text(png_structp png_ptr, png_infop info_ptr, png_textp text,
       case '5': case '6': case '7': case '8': case '9':
          {
             png_bytep data = NULL;
-            png_size_t fake_len = load_fake(param, &data);
+            size_t fake_len = load_fake(param, &data);
 
             if (fake_len > 0) /* else a simple parameter */
             {
@@ -1378,10 +1378,10 @@ static void
 insert_sBIT(png_structp png_ptr, png_infop info_ptr, int nparams,
       png_charpp params)
 {
-   const int ct = png_get_color_type(png_ptr, info_ptr);
-   const int c = (ct & PNG_COLOR_MASK_COLOR ? 3 : 1) +
+   int ct = png_get_color_type(png_ptr, info_ptr);
+   int c = (ct & PNG_COLOR_MASK_COLOR ? 3 : 1) +
       (ct & PNG_COLOR_MASK_ALPHA ? 1 : 0);
-   const unsigned int maxval =
+   unsigned int maxval =
       ct & PNG_COLOR_MASK_PALETTE ? 8U : png_get_bit_depth(png_ptr, info_ptr);
    png_color_8 sBIT;
 
@@ -1856,7 +1856,7 @@ main(int argc, char **argv)
 
    /* Check the colors */
    {
-      const unsigned int lim = (color_type == PNG_COLOR_TYPE_PALETTE ? 255U :
+      unsigned int lim = (color_type == PNG_COLOR_TYPE_PALETTE ? 255U :
          (1U<<bit_depth)-1);
       unsigned int i;
 
index 442b2f4..f130c04 100644 (file)
@@ -1,8 +1,8 @@
 /* pngimage.c
  *
- * Copyright (c) 2015 John Cunningham Bowler
+ * Copyright (c) 2015,2016 John Cunningham Bowler
  *
- * Last changed in libpng 1.6.20 [December 3, 2015]
+ * Last changed in libpng 1.6.24 [August 4, 2016]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
 #  include <setjmp.h> /* because png.h did *not* include this */
 #endif
 
-#if defined(PNG_INFO_IMAGE_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)\
-    && (defined(PNG_READ_PNG_SUPPORTED) || PNG_LIBPNG_VER < 10700)
+/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
+ * a skipped test, in earlier versions we need to succeed on a skipped test, so:
+ */
+#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
+#  define SKIP 77
+#else
+#  define SKIP 0
+#endif
+
+#if PNG_LIBPNG_VER < 10700
+   /* READ_PNG and WRITE_PNG were not defined, so: */
+#  ifdef PNG_INFO_IMAGE_SUPPORTED
+#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#        define PNG_READ_PNG_SUPPORTED
+#     endif /* SEQUENTIAL_READ */
+#     ifdef PNG_WRITE_SUPPORTED
+#        define PNG_WRITE_PNG_SUPPORTED
+#     endif /* WRITE */
+#  endif /* INFO_IMAGE */
+#endif /* pre 1.7.0 */
+
+#ifdef PNG_READ_PNG_SUPPORTED
 /* If a transform is valid on both read and write this implies that if the
  * transform is applied to read it must also be applied on write to produce
  * meaningful data.  This is because these transforms when performed on read
@@ -386,7 +406,7 @@ buffer_destroy(struct buffer *buffer)
    buffer_destroy_list(list);
 }
 
-#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_PNG_SUPPORTED
 static void
 buffer_start_write(struct buffer *buffer)
 {
@@ -531,7 +551,7 @@ struct display
    png_structp    original_pp;       /* used on the original read */
    png_infop      original_ip;       /* set by the original read */
 
-   png_size_t     original_rowbytes; /* of the original rows: */
+   size_t         original_rowbytes; /* of the original rows: */
    png_bytepp     original_rows;     /* from the original read */
 
    /* Original chunks valid */
@@ -556,7 +576,7 @@ struct display
    png_structp    read_pp;
    png_infop      read_ip;
 
-#  ifdef PNG_WRITE_SUPPORTED
+#  ifdef PNG_WRITE_PNG_SUPPORTED
       /* Used to write a new image (the original info_ptr is used) */
       png_structp   write_pp;
       struct buffer written_file;   /* where the file gets written */
@@ -583,7 +603,7 @@ display_init(struct display *dp)
    dp->read_ip = NULL;
    buffer_init(&dp->original_file);
 
-#  ifdef PNG_WRITE_SUPPORTED
+#  ifdef PNG_WRITE_PNG_SUPPORTED
       dp->write_pp = NULL;
       buffer_init(&dp->written_file);
 #  endif
@@ -596,7 +616,7 @@ display_clean_read(struct display *dp)
       png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL);
 }
 
-#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_PNG_SUPPORTED
 static void
 display_clean_write(struct display *dp)
 {
@@ -608,7 +628,7 @@ display_clean_write(struct display *dp)
 static void
 display_clean(struct display *dp)
 {
-#  ifdef PNG_WRITE_SUPPORTED
+#  ifdef PNG_WRITE_PNG_SUPPORTED
       display_clean_write(dp);
 #  endif
    display_clean_read(dp);
@@ -626,7 +646,7 @@ static void
 display_destroy(struct display *dp)
 {
     /* Release any memory held in the display. */
-#  ifdef PNG_WRITE_SUPPORTED
+#  ifdef PNG_WRITE_PNG_SUPPORTED
       buffer_destroy(&dp->written_file);
 #  endif
 
@@ -787,7 +807,7 @@ display_cache_file(struct display *dp, const char *filename)
 
 static void
 buffer_read(struct display *dp, struct buffer *bp, png_bytep data,
-   png_size_t size)
+   size_t size)
 {
    struct buffer_list *last = bp->current;
    size_t read_count = bp->read_count;
@@ -835,7 +855,7 @@ buffer_read(struct display *dp, struct buffer *bp, png_bytep data,
 }
 
 static void PNGCBAPI
-read_function(png_structp pp, png_bytep data, png_size_t size)
+read_function(png_structp pp, png_bytep data, size_t size)
 {
    buffer_read(get_dp(pp), get_buffer(pp), data, size);
 }
@@ -907,7 +927,7 @@ update_display(struct display *dp)
    png_structp pp;
    png_infop   ip;
 
-   /* Now perform the initial read with a 0 tranform. */
+   /* Now perform the initial read with a 0 transform. */
    read_png(dp, &dp->original_file, "original read", 0/*no transform*/);
 
    /* Move the result to the 'original' fields */
@@ -1073,6 +1093,7 @@ compare_read(struct display *dp, int applied_transforms)
       }
 
       else
+#     ifdef PNG_sBIT_SUPPORTED
       {
          unsigned long y;
          int bpp;   /* bits-per-pixel then bytes-per-pixel */
@@ -1234,15 +1255,19 @@ compare_read(struct display *dp, int applied_transforms)
             }
          } /* for y */
       }
+#     else /* !sBIT */
+         display_log(dp, INTERNAL_ERROR,
+               "active shift transform but no sBIT support");
+#     endif /* !sBIT */
    }
 
    return 1; /* compare succeeded */
 }
 
-#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_PNG_SUPPORTED
 static void
 buffer_write(struct display *dp, struct buffer *buffer, png_bytep data,
-   png_size_t size)
+   size_t size)
    /* Generic write function used both from the write callback provided to
     * libpng and from the generic read code.
     */
@@ -1286,7 +1311,7 @@ buffer_write(struct display *dp, struct buffer *buffer, png_bytep data,
 }
 
 static void PNGCBAPI
-write_function(png_structp pp, png_bytep data, png_size_t size)
+write_function(png_structp pp, png_bytep data, size_t size)
 {
    buffer_write(get_dp(pp), get_buffer(pp), data, size);
 }
@@ -1338,7 +1363,7 @@ write_png(struct display *dp, png_infop ip, int transforms)
     */
    display_clean_write(dp);
 }
-#endif /* WRITE_SUPPORTED */
+#endif /* WRITE_PNG */
 
 static int
 skip_transform(struct display *dp, int tr)
@@ -1400,7 +1425,7 @@ test_one_file(struct display *dp, const char *filename)
          return; /* no point testing more */
    }
 
-#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_PNG_SUPPORTED
    /* Second test: write the original PNG data out to a new file (to test the
     * write side) then read the result back in and make sure that it hasn't
     * changed.
@@ -1421,7 +1446,7 @@ test_one_file(struct display *dp, const char *filename)
        * unsigned, because some transforms are negative on a 16-bit system.
        */
       unsigned int active = dp->active_transforms;
-      const int exhaustive = (dp->options & EXHAUSTIVE) != 0;
+      int exhaustive = (dp->options & EXHAUSTIVE) != 0;
       unsigned int current = first_transform(active);
       unsigned int bad_transforms = 0;
       unsigned int bad_combo = ~0U;    /* bitwise AND of failing transforms */
@@ -1441,7 +1466,7 @@ test_one_file(struct display *dp, const char *filename)
           * out and read it back in again (without the reversible transforms)
           * we should get back to the place where we started.
           */
-#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_PNG_SUPPORTED
          if ((current & write_transforms) == current)
          {
             /* All transforms reversible: write the PNG with the transformations
@@ -1547,7 +1572,7 @@ do_test(struct display *dp, const char *file)
 }
 
 int
-main(const int argc, const char * const * const argv)
+main(int argc, char **argv)
 {
    /* For each file on the command line test it with a range of transforms */
    int option_end, ilog = 0;
@@ -1649,7 +1674,7 @@ main(const int argc, const char * const * const argv)
          /* Here on any return, including failures, except user/internal issues
           */
          {
-            const int pass = (d.options & STRICT) ?
+            int pass = (d.options & STRICT) ?
                RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
 
             if (!pass)
@@ -1677,11 +1702,11 @@ main(const int argc, const char * const * const argv)
       return errors != 0;
    }
 }
-#else /* !INFO_IMAGE || !SEQUENTIAL_READ || !READ_PNG*/
+#else /* !READ_PNG */
 int
 main(void)
 {
    fprintf(stderr, "pngimage: no support for png_read/write_image\n");
-   return 77;
+   return SKIP;
 }
 #endif
index 0febb63..a368bf0 100644 (file)
@@ -1,9 +1,8 @@
 /*-
  * pngstest.c
  *
- * Copyright (c) 2013-2015 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.19 [November 12, 2015]
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Copyright (c) 2013-2017 John Cunningham Bowler
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
 #  include "../../png.h"
 #endif
 
+/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
+ * a skipped test, in earlier versions we need to succeed on a skipped test, so:
+ */
+#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
+#  define SKIP 77
+#else
+#  define SKIP 0
+#endif
+
 #ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */
 #include "../tools/sRGB.h"
 
@@ -99,10 +107,18 @@ make_random_bytes(png_uint_32* seed, void* pv, size_t size)
    seed[1] = u1;
 }
 
+static png_uint_32 color_seed[2];
+
+static void
+reseed(void)
+{
+   color_seed[0] = 0x12345678U;
+   color_seed[1] = 0x9abcdefU;
+}
+
 static void
 random_color(png_colorp color)
 {
-   static png_uint_32 color_seed[2] = { 0x12345678, 0x9abcdef };
    make_random_bytes(color_seed, color, sizeof *color);
 }
 
@@ -307,7 +323,7 @@ compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms)
 }
 #endif /* unused */
 
-#define READ_FILE 1      /* else memory */
+#define USE_FILE 1       /* else memory */
 #define USE_STDIO 2      /* else use file name */
 #define STRICT 4         /* fail on warnings too */
 #define VERBOSE 8
@@ -316,16 +332,19 @@ compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms)
 #define ACCUMULATE 64
 #define FAST_WRITE 128
 #define sRGB_16BIT 256
+#define NO_RESEED  512   /* do not reseed on each new file */
+#define GBG_ERROR 1024   /* do not ignore the gamma+background_rgb_to_gray
+                          * libpng warning. */
 
 static void
 print_opts(png_uint_32 opts)
 {
-   if (opts & READ_FILE)
+   if (opts & USE_FILE)
       printf(" --file");
    if (opts & USE_STDIO)
       printf(" --stdio");
-   if (opts & STRICT)
-      printf(" --strict");
+   if (!(opts & STRICT))
+      printf(" --nostrict");
    if (opts & VERBOSE)
       printf(" --verbose");
    if (opts & KEEP_TMPFILES)
@@ -338,6 +357,12 @@ print_opts(png_uint_32 opts)
       printf(" --slow");
    if (opts & sRGB_16BIT)
       printf(" --sRGB-16bit");
+   if (opts & NO_RESEED)
+      printf(" --noreseed");
+#if PNG_LIBPNG_VER < 10700 /* else on by default */
+   if (opts & GBG_ERROR)
+      printf(" --fault-gbg-warning");
+#endif
 }
 
 #define FORMAT_NO_CHANGE 0x80000000 /* additional flag */
@@ -347,7 +372,7 @@ print_opts(png_uint_32 opts)
  */
 #define FORMAT_COUNT 64
 #define FORMAT_MASK 0x3f
-static PNG_CONST char * PNG_CONST format_names[FORMAT_COUNT] =
+static const char * const format_names[FORMAT_COUNT] =
 {
    "sRGB-gray",
    "sRGB-gray+alpha",
@@ -553,11 +578,11 @@ typedef struct
    int         stride_extra;
    FILE       *input_file;
    png_voidp   input_memory;
-   png_size_t  input_memory_size;
+   size_t      input_memory_size;
    png_bytep   buffer;
    ptrdiff_t   stride;
-   png_size_t  bufsize;
-   png_size_t  allocsize;
+   size_t      bufsize;
+   size_t      allocsize;
    char        tmpfile_name[32];
    png_uint_16 colormap[256*4];
 }
@@ -640,7 +665,7 @@ static void initimage(Image *image, png_uint_32 opts, const char *file_name,
 static void
 allocbuffer(Image *image)
 {
-   png_size_t size = PNG_IMAGE_BUFFER_SIZE(image->image, image->stride);
+   size_t size = PNG_IMAGE_BUFFER_SIZE(image->image, image->stride);
 
    if (size+32 > image->bufsize)
    {
@@ -741,8 +766,15 @@ checkopaque(Image *image)
       return logerror(image, image->file_name, ": opaque not NULL", "");
    }
 
-   else if (image->image.warning_or_error != 0 && (image->opts & STRICT) != 0)
-      return logerror(image, image->file_name, " --strict", "");
+   /* Separate out the gamma+background_rgb_to_gray warning because it may
+    * produce opaque component errors:
+    */
+   else if (image->image.warning_or_error != 0 &&
+            (strcmp(image->image.message,
+               "libpng does not support gamma+background+rgb_to_gray") == 0 ?
+                  (image->opts & GBG_ERROR) != 0 : (image->opts & STRICT) != 0))
+      return logerror(image, image->file_name, (image->opts & GBG_ERROR) != 0 ?
+                      " --fault-gbg-warning" : " --strict", "");
 
    else
       return 1;
@@ -1110,7 +1142,7 @@ get_pixel(png_uint_32 format))(Pixel *p, png_const_voidp pb)
    }
 }
 
-/* Convertion between pixel formats.  The code above effectively eliminates the
+/* Conversion between pixel formats.  The code above effectively eliminates the
  * component ordering changes leaving three basic changes:
  *
  * 1) Remove an alpha channel by pre-multiplication or compositing on a
@@ -2004,7 +2036,7 @@ typedef struct
    /* Precalculated values: */
    int          in_opaque;   /* Value of input alpha that is opaque */
    int          is_palette;  /* Sample values come from the palette */
-   int          accumulate;  /* Accumlate component errors (don't log) */
+   int          accumulate;  /* Accumulate component errors (don't log) */
    int          output_8bit; /* Output is 8-bit (else 16-bit) */
 
    void (*in_gp)(Pixel*, png_const_voidp);
@@ -2314,8 +2346,8 @@ static int
 logpixel(const Transform *transform, png_uint_32 x, png_uint_32 y,
    const Pixel *in, const Pixel *calc, const Pixel *out, const char *reason)
 {
-   const png_uint_32 in_format = transform->in_image->image.format;
-   const png_uint_32 out_format = transform->out_image->image.format;
+   png_uint_32 in_format = transform->in_image->image.format;
+   png_uint_32 out_format = transform->out_image->image.format;
 
    png_uint_32 back_format = out_format & ~PNG_FORMAT_FLAG_ALPHA;
    const char *via_linear = "";
@@ -2570,17 +2602,17 @@ compare_two_images(Image *a, Image *b, int via_linear,
    ptrdiff_t strideb = b->stride;
    png_const_bytep rowa = a->buffer+16;
    png_const_bytep rowb = b->buffer+16;
-   const png_uint_32 width = a->image.width;
-   const png_uint_32 height = a->image.height;
-   const png_uint_32 formata = a->image.format;
-   const png_uint_32 formatb = b->image.format;
-   const unsigned int a_sample = PNG_IMAGE_SAMPLE_SIZE(formata);
-   const unsigned int b_sample = PNG_IMAGE_SAMPLE_SIZE(formatb);
+   png_uint_32 width = a->image.width;
+   png_uint_32 height = a->image.height;
+   png_uint_32 formata = a->image.format;
+   png_uint_32 formatb = b->image.format;
+   unsigned int a_sample = PNG_IMAGE_SAMPLE_SIZE(formata);
+   unsigned int b_sample = PNG_IMAGE_SAMPLE_SIZE(formatb);
    int alpha_added, alpha_removed;
    int bchannels;
-   int btoa[4];
    png_uint_32 y;
    Transform tr;
+   int btoa[4]={0,0,0,0};
 
    /* This should never happen: */
    if (width != b->image.width || height != b->image.height)
@@ -2694,7 +2726,7 @@ compare_two_images(Image *a, Image *b, int via_linear,
                result = 0;
          }
 
-         /* If reqested copy the error values back from the Transform. */
+         /* If requested, copy the error values back from the Transform. */
          if (a->opts & ACCUMULATE)
          {
             tr.error_ptr[0] = tr.error[0];
@@ -2713,22 +2745,27 @@ compare_two_images(Image *a, Image *b, int via_linear,
        */
       else if ((a->opts & ACCUMULATE) == 0)
       {
+#        ifdef __GNUC__
+#           define BYTE_CHARS 20 /* 2^32: GCC sprintf warning */
+#        else
+#           define BYTE_CHARS 3 /* 2^8: real maximum value */
+#        endif
          /* Check the original image first,
           * TODO: deal with input images with bad pixel values?
           */
          if (amax >= a->image.colormap_entries)
          {
-            char pindex[9];
-            sprintf(pindex, "%d[%lu]", amax,
-               (unsigned long)a->image.colormap_entries);
+            char pindex[3+2*BYTE_CHARS];
+            sprintf(pindex, "%d[%u]", amax,
+               (png_byte)/*SAFE*/a->image.colormap_entries);
             return logerror(a, a->file_name, ": bad pixel index: ", pindex);
          }
 
          else if (bmax >= b->image.colormap_entries)
          {
-            char pindex[9];
-            sprintf(pindex, "%d[%lu]", bmax,
-               (unsigned long)b->image.colormap_entries);
+            char pindex[3+2*BYTE_CHARS];
+            sprintf(pindex, "%d[%u]", bmax,
+               (png_byte)/*SAFE*/b->image.colormap_entries);
             return logerror(b, b->file_name, ": bad pixel index: ", pindex);
          }
       }
@@ -2753,8 +2790,7 @@ compare_two_images(Image *a, Image *b, int via_linear,
       (formata & (formatb ^ PNG_FORMAT_FLAG_COLOR) & PNG_FORMAT_FLAG_COLOR)))
    {
       /* Was an alpha channel changed? */
-      const png_uint_32 alpha_changed = (formata ^ formatb) &
-         PNG_FORMAT_FLAG_ALPHA;
+      png_uint_32 alpha_changed = (formata ^ formatb) & PNG_FORMAT_FLAG_ALPHA;
 
       /* Was an alpha channel removed?  (The third test.)  If so the direct
        * comparison is only possible if the input alpha is opaque.
@@ -2848,10 +2884,13 @@ compare_two_images(Image *a, Image *b, int via_linear,
                {
                   case 4:
                      if (pua[btoa[3]] != pub[3]) break;
+                     /* FALLTHROUGH */
                   case 3:
                      if (pua[btoa[2]] != pub[2]) break;
+                     /* FALLTHROUGH */
                   case 2:
                      if (pua[btoa[1]] != pub[1]) break;
+                     /* FALLTHROUGH */
                   case 1:
                      if (pua[btoa[0]] != pub[0]) break;
                      if (alpha_added != 4 && pub[alpha_added] != 65535) break;
@@ -2867,10 +2906,13 @@ compare_two_images(Image *a, Image *b, int via_linear,
                {
                   case 4:
                      if (psa[btoa[3]] != psb[3]) break;
+                     /* FALLTHROUGH */
                   case 3:
                      if (psa[btoa[2]] != psb[2]) break;
+                     /* FALLTHROUGH */
                   case 2:
                      if (psa[btoa[1]] != psb[1]) break;
+                     /* FALLTHROUGH */
                   case 1:
                      if (psa[btoa[0]] != psb[0]) break;
                      if (alpha_added != 4 && psb[alpha_added] != 255) break;
@@ -2889,7 +2931,7 @@ compare_two_images(Image *a, Image *b, int via_linear,
       }
    }
 
-   /* If reqested copy the error values back from the Transform. */
+   /* If requested, copy the error values back from the Transform. */
    if (a->opts & ACCUMULATE)
    {
       tr.error_ptr[0] = tr.error[0];
@@ -3008,14 +3050,14 @@ read_file(Image *image, png_uint_32 format, png_const_colorp background)
 static int
 read_one_file(Image *image)
 {
-   if (!(image->opts & READ_FILE) || (image->opts & USE_STDIO))
+   if (!(image->opts & USE_FILE) || (image->opts & USE_STDIO))
    {
       /* memory or stdio. */
       FILE *f = fopen(image->file_name, "rb");
 
       if (f != NULL)
       {
-         if (image->opts & READ_FILE)
+         if (image->opts & USE_FILE)
             image->input_file = f;
 
          else /* memory */
@@ -3096,7 +3138,8 @@ write_one_file(Image *output, Image *image, int convert_to_8bit)
 
    if (image->opts & USE_STDIO)
    {
-#ifndef PNG_USE_MKSTEMP
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+#ifndef __COVERITY__
       FILE *f = tmpfile();
 #else
       /* Experimental. Coverity says tmpfile() is insecure because it
@@ -3158,10 +3201,14 @@ write_one_file(Image *output, Image *image, int convert_to_8bit)
 
       else
          return logerror(image, "tmpfile", ": open: ", strerror(errno));
+#else /* SIMPLIFIED_WRITE_STDIO */
+      return logerror(image, "tmpfile", ": open: unsupported", "");
+#endif /* SIMPLIFIED_WRITE_STDIO */
    }
 
-   else
+   else if (image->opts & USE_FILE)
    {
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
       static int counter = 0;
       char name[32];
 
@@ -3181,6 +3228,51 @@ write_one_file(Image *output, Image *image, int convert_to_8bit)
 
       else
          return logerror(image, name, ": write failed", "");
+#else /* SIMPLIFIED_WRITE_STDIO */
+      return logerror(image, "stdio", ": open: unsupported", "");
+#endif /* SIMPLIFIED_WRITE_STDIO */
+   }
+
+   else /* use memory */
+   {
+      png_alloc_size_t size;
+
+      if (png_image_write_get_memory_size(image->image, size, convert_to_8bit,
+               image->buffer+16, (png_int_32)image->stride, image->colormap))
+      {
+         /* This is non-fatal but ignoring it was causing serious problems in
+          * the macro to be ignored:
+          */
+         if (size > PNG_IMAGE_PNG_SIZE_MAX(image->image))
+            return logerror(image, "memory", ": PNG_IMAGE_SIZE_MAX wrong", "");
+
+         initimage(output, image->opts, "memory", image->stride_extra);
+         output->input_memory = malloc(size);
+
+         if (output->input_memory != NULL)
+         {
+            output->input_memory_size = size;
+
+            if (png_image_write_to_memory(&image->image, output->input_memory,
+                  &output->input_memory_size, convert_to_8bit, image->buffer+16,
+                  (png_int_32)image->stride, image->colormap))
+            {
+               /* This is also non-fatal but it safes safer to error out anyway:
+                */
+               if (size != output->input_memory_size)
+                  return logerror(image, "memory", ": memory size wrong", "");
+            }
+
+            else
+               return logerror(image, "memory", ": write failed", "");
+         }
+
+         else
+            return logerror(image, "memory", ": out of memory", "");
+      }
+
+      else
+         return logerror(image, "memory", ": get size:", "");
    }
 
    /* 'output' has an initialized temporary image, read this back in and compare
@@ -3356,6 +3448,8 @@ test_one_file(const char *file_name, format_list *formats, png_uint_32 opts,
    int result;
    Image image;
 
+   if (!(opts & NO_RESEED))
+      reseed(); /* ensure that the random numbers don't depend on file order */
    newimage(&image);
    initimage(&image, opts, file_name, stride_extra);
    result = read_one_file(&image);
@@ -3393,7 +3487,7 @@ test_one_file(const char *file_name, format_list *formats, png_uint_32 opts,
 int
 main(int argc, char **argv)
 {
-   png_uint_32 opts = FAST_WRITE;
+   png_uint_32 opts = FAST_WRITE | STRICT;
    format_list formats;
    const char *touch = NULL;
    int log_pass = 0;
@@ -3402,11 +3496,17 @@ main(int argc, char **argv)
    int retval = 0;
    int c;
 
+#if PNG_LIBPNG_VER >= 10700
+      /* This error should not exist in 1.7 or later: */
+      opts |= GBG_ERROR;
+#endif
+
    init_sRGB_to_d();
 #if 0
    init_error_via_linear();
 #endif
    format_init(&formats);
+   reseed(); /* initialize random number seeds */
 
    for (c=1; c<argc; ++c)
    {
@@ -3421,17 +3521,17 @@ main(int argc, char **argv)
       }
       else if (strcmp(arg, "--file") == 0)
 #        ifdef PNG_STDIO_SUPPORTED
-            opts |= READ_FILE;
+            opts |= USE_FILE;
 #        else
-            return 77; /* skipped: no support */
+            return SKIP; /* skipped: no support */
 #        endif
       else if (strcmp(arg, "--memory") == 0)
-         opts &= ~READ_FILE;
+         opts &= ~USE_FILE;
       else if (strcmp(arg, "--stdio") == 0)
 #        ifdef PNG_STDIO_SUPPORTED
             opts |= USE_STDIO;
 #        else
-            return 77; /* skipped: no support */
+            return SKIP; /* skipped: no support */
 #        endif
       else if (strcmp(arg, "--name") == 0)
          opts &= ~USE_STDIO;
@@ -3457,10 +3557,16 @@ main(int argc, char **argv)
          opts &= ~KEEP_GOING;
       else if (strcmp(arg, "--strict") == 0)
          opts |= STRICT;
+      else if (strcmp(arg, "--nostrict") == 0)
+         opts &= ~STRICT;
       else if (strcmp(arg, "--sRGB-16bit") == 0)
          opts |= sRGB_16BIT;
       else if (strcmp(arg, "--linear-16bit") == 0)
          opts &= ~sRGB_16BIT;
+      else if (strcmp(arg, "--noreseed") == 0)
+         opts |= NO_RESEED;
+      else if (strcmp(arg, "--fault-gbg-warning") == 0)
+         opts |= GBG_ERROR;
       else if (strcmp(arg, "--tmpfile") == 0)
       {
          if (c+1 < argc)
@@ -3520,7 +3626,7 @@ main(int argc, char **argv)
 
          if (arg[0] == '-')
          {
-            const int term = (arg[1] == '0' ? 0 : '\n');
+            int term = (arg[1] == '0' ? 0 : '\n');
             unsigned int ich = 0;
 
             /* Loop reading files, use a static buffer to simplify this and just
@@ -3717,6 +3823,6 @@ int main(void)
 {
    fprintf(stderr, "pngstest: no read support in libpng, test skipped\n");
    /* So the test is skipped: */
-   return 77;
+   return SKIP;
 }
 #endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
index 0d52ff8..05bdd83 100644 (file)
@@ -1,8 +1,8 @@
 
 /* pngunknown.c - test the read side unknown chunk handling
  *
- * Last changed in libpng 1.6.10 [March 6, 2014]
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 2015,2017 Glenn Randers-Pehrson
  * Written by John Cunningham Bowler
  *
  * This code is released under the libpng license.
 #  include "../../png.h"
 #endif
 
+/* 1.6.1 added support for the configure test harness, which uses 77 to indicate
+ * a skipped test, in earlier versions we need to succeed on a skipped test, so:
+ */
+#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
+#  define SKIP 77
+#else
+#  define SKIP 0
+#endif
+
+
 /* Since this program tests the ability to change the unknown chunk handling
  * these must be defined:
  */
 #if defined(PNG_SET_UNKNOWN_CHUNKS_SUPPORTED) &&\
+   defined(PNG_STDIO_SUPPORTED) &&\
    defined(PNG_READ_SUPPORTED)
 
 /* One of these must be defined to allow us to find out what happened.  It is
@@ -45,7 +56,7 @@
    defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED)
 
 #if PNG_LIBPNG_VER < 10500
-/* This deliberately lacks the PNG_CONST. */
+/* This deliberately lacks the const. */
 typedef png_byte *png_const_bytep;
 
 /* This is copied from 1.5.1 png.h: */
@@ -74,7 +85,7 @@ typedef png_byte *png_const_bytep;
 #define PNG_WRITE_16BIT_SUPPORTED
 #define PNG_READ_16BIT_SUPPORTED
 
-/* This comes from pnglibconf.h afer 1.5: */
+/* This comes from pnglibconf.h after 1.5: */
 #define PNG_FP_1 100000
 #define PNG_GAMMA_THRESHOLD_FIXED\
    ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
@@ -103,6 +114,7 @@ typedef png_byte *png_const_bytep;
 #define png_PLTE PNG_U32( 80,  76,  84,  69)
 #define png_bKGD PNG_U32( 98,  75,  71,  68)
 #define png_cHRM PNG_U32( 99,  72,  82,  77)
+#define png_eXIf PNG_U32(101,  88,  73, 102) /* registered July 2017 */
 #define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
 #define png_gAMA PNG_U32(103,  65,  77,  65)
 #define png_gIFg PNG_U32(103,  73,  70, 103)
@@ -199,6 +211,13 @@ static struct
          1,
 #     endif
       1,  START, 0 },
+   { "eXIf", PNG_INFO_eXIf, png_eXIf,
+#     ifdef PNG_READ_eXIf_SUPPORTED
+         0,
+#     else
+         1,
+#     endif
+      1,  END, 0 },
    { "gAMA", PNG_INFO_gAMA, png_gAMA,
 #     ifdef PNG_READ_gAMA_SUPPORTED
          0,
@@ -467,7 +486,7 @@ get_valid(display *d, png_infop info_ptr)
       png_textp text;
       png_uint_32 ntext = png_get_text(d->png_ptr, info_ptr, &text, NULL);
 
-      while (ntext-- > 0) switch (text[ntext].compression)
+      while (ntext > 0) switch (text[--ntext].compression)
       {
          case -1:
             flags |= PNG_INFO_tEXt;
@@ -603,7 +622,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT)
                   ++(d->error_count);
                   break;
                }
-               /* FALL THROUGH (safe) */
+               /* FALLTHROUGH */ /* (safe) */
             case PNG_HANDLE_CHUNK_ALWAYS:
                break;
          }
@@ -615,7 +634,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT)
 
    return flags;
 }
-#else
+#else /* SAVE_UNKNOWN_CHUNKS */
 static png_uint_32
 get_unknown(display *d, png_infop info_ptr, int after_IDAT)
    /* Otherwise this will return the cached values set by any user callback */
@@ -634,8 +653,8 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT)
        * a check to ensure the logic is correct.
        */
 #     error No store support and no user chunk support, this will not work
-#  endif
-#endif
+#  endif /* READ_USER_CHUNKS */
+#endif /* SAVE_UNKNOWN_CHUNKS */
 
 static int
 check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/,
@@ -1001,6 +1020,20 @@ perform_one_test(FILE *fp, int argc, const char **argv,
 
    def = check(fp, argc, argv, flags[1], d, set_callback);
 
+   /* If IDAT is being handled as unknown the image read is skipped and all the
+    * IDATs after the first end up in the end info struct, so in this case add
+    * IDAT to the list of unknowns.  (Do this after 'check' above sets the
+    * chunk_info 'keep' fields.)
+    *
+    * Note that the flag setting has to be in the 'known' field to avoid
+    * triggering the consistency check below and the flag must only be set if
+    * there are multiple IDATs, so if the check above did find an unknown IDAT
+    * after IDAT.
+    */
+   if (chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT &&
+       (flags[1][3] & PNG_INFO_IDAT) != 0)
+      flags[0][2] |= PNG_INFO_IDAT;
+
    /* Chunks should either be known or unknown, never both and this should apply
     * whether the chunk is before or after the IDAT (actually, the app can
     * probably change this by swapping the handling after the image, but this
@@ -1065,7 +1098,7 @@ static const char *standard_tests[] =
  "sTER", "sTER=if-safe", 0,
  "IDAT", "default=discard", "IDAT=save", 0,
  "sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save",
-   "sBIT=save", "sRGB=save", 0,
+   "sBIT=save", "sRGB=save", "eXIf=save", 0,
  0/*end*/
 };
 
@@ -1245,7 +1278,7 @@ main(void)
    fprintf(stderr,
       " test ignored: no support to find out about unknown chunks\n");
    /* So the test is skipped: */
-   return 77;
+   return SKIP;
 }
 #endif /* READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS */
 
@@ -1256,6 +1289,6 @@ main(void)
    fprintf(stderr,
       " test ignored: no support to modify unknown chunk handling\n");
    /* So the test is skipped: */
-   return 77;
+   return SKIP;
 }
 #endif /* SET_UNKNOWN_CHUNKS && READ*/
index 55d0945..d800110 100644 (file)
@@ -1,9 +1,8 @@
 
 /* pngvalid.c - validate libpng by constructing then reading png files.
  *
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 2014-2016 Glenn Randers-Pehrson
- * Written by John Cunningham Bowler
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Copyright (c) 2014-2017 John Cunningham Bowler
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -22,6 +21,7 @@
 #define _POSIX_SOURCE 1
 #define _ISOC99_SOURCE 1 /* For floating point */
 #define _GNU_SOURCE 1 /* For the floating point exception extension */
+#define _BSD_SOURCE 1 /* For the floating point exception extension */
 
 #include <signal.h>
 #include <stdio.h>
 /* 1.6.1 added support for the configure test harness, which uses 77 to indicate
  * a skipped test, in earlier versions we need to succeed on a skipped test, so:
  */
-#if PNG_LIBPNG_VER < 10601
-#  define SKIP 0
-#else
+#if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
 #  define SKIP 77
+#else
+#  define SKIP 0
 #endif
 
 /* pngvalid requires write support and one of the fixed or floating point APIs.
@@ -103,7 +103,7 @@ typedef png_byte *png_const_bytep;
 #define PNG_WRITE_16BIT_SUPPORTED
 #define PNG_READ_16BIT_SUPPORTED
 
-/* This comes from pnglibconf.h afer 1.5: */
+/* This comes from pnglibconf.h after 1.5: */
 #define PNG_FP_1 100000
 #define PNG_GAMMA_THRESHOLD_FIXED\
    ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
@@ -131,6 +131,17 @@ typedef png_byte *png_const_bytep;
 #include <string.h> /* For memcpy, memset */
 #include <math.h>   /* For floor */
 
+/* Convenience macros. */
+#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
+#define CHUNK_IHDR CHUNK(73,72,68,82)
+#define CHUNK_PLTE CHUNK(80,76,84,69)
+#define CHUNK_IDAT CHUNK(73,68,65,84)
+#define CHUNK_IEND CHUNK(73,69,78,68)
+#define CHUNK_cHRM CHUNK(99,72,82,77)
+#define CHUNK_gAMA CHUNK(103,65,77,65)
+#define CHUNK_sBIT CHUNK(115,66,73,84)
+#define CHUNK_sRGB CHUNK(115,82,71,66)
+
 /* Unused formal parameter errors are removed using the following macro which is
  * expected to have no bad effects on performance.
  */
@@ -297,48 +308,33 @@ randomize(void *pv, size_t size)
 
 #define R8(this) randomize(&(this), sizeof (this))
 
-static void r16(png_uint_16p p16, size_t count)
+#ifdef PNG_READ_SUPPORTED
+static png_byte
+random_byte(void)
 {
-   size_t i;
-
-   for (i=0; i<count; ++i)
-   {
-      unsigned char b2[2];
-      randomize(b2, sizeof b2);
-      *p16++ = png_get_uint_16(b2);
-   }
+   unsigned char b1[1];
+   randomize(b1, sizeof b1);
+   return b1[0];
 }
+#endif /* READ */
 
-#ifdef __COVERITY__
-#  define R16(this)\
-   r16(&(this), (sizeof (this))/2U/*(sizeof (png_uint_16))*/)
-#else
-#  define R16(this)\
-   r16(&(this), (sizeof (this))/(sizeof (png_uint_16)))
-#endif
+static png_uint_16
+random_u16(void)
+{
+   unsigned char b2[2];
+   randomize(b2, sizeof b2);
+   return png_get_uint_16(b2);
+}
 
 #if defined PNG_READ_RGB_TO_GRAY_SUPPORTED ||\
     defined PNG_READ_FILLER_SUPPORTED
-static void r32(png_uint_32p p32, size_t count)
+static png_uint_32
+random_u32(void)
 {
-   size_t i;
-
-   for (i=0; i<count; ++i)
-   {
-      unsigned char b4[4];
-      randomize(b4, sizeof b4);
-      *p32++ = png_get_uint_32(b4);
-   }
+   unsigned char b4[4];
+   randomize(b4, sizeof b4);
+   return png_get_uint_32(b4);
 }
-
-#ifdef __COVERITY__
-#  define R32(this)\
-   r32(&(this), (sizeof (this))/4U/*(sizeof (png_uint_32))*/)
-#else
-#  define R32(this)\
-   r32(&(this), (sizeof (this))/(sizeof (png_uint_32)))
-#endif
-
 #endif /* READ_FILLER || READ_RGB_TO_GRAY */
 
 #endif /* READ || WRITE_tRNS || WRITE_FILTER */
@@ -348,11 +344,7 @@ static void r32(png_uint_32p p32, size_t count)
 static unsigned int
 random_mod(unsigned int max)
 {
-   png_uint_16 x;
-
-   R16(x);
-
-   return x % max; /* 0 .. max-1 */
+   return random_u16() % max; /* 0 .. max-1 */
 }
 #endif /* READ_TRANSFORMS || WRITE_FILTER */
 
@@ -361,11 +353,7 @@ random_mod(unsigned int max)
 static int
 random_choice(void)
 {
-   unsigned char x;
-
-   R8(x);
-
-   return x & 1;
+   return random_byte() & 1;
 }
 #endif /* READ_RGB_TO_GRAY || READ_FILLER */
 
@@ -721,8 +709,10 @@ typedef struct png_store_file
 {
    struct png_store_file*  next;      /* as many as you like... */
    char                    name[FILE_NAME_SIZE];
+   unsigned int            IDAT_bits; /* Number of bits in IDAT size */
+   png_uint_32             IDAT_size; /* Total size of IDAT data */
    png_uint_32             id;        /* must be correct (see FILEID) */
-   png_size_t              datacount; /* In this (the last) buffer */
+   size_t                  datacount; /* In this (the last) buffer */
    png_store_buffer        data;      /* Last buffer in file */
    int                     npalette;  /* Number of entries in palette */
    store_palette_entry*    palette;   /* May be NULL */
@@ -776,15 +766,25 @@ typedef struct png_store
    char               test[128];      /* Name of test */
    char               error[256];
 
+   /* Share fields */
+   png_uint_32        chunklen; /* Length of chunk+overhead (chunkpos >= 8) */
+   png_uint_32        chunktype;/* Type of chunk (valid if chunkpos >= 4) */
+   png_uint_32        chunkpos; /* Position in chunk */
+   png_uint_32        IDAT_size;/* Accumulated IDAT size in .new */
+   unsigned int       IDAT_bits;/* Cache of the file store value */
+
    /* Read fields */
    png_structp        pread;    /* Used to read a saved file */
    png_infop          piread;
    png_store_file*    current;  /* Set when reading */
    png_store_buffer*  next;     /* Set when reading */
-   png_size_t         readpos;  /* Position in *next */
+   size_t             readpos;  /* Position in *next */
    png_byte*          image;    /* Buffer for reading interlaced images */
-   png_size_t         cb_image; /* Size of this buffer */
-   png_size_t         cb_row;   /* Row size of the image(s) */
+   size_t             cb_image; /* Size of this buffer */
+   size_t             cb_row;   /* Row size of the image(s) */
+   uLong              IDAT_crc;
+   png_uint_32        IDAT_len; /* Used when re-chunking IDAT chunks */
+   png_uint_32        IDAT_pos; /* Used when re-chunking IDAT chunks */
    png_uint_32        image_h;  /* Number of rows in a single image */
    store_pool         read_memory_pool;
 
@@ -792,7 +792,7 @@ typedef struct png_store
    png_store_file*    saved;
    png_structp        pwrite;   /* Used when writing a new file */
    png_infop          piwrite;
-   png_size_t         writepos; /* Position in .new */
+   size_t             writepos; /* Position in .new */
    char               wname[FILE_NAME_SIZE];
    png_store_buffer   new;      /* The end of the new PNG file being written. */
    store_pool         write_memory_pool;
@@ -871,6 +871,11 @@ store_init(png_store* ps)
    ps->pwrite = NULL;
    ps->piwrite = NULL;
    ps->writepos = 0;
+   ps->chunkpos = 8;
+   ps->chunktype = 0;
+   ps->chunklen = 16;
+   ps->IDAT_size = 0;
+   ps->IDAT_bits = 0;
    ps->new.prev = NULL;
    ps->palette = NULL;
    ps->npalette = 0;
@@ -893,6 +898,11 @@ store_freenew(png_store *ps)
 {
    store_freebuffer(&ps->new);
    ps->writepos = 0;
+   ps->chunkpos = 8;
+   ps->chunktype = 0;
+   ps->chunklen = 16;
+   ps->IDAT_size = 0;
+   ps->IDAT_bits = 0;
    if (ps->palette != NULL)
    {
       free(ps->palette);
@@ -906,9 +916,6 @@ store_storenew(png_store *ps)
 {
    png_store_buffer *pb;
 
-   if (ps->writepos != STORE_BUFFER_SIZE)
-      png_error(ps->pwrite, "invalid store call");
-
    pb = voidcast(png_store_buffer*, malloc(sizeof *pb));
 
    if (pb == NULL)
@@ -939,21 +946,52 @@ store_freefile(png_store_file **ppf)
    }
 }
 
-/* Main interface to file storeage, after writing a new PNG file (see the API
+static unsigned int
+bits_of(png_uint_32 num)
+{
+   /* Return the number of bits in 'num' */
+   unsigned int b = 0;
+
+   if (num & 0xffff0000U)  b += 16U, num >>= 16;
+   if (num & 0xff00U)      b += 8U, num >>= 8;
+   if (num & 0xf0U)        b += 4U, num >>= 4;
+   if (num & 0xcU)         b += 2U, num >>= 2;
+   if (num & 0x2U)         ++b, num >>= 1;
+   if (num)                ++b;
+
+   return b; /* 0..32 */
+}
+
+/* Main interface to file storage, after writing a new PNG file (see the API
  * below) call store_storefile to store the result with the given name and id.
  */
 static void
 store_storefile(png_store *ps, png_uint_32 id)
 {
-   png_store_file *pf = voidcast(png_store_file*, malloc(sizeof *pf));
+   png_store_file *pf;
+
+   if (ps->chunkpos != 0U || ps->chunktype != 0U || ps->chunklen != 0U ||
+       ps->IDAT_size == 0)
+      png_error(ps->pwrite, "storefile: incomplete write");
+
+   pf = voidcast(png_store_file*, malloc(sizeof *pf));
    if (pf == NULL)
       png_error(ps->pwrite, "storefile: OOM");
    safecat(pf->name, sizeof pf->name, 0, ps->wname);
    pf->id = id;
    pf->data = ps->new;
    pf->datacount = ps->writepos;
+   pf->IDAT_size = ps->IDAT_size;
+   pf->IDAT_bits = bits_of(ps->IDAT_size);
+   /* Because the IDAT always has zlib header stuff this must be true: */
+   if (pf->IDAT_bits == 0U)
+      png_error(ps->pwrite, "storefile: 0 sized IDAT");
    ps->new.prev = NULL;
    ps->writepos = 0;
+   ps->chunkpos = 8;
+   ps->chunktype = 0;
+   ps->chunklen = 16;
+   ps->IDAT_size = 0;
    pf->palette = ps->palette;
    pf->npalette = ps->npalette;
    ps->palette = 0;
@@ -1088,7 +1126,7 @@ static png_bytep
 store_image_row(const png_store* ps, png_const_structp pp, int nImage,
    png_uint_32 y)
 {
-   png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2;
+   size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2;
 
    if (ps->image == NULL)
       png_error(pp, "no allocated image");
@@ -1123,9 +1161,9 @@ store_image_free(png_store *ps, png_const_structp pp)
 
 static void
 store_ensure_image(png_store *ps, png_const_structp pp, int nImages,
-   png_size_t cbRow, png_uint_32 cRows)
+   size_t cbRow, png_uint_32 cRows)
 {
-   png_size_t cb = nImages * cRows * (cbRow + 5);
+   size_t cb = nImages * cRows * (cbRow + 5);
 
    if (ps->cb_image < cb)
    {
@@ -1197,14 +1235,14 @@ store_image_check(const png_store* ps, png_const_structp pp, int iImage)
       png_error(pp, "image overwrite");
    else
    {
-      png_size_t cbRow = ps->cb_row;
+      size_t cbRow = ps->cb_row;
       png_uint_32 rows = ps->image_h;
 
       image += iImage * (cbRow+5) * ps->image_h;
 
       image += 2; /* skip image first row markers */
 
-      while (rows-- > 0)
+      for (; rows > 0; --rows)
       {
          if (image[-2] != 190 || image[-1] != 239)
             png_error(pp, "row start overwritten");
@@ -1219,32 +1257,119 @@ store_image_check(const png_store* ps, png_const_structp pp, int iImage)
 }
 #endif /* PNG_READ_SUPPORTED */
 
+static int
+valid_chunktype(png_uint_32 chunktype)
+{
+   /* Each byte in the chunk type must be in one of the ranges 65..90, 97..122
+    * (both inclusive), so:
+    */
+   unsigned int i;
+
+   for (i=0; i<4; ++i)
+   {
+      unsigned int c = chunktype & 0xffU;
+
+      if (!((c >= 65U && c <= 90U) || (c >= 97U && c <= 122U)))
+         return 0;
+
+      chunktype >>= 8;
+   }
+
+   return 1; /* It's valid */
+}
+
 static void PNGCBAPI
-store_write(png_structp ppIn, png_bytep pb, png_size_t st)
+store_write(png_structp ppIn, png_bytep pb, size_t st)
 {
    png_const_structp pp = ppIn;
    png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
+   size_t writepos = ps->writepos;
+   png_uint_32 chunkpos = ps->chunkpos;
+   png_uint_32 chunktype = ps->chunktype;
+   png_uint_32 chunklen = ps->chunklen;
 
    if (ps->pwrite != pp)
       png_error(pp, "store state damaged");
 
+   /* Technically this is legal, but in practice libpng never writes more than
+    * the maximum chunk size at once so if it happens something weird has
+    * changed inside libpng (probably).
+    */
+   if (st > 0x7fffffffU)
+      png_error(pp, "unexpected write size");
+
+   /* Now process the bytes to be written.  Do this in units of the space in the
+    * output (write) buffer or, at the start 4 bytes for the chunk type and
+    * length limited in any case by the amount of data.
+    */
    while (st > 0)
    {
-      size_t cb;
+      if (writepos >= STORE_BUFFER_SIZE)
+         store_storenew(ps), writepos = 0;
 
-      if (ps->writepos >= STORE_BUFFER_SIZE)
-         store_storenew(ps);
+      if (chunkpos < 4)
+      {
+         png_byte b = *pb++;
+         --st;
+         chunklen = (chunklen << 8) + b;
+         ps->new.buffer[writepos++] = b;
+         ++chunkpos;
+      }
 
-      cb = st;
+      else if (chunkpos < 8)
+      {
+         png_byte b = *pb++;
+         --st;
+         chunktype = (chunktype << 8) + b;
+         ps->new.buffer[writepos++] = b;
 
-      if (cb > STORE_BUFFER_SIZE - ps->writepos)
-         cb = STORE_BUFFER_SIZE - ps->writepos;
+         if (++chunkpos == 8)
+         {
+            chunklen &= 0xffffffffU;
+            if (chunklen > 0x7fffffffU)
+               png_error(pp, "chunk length too great");
 
-      memcpy(ps->new.buffer + ps->writepos, pb, cb);
-      pb += cb;
-      st -= cb;
-      ps->writepos += cb;
-   }
+            chunktype &= 0xffffffffU;
+            if (chunktype == CHUNK_IDAT)
+            {
+               if (chunklen > ~ps->IDAT_size)
+                  png_error(pp, "pngvalid internal image too large");
+
+               ps->IDAT_size += chunklen;
+            }
+
+            else if (!valid_chunktype(chunktype))
+               png_error(pp, "invalid chunk type");
+
+            chunklen += 12; /* for header and CRC */
+         }
+      }
+
+      else /* chunkpos >= 8 */
+      {
+         size_t cb = st;
+
+         if (cb > STORE_BUFFER_SIZE - writepos)
+            cb = STORE_BUFFER_SIZE - writepos;
+
+         if (cb  > chunklen - chunkpos/* bytes left in chunk*/)
+            cb = (size_t)/*SAFE*/(chunklen - chunkpos);
+
+         memcpy(ps->new.buffer + writepos, pb, cb);
+         chunkpos += (png_uint_32)/*SAFE*/cb;
+         pb += cb;
+         writepos += cb;
+         st -= cb;
+
+         if (chunkpos >= chunklen) /* must be equal */
+            chunkpos = chunktype = chunklen = 0;
+      }
+   } /* while (st > 0) */
+
+   ps->writepos = writepos;
+   ps->chunkpos = chunkpos;
+   ps->chunktype = chunktype;
+   ps->chunklen = chunklen;
 }
 
 static void PNGCBAPI
@@ -1264,7 +1389,6 @@ store_read_buffer_size(png_store *ps)
    return ps->current->datacount;
 }
 
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
 /* Return total bytes available for read. */
 static size_t
 store_read_buffer_avail(png_store *ps)
@@ -1289,7 +1413,6 @@ store_read_buffer_avail(png_store *ps)
 
    return 0;
 }
-#endif
 
 static int
 store_read_buffer_next(png_store *ps)
@@ -1318,7 +1441,7 @@ store_read_buffer_next(png_store *ps)
  * during progressive read, where the io_ptr is set internally by libpng.
  */
 static void
-store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
+store_read_imp(png_store *ps, png_bytep pb, size_t st)
 {
    if (ps->current == NULL || ps->next == NULL)
       png_error(ps->pread, "store state damaged");
@@ -1341,8 +1464,241 @@ store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
    }
 }
 
+static size_t
+store_read_chunk(png_store *ps, png_bytep pb, size_t max, size_t min)
+{
+   png_uint_32 chunklen = ps->chunklen;
+   png_uint_32 chunktype = ps->chunktype;
+   png_uint_32 chunkpos = ps->chunkpos;
+   size_t st = max;
+
+   if (st > 0) do
+   {
+      if (chunkpos >= chunklen) /* end of last chunk */
+      {
+         png_byte buffer[8];
+
+         /* Read the header of the next chunk: */
+         store_read_imp(ps, buffer, 8U);
+         chunklen = png_get_uint_32(buffer) + 12U;
+         chunktype = png_get_uint_32(buffer+4U);
+         chunkpos = 0U; /* Position read so far */
+      }
+
+      if (chunktype == CHUNK_IDAT)
+      {
+         png_uint_32 IDAT_pos = ps->IDAT_pos;
+         png_uint_32 IDAT_len = ps->IDAT_len;
+         png_uint_32 IDAT_size = ps->IDAT_size;
+
+         /* The IDAT headers are constructed here; skip the input header. */
+         if (chunkpos < 8U)
+            chunkpos = 8U;
+
+         if (IDAT_pos == IDAT_len)
+         {
+            png_byte random = random_byte();
+
+            /* Make a new IDAT chunk, if IDAT_len is 0 this is the first IDAT,
+             * if IDAT_size is 0 this is the end.  At present this is set up
+             * using a random number so that there is a 25% chance before
+             * the start of the first IDAT chunk being 0 length.
+             */
+            if (IDAT_len == 0U) /* First IDAT */
+            {
+               switch (random & 3U)
+               {
+                  case 0U: IDAT_len = 12U; break; /* 0 bytes */
+                  case 1U: IDAT_len = 13U; break; /* 1 byte */
+                  default: IDAT_len = random_u32();
+                           IDAT_len %= IDAT_size;
+                           IDAT_len += 13U; /* 1..IDAT_size bytes */
+                           break;
+               }
+            }
+
+            else if (IDAT_size == 0U) /* all IDAT data read */
+            {
+               /* The last (IDAT) chunk should be positioned at the CRC now: */
+               if (chunkpos != chunklen-4U)
+                  png_error(ps->pread, "internal: IDAT size mismatch");
+
+               /* The only option here is to add a zero length IDAT, this
+                * happens 25% of the time.  Because of the check above
+                * chunklen-4U-chunkpos must be zero, we just need to skip the
+                * CRC now.
+                */
+               if ((random & 3U) == 0U)
+                  IDAT_len = 12U; /* Output another 0 length IDAT */
+
+               else
+               {
+                  /* End of IDATs, skip the CRC to make the code above load the
+                   * next chunk header next time round.
+                   */
+                  png_byte buffer[4];
+
+                  store_read_imp(ps, buffer, 4U);
+                  chunkpos += 4U;
+                  ps->IDAT_pos = IDAT_pos;
+                  ps->IDAT_len = IDAT_len;
+                  ps->IDAT_size = 0U;
+                  continue; /* Read the next chunk */
+               }
+            }
+
+            else
+            {
+               /* Middle of IDATs, use 'random' to determine the number of bits
+                * to use in the IDAT length.
+                */
+               IDAT_len = random_u32();
+               IDAT_len &= (1U << (1U + random % ps->IDAT_bits)) - 1U;
+               if (IDAT_len > IDAT_size)
+                  IDAT_len = IDAT_size;
+               IDAT_len += 12U; /* zero bytes may occur */
+            }
+
+            IDAT_pos = 0U;
+            ps->IDAT_crc = 0x35af061e; /* Ie: crc32(0UL, "IDAT", 4) */
+         } /* IDAT_pos == IDAT_len */
+
+         if (IDAT_pos < 8U) /* Return the header */ do
+         {
+            png_uint_32 b;
+            unsigned int shift;
+
+            if (IDAT_pos < 4U)
+               b = IDAT_len - 12U;
+
+            else
+               b = CHUNK_IDAT;
+
+            shift = 3U & IDAT_pos;
+            ++IDAT_pos;
+
+            if (shift < 3U)
+               b >>= 8U*(3U-shift);
+
+            *pb++ = 0xffU & b;
+         }
+         while (--st > 0 && IDAT_pos < 8);
+
+         else if (IDAT_pos < IDAT_len - 4U) /* I.e not the CRC */
+         {
+            if (chunkpos < chunklen-4U)
+            {
+               uInt avail = (uInt)-1;
+
+               if (avail > (IDAT_len-4U) - IDAT_pos)
+                  avail = (uInt)/*SAFE*/((IDAT_len-4U) - IDAT_pos);
+
+               if (avail > st)
+                  avail = (uInt)/*SAFE*/st;
+
+               if (avail > (chunklen-4U) - chunkpos)
+                  avail = (uInt)/*SAFE*/((chunklen-4U) - chunkpos);
+
+               store_read_imp(ps, pb, avail);
+               ps->IDAT_crc = crc32(ps->IDAT_crc, pb, avail);
+               pb += (size_t)/*SAFE*/avail;
+               st -= (size_t)/*SAFE*/avail;
+               chunkpos += (png_uint_32)/*SAFE*/avail;
+               IDAT_size -= (png_uint_32)/*SAFE*/avail;
+               IDAT_pos += (png_uint_32)/*SAFE*/avail;
+            }
+
+            else /* skip the input CRC */
+            {
+               png_byte buffer[4];
+
+               store_read_imp(ps, buffer, 4U);
+               chunkpos += 4U;
+            }
+         }
+
+         else /* IDAT crc */ do
+         {
+            uLong b = ps->IDAT_crc;
+            unsigned int shift = (IDAT_len - IDAT_pos); /* 4..1 */
+            ++IDAT_pos;
+
+            if (shift > 1U)
+               b >>= 8U*(shift-1U);
+
+            *pb++ = 0xffU & b;
+         }
+         while (--st > 0 && IDAT_pos < IDAT_len);
+
+         ps->IDAT_pos = IDAT_pos;
+         ps->IDAT_len = IDAT_len;
+         ps->IDAT_size = IDAT_size;
+      }
+
+      else /* !IDAT */
+      {
+         /* If there is still some pending IDAT data after the IDAT chunks have
+          * been processed there is a problem:
+          */
+         if (ps->IDAT_len > 0 && ps->IDAT_size > 0)
+            png_error(ps->pread, "internal: missing IDAT data");
+
+         if (chunktype == CHUNK_IEND && ps->IDAT_len == 0U)
+            png_error(ps->pread, "internal: missing IDAT");
+
+         if (chunkpos < 8U) /* Return the header */ do
+         {
+            png_uint_32 b;
+            unsigned int shift;
+
+            if (chunkpos < 4U)
+               b = chunklen - 12U;
+
+            else
+               b = chunktype;
+
+            shift = 3U & chunkpos;
+            ++chunkpos;
+
+            if (shift < 3U)
+               b >>= 8U*(3U-shift);
+
+            *pb++ = 0xffU & b;
+         }
+         while (--st > 0 && chunkpos < 8);
+
+         else /* Return chunk bytes, including the CRC */
+         {
+            size_t avail = st;
+
+            if (avail > chunklen - chunkpos)
+               avail = (size_t)/*SAFE*/(chunklen - chunkpos);
+
+            store_read_imp(ps, pb, avail);
+            pb += avail;
+            st -= avail;
+            chunkpos += (png_uint_32)/*SAFE*/avail;
+
+            /* Check for end of chunk and end-of-file; don't try to read a new
+             * chunk header at this point unless instructed to do so by 'min'.
+             */
+            if (chunkpos >= chunklen && max-st >= min &&
+                     store_read_buffer_avail(ps) == 0)
+               break;
+         }
+      } /* !IDAT */
+   }
+   while (st > 0);
+
+   ps->chunklen = chunklen;
+   ps->chunktype = chunktype;
+   ps->chunkpos = chunkpos;
+
+   return st; /* space left */
+}
+
 static void PNGCBAPI
-store_read(png_structp ppIn, png_bytep pb, png_size_t st)
+store_read(png_structp ppIn, png_bytep pb, size_t st)
 {
    png_const_structp pp = ppIn;
    png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
@@ -1350,26 +1706,33 @@ store_read(png_structp ppIn, png_bytep pb, png_size_t st)
    if (ps == NULL || ps->pread != pp)
       png_error(pp, "bad store read call");
 
-   store_read_imp(ps, pb, st);
+   store_read_chunk(ps, pb, st, st);
 }
 
 static void
 store_progressive_read(png_store *ps, png_structp pp, png_infop pi)
 {
-   /* Notice that a call to store_read will cause this function to fail because
-    * readpos will be set.
-    */
    if (ps->pread != pp || ps->current == NULL || ps->next == NULL)
       png_error(pp, "store state damaged (progressive)");
 
-   do
+   /* This is another Horowitz and Hill random noise generator.  In this case
+    * the aim is to stress the progressive reader with truly horrible variable
+    * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers
+    * is generated.  We could probably just count from 1 to 32767 and get as
+    * good a result.
+    */
+   while (store_read_buffer_avail(ps) > 0)
    {
-      if (ps->readpos != 0)
-         png_error(pp, "store_read called during progressive read");
+      static png_uint_32 noise = 2;
+      size_t cb;
+      png_byte buffer[512];
 
-      png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps));
+      /* Generate 15 more bits of stuff: */
+      noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);
+      cb = noise & 0x1ff;
+      cb -= store_read_chunk(ps, buffer, cb, 1);
+      png_process_data(pp, pi, buffer, cb);
    }
-   while (store_read_buffer_next(ps));
 }
 #endif /* PNG_READ_SUPPORTED */
 
@@ -1740,6 +2103,11 @@ store_read_reset(png_store *ps)
    ps->next = NULL;
    ps->readpos = 0;
    ps->validated = 0;
+
+   ps->chunkpos = 8;
+   ps->chunktype = 0;
+   ps->chunklen = 16;
+   ps->IDAT_size = 0;
 }
 
 #ifdef PNG_READ_SUPPORTED
@@ -1754,6 +2122,11 @@ store_read_set(png_store *ps, png_uint_32 id)
       {
          ps->current = pf;
          ps->next = NULL;
+         ps->IDAT_size = pf->IDAT_size;
+         ps->IDAT_bits = pf->IDAT_bits; /* just a cache */
+         ps->IDAT_len = 0;
+         ps->IDAT_pos = 0;
+         ps->IDAT_crc = 0UL;
          store_read_buffer_next(ps);
          return;
       }
@@ -2217,7 +2590,7 @@ static double digitize(double value, int depth, int do_round)
     * rounding and 'do_round' should be 1, if it is 0 the digitized value will
     * be truncated.
     */
-   const unsigned int digitization_factor = (1U << depth) -1;
+   unsigned int digitization_factor = (1U << depth) - 1;
 
    /* Limiting the range is done as a convenience to the caller - it's easier to
     * do it once here than every time at the call site.
@@ -2591,17 +2964,6 @@ modifier_color_encoding_is_set(const png_modifier *pm)
    return pm->current_gamma != 0;
 }
 
-/* Convenience macros. */
-#define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
-#define CHUNK_IHDR CHUNK(73,72,68,82)
-#define CHUNK_PLTE CHUNK(80,76,84,69)
-#define CHUNK_IDAT CHUNK(73,68,65,84)
-#define CHUNK_IEND CHUNK(73,69,78,68)
-#define CHUNK_cHRM CHUNK(99,72,82,77)
-#define CHUNK_gAMA CHUNK(103,65,77,65)
-#define CHUNK_sBIT CHUNK(115,66,73,84)
-#define CHUNK_sRGB CHUNK(115,82,71,66)
-
 /* The guts of modification are performed during a read. */
 static void
 modifier_crc(png_bytep buffer)
@@ -2629,7 +2991,7 @@ modifier_setbuffer(png_modifier *pm)
  * png_struct.
  */
 static void
-modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
+modifier_read_imp(png_modifier *pm, png_bytep pb, size_t st)
 {
    while (st > 0)
    {
@@ -2641,7 +3003,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
       {
          static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
          case modifier_start:
-            store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */
+            store_read_chunk(&pm->this, pm->buffer, 8, 8); /* signature. */
             pm->buffer_count = 8;
             pm->buffer_position = 0;
 
@@ -2651,7 +3013,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
             break;
 
          case modifier_signature:
-            store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */
+            store_read_chunk(&pm->this, pm->buffer, 13+12, 13+12); /* IHDR */
             pm->buffer_count = 13+12;
             pm->buffer_position = 0;
 
@@ -2692,7 +3054,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
             {
                if (cb > st) cb = st;
                pm->flush -= cb;
-               store_read_imp(&pm->this, pb, cb);
+               store_read_chunk(&pm->this, pb, cb, cb);
                pb += cb;
                st -= cb;
                if (st == 0) return;
@@ -2709,7 +3071,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
                pm->pending_chunk = 0;
             }
             else
-               store_read_imp(&pm->this, pm->buffer, 8);
+               store_read_chunk(&pm->this, pm->buffer, 8, 8);
 
             pm->buffer_count = 8;
             pm->buffer_position = 0;
@@ -2775,8 +3137,8 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
              */
             if (len+12 <= sizeof pm->buffer)
             {
-               store_read_imp(&pm->this, pm->buffer+pm->buffer_count,
-                   len+12-pm->buffer_count);
+               size_t s = len+12-pm->buffer_count;
+               store_read_chunk(&pm->this, pm->buffer+pm->buffer_count, s, s);
                pm->buffer_count = len+12;
 
                /* Check for a modification, else leave it be. */
@@ -2834,7 +3196,7 @@ modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
 
 /* The callback: */
 static void PNGCBAPI
-modifier_read(png_structp ppIn, png_bytep pb, png_size_t st)
+modifier_read(png_structp ppIn, png_bytep pb, size_t st)
 {
    png_const_structp pp = ppIn;
    png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp));
@@ -2864,7 +3226,7 @@ modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi)
    for (;;)
    {
       static png_uint_32 noise = 1;
-      png_size_t cb, cbAvail;
+      size_t cb, cbAvail;
       png_byte buffer[512];
 
       /* Generate 15 more bits of stuff: */
@@ -3317,17 +3679,17 @@ init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette,
       for (; i<256; ++i)
          tRNS[i] = 24;
 
-#     ifdef PNG_WRITE_tRNS_SUPPORTED
-         if (j > 0)
-            png_set_tRNS(pp, pi, tRNS, j, 0/*color*/);
-#     endif
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+      if (j > 0)
+         png_set_tRNS(pp, pi, tRNS, j, 0/*color*/);
+#endif
    }
 }
 
 #ifdef PNG_WRITE_tRNS_SUPPORTED
 static void
-set_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type,
-   const int bit_depth)
+set_random_tRNS(png_structp pp, png_infop pi, png_byte colour_type,
+   int bit_depth)
 {
    /* To make this useful the tRNS color needs to match at least one pixel.
     * Random values are fine for gray, including the 16-bit case where we know
@@ -3335,7 +3697,7 @@ set_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type,
     * method as only 65536 different RGB values are generated.
     */
    png_color_16 tRNS;
-   const png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);
+   png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);
 
    R8(tRNS); /* makes unset fields random */
 
@@ -3343,8 +3705,8 @@ set_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type,
    {
       if (bit_depth == 8)
       {
-         R16(tRNS.red);
-         R16(tRNS.green);
+         tRNS.red = random_u16();
+         tRNS.green = random_u16();
          tRNS.blue = tRNS.red ^ tRNS.green;
          tRNS.red &= mask;
          tRNS.green &= mask;
@@ -3353,7 +3715,7 @@ set_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type,
 
       else /* bit_depth == 16 */
       {
-         R16(tRNS.red);
+         tRNS.red = random_u16();
          tRNS.green = (png_uint_16)(tRNS.red * 257);
          tRNS.blue = (png_uint_16)(tRNS.green * 17);
       }
@@ -3361,7 +3723,7 @@ set_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type,
 
    else
    {
-      R16(tRNS.gray);
+      tRNS.gray = random_u16();
       tRNS.gray &= mask;
    }
 
@@ -3648,8 +4010,11 @@ check_interlace_type(int const interlace_type)
 #  define do_own_interlace 1
 #endif /* WRITE_INTERLACING tests */
 
-#define CAN_WRITE_INTERLACE\
-   PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED
+#if PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED
+#   define CAN_WRITE_INTERLACE 1
+#else
+#   define CAN_WRITE_INTERLACE 0
+#endif
 
 /* Do the same thing for read interlacing; this controls whether read tests do
  * their own de-interlace or use libpng.
@@ -3973,7 +4338,7 @@ make_size_image(png_store* const ps, png_byte const colour_type,
 
       /* Make a name and get an appropriate id for the store: */
       char name[FILE_NAME_SIZE];
-      const png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/,
+      png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/,
          interlace_type, w, h, do_interlace);
 
       standard_name_from_id(name, sizeof name, 0, id);
@@ -4049,7 +4414,7 @@ make_size_image(png_store* const ps, png_byte const colour_type,
          for (pass=0; pass<npasses; ++pass)
          {
             /* The following two are for checking the macros: */
-            const png_uint_32 wPass = PNG_PASS_COLS(w, pass);
+            png_uint_32 wPass = PNG_PASS_COLS(w, pass);
 
             /* If do_interlace is set we don't call png_write_row for every
              * row because some of them are empty.  In fact, for a 1x1 image,
@@ -4281,7 +4646,7 @@ make_error(png_store* const ps, png_byte const colour_type,
    Try
    {
       png_infop pi;
-      const png_structp pp = set_store_for_write(ps, &pi, name);
+      png_structp pp = set_store_for_write(ps, &pi, name);
       png_uint_32 w, h;
       gnu_volatile(pp)
 
@@ -4341,7 +4706,7 @@ make_error(png_store* const ps, png_byte const colour_type,
       else
       {
          /* Now write the whole image, just to make sure that the detected, or
-          * undetected, errro has not created problems inside libpng.  This
+          * undetected, error has not created problems inside libpng.  This
           * doesn't work if there was a png_error in png_write_info because that
           * can abort before PLTE was written.
           */
@@ -4636,7 +5001,7 @@ standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
    dp->npalette = 0;
    /* Preset the transparent color to black: */
    memset(&dp->transparent, 0, sizeof dp->transparent);
-   /* Preset the palette to full intensity/opaque througout: */
+   /* Preset the palette to full intensity/opaque throughout: */
    memset(dp->palette, 0xff, sizeof dp->palette);
 }
 
@@ -4905,7 +5270,7 @@ standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
     */
    standard_palette_validate(dp, pp, pi);
 
-   /* In any case always check for a tranparent color (notice that the
+   /* In any case always check for a transparent color (notice that the
     * colour type 3 case must not give a successful return on the get_tRNS call
     * with these arguments!)
     */
@@ -5104,14 +5469,14 @@ progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass)
 
 static void
 sequential_row(standard_display *dp, png_structp pp, png_infop pi,
-    const int iImage, const int iDisplay)
+    int iImage, int iDisplay)
 {
-   const int         npasses = dp->npasses;
-   const int         do_interlace = dp->do_interlace &&
+   int npasses = dp->npasses;
+   int do_interlace = dp->do_interlace &&
       dp->interlace_type == PNG_INTERLACE_ADAM7;
-   const png_uint_32 height = standard_height(pp, dp->id);
-   const png_uint_32 width = standard_width(pp, dp->id);
-   const png_store*  ps = dp->ps;
+   png_uint_32 height = standard_height(pp, dp->id);
+   png_uint_32 width = standard_width(pp, dp->id);
+   const png_store* ps = dp->ps;
    int pass;
 
    for (pass=0; pass<npasses; ++pass)
@@ -5505,7 +5870,7 @@ test_size(png_modifier* const pm, png_byte const colour_type,
     */
    static const png_byte hinc[] = {1, 3, 11, 1, 5};
    static const png_byte winc[] = {1, 9, 5, 7, 1};
-   const int save_bdlo = bdlo;
+   int save_bdlo = bdlo;
 
    for (; bdlo <= bdhi; ++bdlo)
    {
@@ -5713,12 +6078,12 @@ image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
     png_byte bit_depth, png_uint_32 x, store_palette palette,
     const image_pixel *format /*from pngvalid transform of input*/)
 {
-   const png_byte sample_depth = (png_byte)(colour_type ==
-      PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
-   const unsigned int max = (1U<<sample_depth)-1;
-   const int swap16 = (format != 0 && format->swap16);
-   const int littleendian = (format != 0 && format->littleendian);
-   const int sig_bits = (format != 0 && format->sig_bits);
+   png_byte sample_depth =
+      (png_byte)(colour_type == PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
+   unsigned int max = (1U<<sample_depth)-1;
+   int swap16 = (format != 0 && format->swap16);
+   int littleendian = (format != 0 && format->littleendian);
+   int sig_bits = (format != 0 && format->sig_bits);
 
    /* Initially just set everything to the same number and the alpha to opaque.
     * Note that this currently assumes a simple palette where entry x has colour
@@ -5736,7 +6101,7 @@ image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
       /* This permits the caller to default to the sample value. */
       if (palette != 0)
       {
-         const unsigned int i = this->palette_index;
+         unsigned int i = this->palette_index;
 
          this->red = palette[i].red;
          this->green = palette[i].green;
@@ -6067,8 +6432,8 @@ static void
 image_transform_mod_end(const image_transform *this, image_pixel *that,
     png_const_structp pp, const transform_display *display)
 {
-   const unsigned int scale = (1U<<that->sample_depth)-1;
-   const int sig_bits = that->sig_bits;
+   unsigned int scale = (1U<<that->sample_depth)-1;
+   int sig_bits = that->sig_bits;
 
    UNUSED(this)
    UNUSED(pp)
@@ -6219,16 +6584,16 @@ transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
    {
    case PNG_COLOR_TYPE_PALETTE:
       if (dp->output_bit_depth > 8) goto error;
-      /*FALL THROUGH*/
+      /* FALLTHROUGH */
    case PNG_COLOR_TYPE_GRAY:
       if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 ||
          dp->output_bit_depth == 4)
          break;
-      /*FALL THROUGH*/
+      /* FALLTHROUGH */
    default:
       if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16)
          break;
-      /*FALL THROUGH*/
+      /* FALLTHROUGH */
    error:
       {
          char message[128];
@@ -6391,19 +6756,19 @@ transform_image_validate(transform_display *dp, png_const_structp pp,
 {
    /* Constants for the loop below: */
    const png_store* const ps = dp->this.ps;
-   const png_byte in_ct = dp->this.colour_type;
-   const png_byte in_bd = dp->this.bit_depth;
-   const png_uint_32 w = dp->this.w;
-   const png_uint_32 h = dp->this.h;
-   const png_byte out_ct = dp->output_colour_type;
-   const png_byte out_bd = dp->output_bit_depth;
-   const png_byte sample_depth = (png_byte)(out_ct ==
-      PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);
-   const png_byte red_sBIT = dp->this.red_sBIT;
-   const png_byte green_sBIT = dp->this.green_sBIT;
-   const png_byte blue_sBIT = dp->this.blue_sBIT;
-   const png_byte alpha_sBIT = dp->this.alpha_sBIT;
-   const int have_tRNS = dp->this.is_transparent;
+   png_byte in_ct = dp->this.colour_type;
+   png_byte in_bd = dp->this.bit_depth;
+   png_uint_32 w = dp->this.w;
+   png_uint_32 h = dp->this.h;
+   png_byte out_ct = dp->output_colour_type;
+   png_byte out_bd = dp->output_bit_depth;
+   png_byte sample_depth =
+      (png_byte)(out_ct == PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);
+   png_byte red_sBIT = dp->this.red_sBIT;
+   png_byte green_sBIT = dp->this.green_sBIT;
+   png_byte blue_sBIT = dp->this.blue_sBIT;
+   png_byte alpha_sBIT = dp->this.alpha_sBIT;
+   int have_tRNS = dp->this.is_transparent;
    double digitization_error;
 
    store_palette out_palette;
@@ -6415,7 +6780,7 @@ transform_image_validate(transform_display *dp, png_const_structp pp,
    store_image_check(dp->this.ps, pp, 0);
 
    /* Read the palette corresponding to the output if the output colour type
-    * indicates a palette, othewise set out_palette to garbage.
+    * indicates a palette, otherwise set out_palette to garbage.
     */
    if (out_ct == PNG_COLOR_TYPE_PALETTE)
    {
@@ -6564,7 +6929,7 @@ transform_end(png_structp ppIn, png_infop pi)
 
 /* A single test run. */
 static void
-transform_test(png_modifier *pmIn, const png_uint_32 idIn,
+transform_test(png_modifier *pmIn, png_uint_32 idIn,
     const image_transform* transform_listIn, const char * const name)
 {
    transform_display d;
@@ -7313,7 +7678,7 @@ image_transform_png_set_rgb_to_gray_ini(const image_transform *this,
       png_uint_32 ru;
       double total;
 
-      R32(ru);
+      ru = random_u32();
       data.green_coefficient = total = (ru & 0xffff) / 65535.;
       ru >>= 16;
       data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.;
@@ -7377,13 +7742,11 @@ image_transform_png_set_rgb_to_gray_ini(const image_transform *this,
           * NOTE: this number only affects the internal limit check in pngvalid,
           * it has no effect on the limits applied to the libpng values.
           */
-         that->pm->limit += pow(
-#        if DIGITIZE
-            2.0
-#        else
-            1.0
-#        endif
-            /255, data.gamma);
+#if DIGITIZE
+          that->pm->limit += pow( 2.0/255, data.gamma);
+#else
+          that->pm->limit += pow( 1.0/255, data.gamma);
+#endif
       }
    }
 
@@ -7401,7 +7764,7 @@ static void
 image_transform_png_set_rgb_to_gray_set(const image_transform *this,
     transform_display *that, png_structp pp, png_infop pi)
 {
-   const int error_action = 1; /* no error, no defines in png.h */
+   int error_action = 1; /* no error, no defines in png.h */
 
 #  ifdef PNG_FLOATING_POINT_SUPPORTED
       png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set);
@@ -7542,10 +7905,10 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
 #  if DIGITIZE
       {
          png_modifier *pm = display->pm;
-         const unsigned int sample_depth = that->sample_depth;
-         const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
+         unsigned int sample_depth = that->sample_depth;
+         unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
             sample_depth);
-         const unsigned int gamma_depth =
+         unsigned int gamma_depth =
             (sample_depth == 16 ?
                display->max_gamma_8 :
                (pm->assume_16_bit_calculations ?
@@ -7628,7 +7991,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
          /* Now calculate the actual gray values.  Although the error in the
           * coefficients depends on whether they were specified on the command
           * line (in which case truncation to 15 bits happened) or not (rounding
-          * was used) the maxium error in an individual coefficient is always
+          * was used) the maximum error in an individual coefficient is always
           * 2/32768, because even in the rounding case the requirement that
           * coefficients add up to 32768 can cause a larger rounding error.
           *
@@ -7639,7 +8002,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
             b * data.blue_coefficient;
 
          {
-            const int do_round = data.gamma != 1 || calc_depth == 16;
+            int do_round = data.gamma != 1 || calc_depth == 16;
             const double ce = 2. / 32768;
 
             graylo = DD(rlo * (data.red_coefficient-ce) +
@@ -7844,7 +8207,7 @@ image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
       that->bluef = that->greenf = that->redf = gray;
       that->bluee = that->greene = that->rede = err;
 
-      /* The sBIT is the minium of the three colour channel sBITs. */
+      /* The sBIT is the minimum of the three colour channel sBITs. */
       if (that->red_sBIT > that->green_sBIT)
          that->red_sBIT = that->green_sBIT;
       if (that->red_sBIT > that->blue_sBIT)
@@ -7947,11 +8310,11 @@ image_transform_png_set_background_set(const image_transform *this,
    else
       back.gray = (png_uint_16)data.red;
 
-#  ifdef PNG_FLOATING_POINT_SUPPORTED
-      png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
-#  else
-      png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
-#  endif
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+   png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
+#else
+   png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
+#endif
 
    this->next->set(this->next, that, pp, pi);
 }
@@ -8241,7 +8604,7 @@ image_transform_png_set_filler_set(const image_transform *this,
     * filler.  The 'filler' value has all 32 bits set, but only bit_depth
     * will be used.  At this point we don't know bit_depth.
     */
-   R32(data.filler);
+   data.filler = random_u32();
    data.flags = random_choice();
 
    png_set_filler(pp, data.filler, data.flags);
@@ -8263,7 +8626,7 @@ image_transform_png_set_filler_mod(const image_transform *this,
        (that->colour_type == PNG_COLOR_TYPE_RGB ||
         that->colour_type == PNG_COLOR_TYPE_GRAY))
    {
-      const unsigned int max = (1U << that->bit_depth)-1;
+      unsigned int max = (1U << that->bit_depth)-1;
       that->alpha = data.filler & max;
       that->alphaf = ((double)that->alpha) / max;
       that->alphae = 0;
@@ -8314,7 +8677,7 @@ image_transform_png_set_add_alpha_set(const image_transform *this,
     * filler.  The 'filler' value has all 32 bits set, but only bit_depth
     * will be used.  At this point we don't know bit_depth.
     */
-   R32(data.filler);
+   data.filler = random_u32();
    data.flags = random_choice();
 
    png_set_add_alpha(pp, data.filler, data.flags);
@@ -8330,7 +8693,7 @@ image_transform_png_set_add_alpha_mod(const image_transform *this,
        (that->colour_type == PNG_COLOR_TYPE_RGB ||
         that->colour_type == PNG_COLOR_TYPE_GRAY))
    {
-      const unsigned int max = (1U << that->bit_depth)-1;
+      unsigned int max = (1U << that->bit_depth)-1;
       that->alpha = data.filler & max;
       that->alphaf = ((double)that->alpha) / max;
       that->alphae = 0;
@@ -8521,7 +8884,7 @@ image_transform_png_set_shift_set(const image_transform *this,
     * field is randomized independently.  This acts as a check that
     * libpng does use the correct field.
     */
-   const unsigned int depth = that->this.bit_depth;
+   unsigned int depth = that->this.bit_depth;
 
    data.red = (png_byte)/*SAFE*/(random_mod(depth)+1);
    data.green = (png_byte)/*SAFE*/(random_mod(depth)+1);
@@ -8936,12 +9299,12 @@ gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
          int mode = dp->do_background - ALPHA_MODE_OFFSET;
 
          /* The gamma value is the output gamma, and is in the standard,
-          * non-inverted, represenation.  It provides a default for the PNG file
+          * non-inverted, representation.  It provides a default for the PNG file
           * gamma, but since the file has a gAMA chunk this does not matter.
           */
          const double sg = dp->screen_gamma;
 #        ifndef PNG_FLOATING_POINT_SUPPORTED
-            const png_fixed_point g = fix(sg);
+            png_fixed_point g = fix(sg);
 #        endif
 
 #        ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -8989,7 +9352,7 @@ gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
           */
          const double bg = dp->background_gamma;
 #        ifndef PNG_FLOATING_POINT_SUPPORTED
-            const png_fixed_point g = fix(bg);
+            png_fixed_point g = fix(bg);
 #        endif
 
 #        ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -9063,7 +9426,7 @@ static void
 init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,
     int in_depth, int out_depth)
 {
-   const unsigned int outmax = (1U<<out_depth)-1;
+   unsigned int outmax = (1U<<out_depth)-1;
 
    vi->pp = pp;
    vi->dp = dp;
@@ -9225,14 +9588,14 @@ gamma_component_compose(int do_background, double input_sample, double alpha,
 /* This API returns the encoded *input* component, in the range 0..1 */
 static double
 gamma_component_validate(const char *name, const validate_info *vi,
-    const unsigned int id, const unsigned int od,
+    unsigned int id, unsigned int od,
     const double alpha /* <0 for the alpha channel itself */,
     const double background /* component background value */)
 {
-   const unsigned int isbit = id >> vi->isbit_shift;
-   const unsigned int sbit_max = vi->sbit_max;
-   const unsigned int outmax = vi->outmax;
-   const int do_background = vi->do_background;
+   unsigned int isbit = id >> vi->isbit_shift;
+   unsigned int sbit_max = vi->sbit_max;
+   unsigned int outmax = vi->outmax;
+   int do_background = vi->do_background;
 
    double i;
 
@@ -9383,7 +9746,7 @@ gamma_component_validate(const char *name, const validate_info *vi,
        *
        * pngvalid calculations:
        *  input_sample: linear result; i linearized and composed, range 0..1
-       *  encoded_sample: encoded result; input_sample scaled to ouput bit depth
+       *  encoded_sample: encoded result; input_sample scaled to output bit depth
        *
        * libpng calculations:
        *  output: linear result; od scaled to 0..1 and linearized
@@ -9631,9 +9994,9 @@ gamma_component_validate(const char *name, const validate_info *vi,
                case PNG_BACKGROUND_GAMMA_FILE:
                case PNG_BACKGROUND_GAMMA_UNIQUE:
                   use_background = (alpha >= 0 && alpha < 1);
-                  /*FALL THROUGH*/
 #           endif
 #           ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+               /* FALLTHROUGH */
                case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
                case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
                case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
@@ -9798,13 +10161,13 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
 {
    /* Get some constants derived from the input and output file formats: */
    const png_store* const ps = dp->this.ps;
-   const png_byte in_ct = dp->this.colour_type;
-   const png_byte in_bd = dp->this.bit_depth;
-   const png_uint_32 w = dp->this.w;
-   const png_uint_32 h = dp->this.h;
+   png_byte in_ct = dp->this.colour_type;
+   png_byte in_bd = dp->this.bit_depth;
+   png_uint_32 w = dp->this.w;
+   png_uint_32 h = dp->this.h;
    const size_t cbRow = dp->this.cbRow;
-   const png_byte out_ct = png_get_color_type(pp, pi);
-   const png_byte out_bd = png_get_bit_depth(pp, pi);
+   png_byte out_ct = png_get_color_type(pp, pi);
+   png_byte out_bd = png_get_bit_depth(pp, pi);
 
    /* There are three sources of error, firstly the quantization in the
     * file encoding, determined by sbit and/or the file depth, secondly
@@ -9820,10 +10183,10 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
     * Since the library must quantize the output to 8 or 16 bits there is
     * a fundamental limit on the accuracy of the output of +/-.5 - this
     * quantization limit is included in addition to the other limits
-    * specified by the paramaters to the API.  (Effectively, add .5
+    * specified by the parameters to the API.  (Effectively, add .5
     * everywhere.)
     *
-    * The behavior of the 'sbit' paramter is defined by section 12.5
+    * The behavior of the 'sbit' parameter is defined by section 12.5
     * (sample depth scaling) of the PNG spec.  That section forces the
     * decoder to assume that the PNG values have been scaled if sBIT is
     * present:
@@ -9845,11 +10208,11 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
     * The basic tests below do not do this, however if 'use_input_precision'
     * is set a subsequent test is performed above.
     */
-   const unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
+   unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
    int processing;
    png_uint_32 y;
    const store_palette_entry *in_palette = dp->this.palette;
-   const int in_is_transparent = dp->this.is_transparent;
+   int in_is_transparent = dp->this.is_transparent;
    int process_tRNS;
    int out_npalette = -1;
    int out_is_transparent = 0; /* Just refers to the palette case */
@@ -9897,9 +10260,9 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
             double alpha = 1; /* serves as a flag value */
 
             /* Record the palette index for index images. */
-            const unsigned int in_index =
+            unsigned int in_index =
                in_ct == 3 ? sample(std, 3, in_bd, x, 0, 0, 0) : 256;
-            const unsigned int out_index =
+            unsigned int out_index =
                out_ct == 3 ? sample(std, 3, out_bd, x, 0, 0, 0) : 256;
 
             /* Handle input alpha - png_set_background will cause the output
@@ -9908,7 +10271,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
             if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 ||
                 (in_ct == 3 && in_is_transparent))
             {
-               const unsigned int input_alpha = in_ct == 3 ?
+               unsigned int input_alpha = in_ct == 3 ?
                   dp->this.palette[in_index].alpha :
                   sample(std, in_ct, in_bd, x, samples_per_pixel, 0, 0);
 
@@ -10033,14 +10396,14 @@ gamma_end(png_structp ppIn, png_infop pi)
  * maxpc:  maximum percentage error (as a percentage)
  */
 static void
-gamma_test(png_modifier *pmIn, const png_byte colour_typeIn,
-    const png_byte bit_depthIn, const int palette_numberIn,
-    const int interlace_typeIn,
+gamma_test(png_modifier *pmIn, png_byte colour_typeIn,
+    png_byte bit_depthIn, int palette_numberIn,
+    int interlace_typeIn,
     const double file_gammaIn, const double screen_gammaIn,
-    const png_byte sbitIn, const int threshold_testIn,
+    png_byte sbitIn, int threshold_testIn,
     const char *name,
-    const int use_input_precisionIn, const int scale16In,
-    const int expand16In, const int do_backgroundIn,
+    int use_input_precisionIn, int scale16In,
+    int expand16In, int do_backgroundIn,
     const png_color_16 *bkgd_colorIn, double bkgd_gammaIn)
 {
    gamma_display d;
@@ -10244,11 +10607,11 @@ perform_gamma_threshold_tests(png_modifier *pm)
 }
 
 static void gamma_transform_test(png_modifier *pm,
-   const png_byte colour_type, const png_byte bit_depth,
-   const int palette_number,
-   const int interlace_type, const double file_gamma,
-   const double screen_gamma, const png_byte sbit,
-   const int use_input_precision, const int scale16)
+   png_byte colour_type, png_byte bit_depth,
+   int palette_number,
+   int interlace_type, const double file_gamma,
+   const double screen_gamma, png_byte sbit,
+   int use_input_precision, int scale16)
 {
    size_t pos = 0;
    char name[64];
@@ -10405,12 +10768,12 @@ static void perform_gamma_scale16_tests(png_modifier *pm)
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
 static void gamma_composition_test(png_modifier *pm,
-   const png_byte colour_type, const png_byte bit_depth,
-   const int palette_number,
-   const int interlace_type, const double file_gamma,
+   png_byte colour_type, png_byte bit_depth,
+   int palette_number,
+   int interlace_type, const double file_gamma,
    const double screen_gamma,
-   const int use_input_precision, const int do_background,
-   const int expand_16)
+   int use_input_precision, int do_background,
+   int expand_16)
 {
    size_t pos = 0;
    png_const_charp base;
@@ -11064,23 +11427,36 @@ perform_interlace_macro_validation(void)
        */
       for (v=0;;)
       {
+         /* The first two tests overflow if the pass row or column is outside
+          * the possible range for a 32-bit result.  In fact the values should
+          * never be outside the range for a 31-bit result, but checking for 32
+          * bits here ensures that if an app uses a bogus pass row or column
+          * (just so long as it fits in a 32 bit integer) it won't get a
+          * possibly dangerous overflow.
+          */
          /* First the base 0 stuff: */
-         m = PNG_ROW_FROM_PASS_ROW(v, pass);
-         f = png_row_from_pass_row(v, pass);
-         if (m != f)
+         if (v < png_pass_rows(0xFFFFFFFFU, pass))
          {
-            fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n",
-               v, pass, m, f);
-            exit(99);
+            m = PNG_ROW_FROM_PASS_ROW(v, pass);
+            f = png_row_from_pass_row(v, pass);
+            if (m != f)
+            {
+               fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n",
+                  v, pass, m, f);
+               exit(99);
+            }
          }
 
-         m = PNG_COL_FROM_PASS_COL(v, pass);
-         f = png_col_from_pass_col(v, pass);
-         if (m != f)
+         if (v < png_pass_cols(0xFFFFFFFFU, pass))
          {
-            fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n",
-               v, pass, m, f);
-            exit(99);
+            m = PNG_COL_FROM_PASS_COL(v, pass);
+            f = png_col_from_pass_col(v, pass);
+            if (m != f)
+            {
+               fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n",
+                  v, pass, m, f);
+               exit(99);
+            }
          }
 
          m = PNG_ROW_IN_INTERLACE_PASS(v, pass);
@@ -11353,7 +11729,7 @@ int main(int argc, char **argv)
 
    /* Some default values (set the behavior for 'make check' here).
     * These values simply control the maximum error permitted in the gamma
-    * transformations.  The practial limits for human perception are described
+    * transformations.  The practical limits for human perception are described
     * below (the setting for maxpc16), however for 8 bit encodings it isn't
     * possible to meet the accepted capabilities of human vision - i.e. 8 bit
     * images can never be good enough, regardless of encoding.
index 3336d4e..60a2d46 100644 (file)
@@ -60,7 +60,7 @@ read_png(FILE *fp)
    png_read_info(png_ptr, info_ptr);
 
    {
-      png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+      size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
       /* Failure to initialize these is harmless */
       row = malloc(rowbytes);
index cb17ffa..c03f05a 100644 (file)
@@ -108,7 +108,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
 
    do
    {
-      png_size_t index;
+      size_t index;
       int state, failed = 0;
       char buffer[64];
 
@@ -176,7 +176,7 @@ int validation_ascii_to_fp(int count, int argc, char **argv)
       }
       else if (PNG_FP_IS_POSITIVE(state) && !(test > 0))
       {
-         fprintf(stderr, "%g[%d] -> '%s' but postive value not so reported\n",
+         fprintf(stderr, "%g[%d] -> '%s' but positive value not so reported\n",
             test, precision, buffer);
          failed = 1;
          assert(!PNG_FP_IS_NEGATIVE(state));
@@ -329,10 +329,10 @@ static int check_one_character(checkfp_command *co, checkfp_control c, int ch)
 {
    /* Test this character (ch) to ensure the parser does the correct thing.
     */
-   png_size_t index = 0;
+   size_t index = 0;
    const char test = (char)ch;
-   const int number_is_valid = png_check_fp_number(&test, 1, &c.state, &index);
-   const int character_accepted = (index == 1);
+   int number_is_valid = png_check_fp_number(&test, 1, &c.state, &index);
+   int character_accepted = (index == 1);
 
    if (c.check_state != exponent && isdigit(ch) && ch != '0')
       c.is_zero = 0;
index 7c93797..23d8b17 100644 (file)
@@ -1,8 +1,8 @@
 /* timepng.c
  *
- * Copyright (c) 2013 John Cunningham Bowler
+ * Copyright (c) 2013,2016 John Cunningham Bowler
  *
- * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Last changed in libpng 1.6.22 [May 26, 2016]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  *
  * Load an arbitrary number of PNG files (from the command line, or, if there
  * are no arguments on the command line, from stdin) then run a time test by
- * reading each file by row.  The test does nothing with the read result and
- * does no transforms.  The only output is a time as a floating point number of
- * seconds with 9 decimal digits.
+ * reading each file by row or by image (possibly with transforms in the latter
+ * case).  The only output is a time as a floating point number of seconds with
+ * 9 decimal digits.
  */
 #define _POSIX_C_SOURCE 199309L /* for clock_gettime */
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <errno.h>
+#include <limits.h>
 
 #include <time.h>
 
 #  include "../../png.h"
 #endif
 
-static int read_png(FILE *fp)
+/* The following is to support direct compilation of this file as C++ */
+#ifdef __cplusplus
+#  define voidcast(type, value) static_cast<type>(value)
+#else
+#  define voidcast(type, value) (value)
+#endif /* __cplusplus */
+
+/* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime.  It
+ * need not be supported even when clock_gettime is available.  It returns the
+ * 'CPU' time the process has consumed.  'CPU' time is assumed to include time
+ * when the CPU is actually blocked by a pending cache fill but not time
+ * waiting for page faults.  The attempt is to get a measure of the actual time
+ * the implementation takes to read a PNG ignoring the potentially very large IO
+ * overhead.
+ */
+#if defined (CLOCK_PROCESS_CPUTIME_ID) && defined(PNG_STDIO_SUPPORTED) &&\
+    defined(PNG_EASY_ACCESS_SUPPORTED) &&\
+    (PNG_LIBPNG_VER >= 10700 ? defined(PNG_READ_PNG_SUPPORTED) :\
+     defined (PNG_SEQUENTIAL_READ_SUPPORTED) &&\
+     defined(PNG_INFO_IMAGE_SUPPORTED))
+
+typedef struct
 {
-   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
-   png_infop info_ptr = NULL;
-   png_bytep row = NULL, display = NULL;
+   FILE *input;
+   FILE *output;
+}  io_data;
 
-   if (png_ptr == NULL)
-      return 0;
+static PNG_CALLBACK(void, read_and_copy,
+      (png_structp png_ptr, png_bytep buffer, size_t cb))
+{
+   io_data *io = (io_data*)png_get_io_ptr(png_ptr);
 
-   if (setjmp(png_jmpbuf(png_ptr)))
+   if (fread(buffer, cb, 1, io->input) != 1)
+      png_error(png_ptr, strerror(errno));
+
+   if (fwrite(buffer, cb, 1, io->output) != 1)
    {
-      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-      if (row != NULL) free(row);
-      if (display != NULL) free(display);
-      return 0;
+      perror("temporary file");
+      fprintf(stderr, "temporary file PNG write failed\n");
+      exit(1);
    }
+}
 
-   png_init_io(png_ptr, fp);
+static void read_by_row(png_structp png_ptr, png_infop info_ptr,
+      FILE *write_ptr, FILE *read_ptr)
+{
+   /* These don't get freed on error, this is fine; the program immediately
+    * exits.
+    */
+   png_bytep row = NULL, display = NULL;
+   io_data io_copy;
 
-   info_ptr = png_create_info_struct(png_ptr);
-   if (info_ptr == NULL)
-      png_error(png_ptr, "OOM allocating info structure");
+   if (write_ptr != NULL)
+   {
+      /* Set up for a copy to the temporary file: */
+      io_copy.input = read_ptr;
+      io_copy.output = write_ptr;
+      png_set_read_fn(png_ptr, &io_copy, read_and_copy);
+   }
 
    png_read_info(png_ptr, info_ptr);
 
    {
-      png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+      size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
-      row = malloc(rowbytes);
-      display = malloc(rowbytes);
+      row = voidcast(png_bytep,malloc(rowbytes));
+      display = voidcast(png_bytep,malloc(rowbytes));
 
       if (row == NULL || display == NULL)
          png_error(png_ptr, "OOM allocating row buffers");
@@ -81,7 +120,8 @@ static int read_png(FILE *fp)
             png_uint_32 y = height;
 
             /* NOTE: this trashes the row each time; interlace handling won't
-             * work, but this avoids memory thrashing for speed testing.
+             * work, but this avoids memory thrashing for speed testing and is
+             * somewhat representative of an application that works row-by-row.
              */
             while (y-- > 0)
                png_read_row(png_ptr, row, display);
@@ -91,9 +131,51 @@ static int read_png(FILE *fp)
 
    /* Make sure to read to the end of the file: */
    png_read_end(png_ptr, info_ptr);
-   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+
+   /* Free this up: */
    free(row);
    free(display);
+}
+
+static PNG_CALLBACK(void, no_warnings, (png_structp png_ptr,
+         png_const_charp warning))
+{
+   (void)png_ptr;
+   (void)warning;
+}
+
+static int read_png(FILE *fp, png_int_32 transforms, FILE *write_file)
+{
+   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,
+         no_warnings);
+   png_infop info_ptr = NULL;
+
+   if (png_ptr == NULL)
+      return 0;
+
+   if (setjmp(png_jmpbuf(png_ptr)))
+   {
+      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+      return 0;
+   }
+
+#  ifdef PNG_BENIGN_ERRORS_SUPPORTED
+      png_set_benign_errors(png_ptr, 1/*allowed*/);
+#  endif
+   png_init_io(png_ptr, fp);
+
+   info_ptr = png_create_info_struct(png_ptr);
+
+   if (info_ptr == NULL)
+      png_error(png_ptr, "OOM allocating info structure");
+
+   if (transforms < 0)
+      read_by_row(png_ptr, info_ptr, write_file, fp);
+
+   else
+      png_read_png(png_ptr, info_ptr, transforms, NULL/*params*/);
+
+   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    return 1;
 }
 
@@ -108,7 +190,7 @@ static int mytime(struct timespec *t)
    return 0;
 }
 
-static int perform_one_test(FILE *fp, int nfiles)
+static int perform_one_test(FILE *fp, int nfiles, png_int_32 transforms)
 {
    int i;
    struct timespec before, after;
@@ -120,7 +202,7 @@ static int perform_one_test(FILE *fp, int nfiles)
    {
       for (i=0; i<nfiles; ++i)
       {
-         if (read_png(fp))
+         if (read_png(fp, transforms, NULL/*write*/))
          {
             if (ferror(fp))
             {
@@ -184,120 +266,343 @@ static int add_one_file(FILE *fp, char *name)
 
    if (ip != NULL)
    {
-      int ch;
-      for (;;)
+      /* Read the file using libpng; this detects errors and also deals with
+       * files which contain data beyond the end of the file.
+       */
+      int ok = 0;
+      fpos_t pos;
+
+      if (fgetpos(fp, &pos))
       {
-         ch = getc(ip);
-         if (ch == EOF) break;
-         putc(ch, fp);
+         /* Fatal error reading the start: */
+         perror("temporary file");
+         fprintf(stderr, "temporary file fgetpos error\n");
+         exit(1);
       }
 
-      if (ferror(ip))
+      if (read_png(ip, -1/*by row*/, fp/*output*/))
       {
-         perror(name);
-         fprintf(stderr, "%s: read error\n", name);
-         return 0;
+         if (ferror(ip))
+         {
+            perror(name);
+            fprintf(stderr, "%s: read error\n", name);
+         }
+
+         else
+            ok = 1; /* read ok */
       }
 
+      else
+         fprintf(stderr, "%s: file not added\n", name);
+
       (void)fclose(ip);
 
+      /* An error in the output is fatal; exit immediately: */
       if (ferror(fp))
       {
          perror("temporary file");
          fprintf(stderr, "temporary file write error\n");
-         return 0;
+         exit(1);
+      }
+
+      if (ok)
+         return 1;
+
+      /* Did not read the file successfully, simply rewind the temporary
+       * file.  This must happen after the ferror check above to avoid clearing
+       * the error.
+       */
+      if (fsetpos(fp, &pos))
+      {
+         perror("temporary file");
+         fprintf(stderr, "temporary file fsetpos error\n");
+         exit(1);
       }
    }
 
    else
    {
+      /* file open error: */
       perror(name);
       fprintf(stderr, "%s: open failed\n", name);
-      return 0;
    }
 
-   return 1;
+   return 0; /* file not added */
+}
+
+static void
+usage(FILE *fp)
+{
+   if (fp != NULL) fclose(fp);
+
+   fprintf(stderr,
+"Usage:\n"
+" timepng --assemble <assembly> {files}\n"
+"  Read the files into <assembly>, output the count.  Options are ignored.\n"
+" timepng --dissemble <assembly> <count> [options]\n"
+"  Time <count> files from <assembly>, additional files may not be given.\n"
+" Otherwise:\n"
+"  Read the files into a temporary file and time the decode\n"
+"Transforms:\n"
+"  --by-image: read by image with png_read_png\n"
+"  --<transform>: implies by-image, use PNG_TRANSFORM_<transform>\n"
+"  Otherwise: read by row using png_read_row (to a single row buffer)\n"
+   /* ISO C90 string length max 509 */);fprintf(stderr,
+"{files}:\n"
+"  PNG files to copy into the assembly and time.  Invalid files are skipped\n"
+"  with appropriate error messages.  If no files are given the list of files\n"
+"  is read from stdin with each file name terminated by a newline\n"
+"Output:\n"
+"  For --assemble the output is the name of the assembly file followed by the\n"
+"  count of the files it contains; the arguments for --dissemble.  Otherwise\n"
+"  the output is the total decode time in seconds.\n");
+
+   exit(99);
 }
 
 int main(int argc, char **argv)
 {
    int ok = 0;
-   FILE *fp = tmpfile();
+   int err = 0;
+   int nfiles = 0;
+   int transforms = -1; /* by row */
+   const char *assembly = NULL;
+   FILE *fp;
+
+   if (argc > 2 && strcmp(argv[1], "--assemble") == 0)
+   {
+      /* Just build the test file, argv[2] is the file name. */
+      assembly = argv[2];
+      fp = fopen(assembly, "wb");
+      if (fp == NULL)
+      {
+         perror(assembly);
+         fprintf(stderr, "timepng --assemble %s: could not open for write\n",
+               assembly);
+         usage(NULL);
+      }
+
+      argv += 2;
+      argc -= 2;
+   }
 
-   if (fp != NULL)
+   else if (argc > 3 && strcmp(argv[1], "--dissemble") == 0)
    {
-      int err = 0;
-      int nfiles = 0;
+      fp = fopen(argv[2], "rb");
 
-      if (argc > 1)
+      if (fp == NULL)
       {
-         int i;
+         perror(argv[2]);
+         fprintf(stderr, "timepng --dissemble %s: could not open for read\n",
+               argv[2]);
+         usage(NULL);
+      }
 
-         for (i=1; i<argc; ++i)
-         {
-            if (add_one_file(fp, argv[i]))
-               ++nfiles;
+      nfiles = atoi(argv[3]);
+      if (nfiles <= 0)
+      {
+         fprintf(stderr,
+               "timepng --dissemble <file> <count>: %s is not a count\n",
+               argv[3]);
+         exit(99);
+      }
+#ifdef __COVERITY__
+      else
+      {
+         nfiles &= PNG_UINT_31_MAX;
+      }
+#endif
 
-            else
-            {
-               err = 1;
-               break;
-            }
-         }
+      argv += 3;
+      argc -= 3;
+   }
+
+   else /* Else use a temporary file */
+   {
+#ifndef __COVERITY__
+      fp = tmpfile();
+#else
+      /* Experimental. Coverity says tmpfile() is insecure because it
+       * generates predictable names.
+       *
+       * It is possible to satisfy Coverity by using mkstemp(); however,
+       * any platform supporting mkstemp() undoubtedly has a secure tmpfile()
+       * implementation as well, and doesn't need the fix.  Note that
+       * the fix won't work on platforms that don't support mkstemp().
+       *
+       * https://www.securecoding.cert.org/confluence/display/c/
+       * FIO21-C.+Do+not+create+temporary+files+in+shared+directories
+       * says that most historic implementations of tmpfile() provide
+       * only a limited number of possible temporary file names
+       * (usually 26) before file names are recycled. That article also
+       * provides a secure solution that unfortunately depends upon mkstemp().
+       */
+      char tmpfile[] = "timepng-XXXXXX";
+      int filedes;
+      umask(0177);
+      filedes = mkstemp(tmpfile);
+      if (filedes < 0)
+        fp = NULL;
+      else
+      {
+        fp = fdopen(filedes,"w+");
+        /* Hide the filename immediately and ensure that the file does
+         * not exist after the program ends
+         */
+        (void) unlink(tmpfile);
       }
+#endif
+
+      if (fp == NULL)
+      {
+         perror("tmpfile");
+         fprintf(stderr, "timepng: could not open the temporary file\n");
+         exit(1); /* not a user error */
+      }
+   }
+
+   /* Handle the transforms: */
+   while (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-')
+   {
+      const char *opt = *++argv + 2;
+
+      --argc;
+
+      /* Transforms turn on the by-image processing and maybe set some
+       * transforms:
+       */
+      if (transforms == -1)
+         transforms = PNG_TRANSFORM_IDENTITY;
+
+      if (strcmp(opt, "by-image") == 0)
+      {
+         /* handled above */
+      }
+
+#        define OPT(name) else if (strcmp(opt, #name) == 0)\
+         transforms |= PNG_TRANSFORM_ ## name
+
+      OPT(STRIP_16);
+      OPT(STRIP_ALPHA);
+      OPT(PACKING);
+      OPT(PACKSWAP);
+      OPT(EXPAND);
+      OPT(INVERT_MONO);
+      OPT(SHIFT);
+      OPT(BGR);
+      OPT(SWAP_ALPHA);
+      OPT(SWAP_ENDIAN);
+      OPT(INVERT_ALPHA);
+      OPT(STRIP_FILLER);
+      OPT(STRIP_FILLER_BEFORE);
+      OPT(STRIP_FILLER_AFTER);
+      OPT(GRAY_TO_RGB);
+      OPT(EXPAND_16);
+      OPT(SCALE_16);
 
       else
       {
-         char filename[FILENAME_MAX+1];
+         fprintf(stderr, "timepng %s: unrecognized transform\n", opt);
+         usage(fp);
+      }
+   }
+
+   /* Handle the files: */
+   if (argc > 1 && nfiles > 0)
+      usage(fp); /* Additional files not valid with --dissemble */
+
+   else if (argc > 1)
+   {
+      int i;
 
-         while (fgets(filename, FILENAME_MAX+1, stdin))
+      for (i=1; i<argc; ++i)
+      {
+         if (nfiles == INT_MAX)
          {
-            size_t len = strlen(filename);
+            fprintf(stderr, "%s: skipped, too many files\n", argv[i]);
+            break;
+         }
 
-            if (filename[len-1] == '\n')
-            {
-               filename[len-1] = 0;
-               if (add_one_file(fp, filename))
-                  ++nfiles;
-
-               else
-               {
-                  err = 1;
-                  break;
-               }
-            }
+         else if (add_one_file(fp, argv[i]))
+            ++nfiles;
+      }
+   }
 
-            else
+   else if (nfiles == 0) /* Read from stdin withoout --dissemble */
+   {
+      char filename[FILENAME_MAX+1];
+
+      while (fgets(filename, FILENAME_MAX+1, stdin))
+      {
+         size_t len = strlen(filename);
+
+         if (filename[len-1] == '\n')
+         {
+            filename[len-1] = 0;
+            if (nfiles == INT_MAX)
             {
-               fprintf(stderr, "timepng: truncated file name ...%s\n",
-                  filename+len-32);
-               err = 1;
+               fprintf(stderr, "%s: skipped, too many files\n", filename);
                break;
             }
+
+            else if (add_one_file(fp, filename))
+               ++nfiles;
          }
 
-         if (ferror(stdin))
+         else
          {
-            fprintf(stderr, "timepng: stdin: read error\n");
+            fprintf(stderr, "timepng: file name too long: ...%s\n",
+               filename+len-32);
             err = 1;
+            break;
          }
       }
 
-      if (!err)
+      if (ferror(stdin))
+      {
+         fprintf(stderr, "timepng: stdin: read error\n");
+         err = 1;
+      }
+   }
+
+   /* Perform the test, or produce the --assemble output: */
+   if (!err)
+   {
+      if (nfiles > 0)
       {
-         if (nfiles > 0)
-            ok = perform_one_test(fp, nfiles);
+         if (assembly != NULL)
+         {
+            if (fflush(fp) && !ferror(fp) && fclose(fp))
+            {
+               perror(assembly);
+               fprintf(stderr, "%s: close failed\n", assembly);
+            }
+
+            else
+            {
+               printf("%s %d\n", assembly, nfiles);
+               fflush(stdout);
+               ok = !ferror(stdout);
+            }
+         }
 
          else
-            fprintf(stderr, "usage: timepng {files} or ls files | timepng\n");
+         {
+            ok = perform_one_test(fp, nfiles, transforms);
+            (void)fclose(fp);
+         }
       }
 
-      (void)fclose(fp);
+      else
+         usage(fp);
    }
 
    else
-      fprintf(stderr, "timepng: could not open temporary file\n");
+      (void)fclose(fp);
 
    /* Exit code 0 on success. */
    return ok == 0;
 }
+#else /* !sufficient support */
+int main(void) { return 77; }
+#endif /* !sufficient support */
diff --git a/contrib/mips-msa/README b/contrib/mips-msa/README
new file mode 100644 (file)
index 0000000..10acc93
--- /dev/null
@@ -0,0 +1,83 @@
+OPERATING SYSTEM SPECIFIC MIPS MSA DETECTION
+--------------------------------------------
+
+Detection of the ability to execute MIPS MSA on an MIPS processor requires
+operating system support.  (The information is not available in user mode.)
+
+HOW TO USE THIS
+---------------
+
+This directory contains C code fragments that can be included in mips/mips_init.c
+by setting the macro PNG_MIPS_MSA_FILE to the file name in "" or <> at build
+time.  This setting is not recorded in pnglibconf.h and can be changed simply by
+rebuilding mips/msa_init.o with the required macro definition.
+
+For any of this code to be used the MIPS MSA code must be enabled and run time
+checks must be supported.  I.e.:
+
+#if PNG_MIPS_MSA_OPT > 0
+#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
+
+This is done in a 'configure' build by passing configure the argument:
+
+   --enable-mips-msa=check
+
+Apart from the basic Linux implementation in contrib/mips-msa/linux.c this code
+is unsupported.  That means that it is not even compiled on a regular basis and
+may be broken in any given minor release.
+
+FILE FORMAT
+-----------
+
+Each file documents its testing status as of the last time it was tested (which
+may have been a long time ago):
+
+STATUS: one of:
+   SUPPORTED: This indicates that the file is included in the regularly
+         performed test builds and bugs are fixed when discovered.
+   COMPILED: This indicates that the code did compile at least once.  See the
+         more detailed description for the extent to which the result was
+         successful.
+   TESTED: This means the code was fully compiled into the libpng test programs
+         and these were run at least once.
+
+BUG REPORTS: an email address to which to send reports of problems
+
+The file is a fragment of C code. It should not define any 'extern' symbols;
+everything should be static.  It must define the function:
+
+static int png_have_msa(png_structp png_ptr);
+
+That function must return 1 if MIPS MSA instructions are supported, 0 if not.
+It must not execute png_error unless it detects a bug.  A png_error will prevent
+the reading of the PNG and in the future, writing too.
+
+BUG REPORTS
+-----------
+
+If you mail a bug report for any file that is not SUPPORTED there may only be
+limited response.  Consider fixing it and sending a patch to fix the problem -
+this is more likely to result in action.
+
+CONTRIBUTIONS
+-------------
+
+You may send contributions of new implementations to
+png-mng-implement@sourceforge.net.  Please write code in strict C90 C where
+possible.  Obviously OS dependencies are to be expected.  If you submit code you
+must have the authors permission and it must have a license that is acceptable
+to the current maintainer; in particular that license must permit modification
+and redistribution.
+
+Please try to make the contribution a single file and give the file a clear and
+unambiguous name that identifies the target OS.  If multiple files really are
+required put them all in a sub-directory.
+
+You must also be prepared to handle bug reports from users of the code, either
+by joining the png-mng-implement mailing list or by providing an email for the
+"BUG REPORTS" entry or both.  Please make sure that the header of the file
+contains the STATUS and BUG REPORTS fields as above.
+
+Please list the OS requirements as precisely as possible.  Ideally you should
+also list the environment in which the code has been tested and certainly list
+any environments where you suspect it might not work.
diff --git a/contrib/mips-msa/linux.c b/contrib/mips-msa/linux.c
new file mode 100644 (file)
index 0000000..140215c
--- /dev/null
@@ -0,0 +1,64 @@
+/* contrib/mips-msa/linux.c
+ *
+ * Copyright (c) 2016 Glenn Randers-Pehrson
+ * Written by Mandar Sahastrabuddhe, 2016.
+ * Last changed in libpng 1.6.25beta03 [August 29, 2016]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * SEE contrib/mips-msa/README before reporting bugs
+ *
+ * STATUS: SUPPORTED
+ * BUG REPORTS: png-mng-implement@sourceforge.net
+ *
+ * png_have_msa implemented for Linux by reading the widely available
+ * pseudo-file /proc/cpuinfo.
+ *
+ * This code is strict ANSI-C and is probably moderately portable; it does
+ * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static int
+png_have_msa(png_structp png_ptr)
+{
+   FILE *f = fopen("/proc/cpuinfo", "rb");
+
+   char *string = "msa";
+   char word[10];
+
+   if (f != NULL)
+   {
+      while(!feof(f))
+      {
+         int ch = fgetc(f);
+         static int i = 0;
+
+         while(!(ch <= 32))
+         {
+            word[i++] = ch;
+            ch = fgetc(f);
+         }
+
+         int val = strcmp(string, word);
+
+         if (val == 0)
+            return 1;
+
+         i = 0;
+         memset(word, 0, 10);
+      }
+
+      fclose(f);
+   }
+#ifdef PNG_WARNINGS_SUPPORTED
+   else
+      png_warning(png_ptr, "/proc/cpuinfo open failed");
+#endif
+   return 0;
+}
diff --git a/contrib/oss-fuzz/Dockerfile b/contrib/oss-fuzz/Dockerfile
new file mode 100644 (file)
index 0000000..f5bc1a9
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright 2016 Google Inc.
+#
+# Licensed 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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER glennrp@gmail.com
+RUN apt-get update && \
+    apt-get install -y make autoconf automake libtool
+
+RUN git clone --depth 1 https://github.com/madler/zlib.git
+RUN git clone --depth 1 https://github.com/glennrp/libpng.git
+RUN cp libpng/contrib/oss-fuzz/build.sh $SRC
+WORKDIR libpng
diff --git a/contrib/oss-fuzz/README.txt b/contrib/oss-fuzz/README.txt
new file mode 100644 (file)
index 0000000..3b3656f
--- /dev/null
@@ -0,0 +1,37 @@
+Last changed in libpng 1.6.33 [September 28, 2017]
+Copyright (c) 2017 Glenn Randers-Pehrson
+
+This code is released under the libpng license.
+For conditions of distribution and use, see the disclaimer
+and license in png.h
+
+Files in this directory are used by the oss-fuzz project
+(https://github.com/google/oss-fuzz/tree/master/projects/libpng).
+for "fuzzing" libpng.
+
+They were licensed by Google Inc, using the BSD-like Chromium license,
+which may be found at https://cs.chromium.org/chromium/src/LICENSE, or, if
+noted in the source, under the Apache-2.0 license, which may
+be found at http://www.apache.org/licenses/LICENSE-2.0 .
+If they have been modified, the derivatives are copyright Glenn Randers-Pehrson
+and are released under the same licenses as the originals.  Several of
+the original files (libpng_read_fuzzer.options, png.dict, project.yaml)
+had no licensing information; we assumed that these were under the Chromium
+license. Any new files are released under the libpng license (see png.h).
+
+The files are
+                            Original
+ Filename                   or derived   Copyright          License
+ =========================  ==========   ================   ==========
+ Dockerfile*                derived      2017, Glenn R-P    Apache 2.0
+ build.sh                   derived      2017, Glenn R-P    Apache 2.0
+ libpng_read_fuzzer.cc      derived      2017, Glenn R-P    Chromium
+ libpng_read_fuzzer.options original     2015, Chrome Devs  Chromium
+ png.dict                   original     2015, Chrome Devs  Chromium
+ README.txt (this file)     original     2017, Glenn R-P    libpng
+
+ * Dockerfile is a copy of the file used by oss-fuzz. build.sh,
+   png.dict and libpng_read_fuzzer.* are the actual files used by oss-fuzz,
+   which retrieves them from the libpng repository at Github.
+
+To do: exercise the progressive reader and the png encoder.
diff --git a/contrib/oss-fuzz/build.sh b/contrib/oss-fuzz/build.sh
new file mode 100755 (executable)
index 0000000..f9e1b07
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/bash -eu
+# Copyright 2017-2018 Glenn Randers-Pehrson
+# Copyright 2016 Google Inc.
+#
+# Licensed 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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Last changed in libpng 1.6.35 [July 15, 2018]
+#
+# Revisions by Glenn Randers-Pehrson, 2017:
+# 1. Build only the library, not the tools (changed "make -j$(nproc) all" to
+#     "make -j$(nproc) libpng16.la").
+# 2. Disabled WARNING and WRITE options in pnglibconf.dfa.
+# 3. Build zlib alongside libpng
+################################################################################
+
+# Disable logging via library build configuration control.
+cat scripts/pnglibconf.dfa | \
+  sed -e "s/option STDIO/option STDIO disabled/" \
+      -e "s/option WARNING /option WARNING disabled/" \
+      -e "s/option WRITE enables WRITE_INT_FUNCTIONS/option WRITE disabled/" \
+> scripts/pnglibconf.dfa.temp
+mv scripts/pnglibconf.dfa.temp scripts/pnglibconf.dfa
+
+# build the libpng library.
+autoreconf -f -i
+./configure --with-libpng-prefix=OSS_FUZZ_
+make -j$(nproc) clean
+make -j$(nproc) libpng16.la
+
+# build libpng_read_fuzzer.
+$CXX $CXXFLAGS -std=c++11 -I. \
+     $SRC/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc \
+     -o $OUT/libpng_read_fuzzer \
+     -lFuzzingEngine .libs/libpng16.a -lz
+
+# add seed corpus.
+find $SRC/libpng -name "*.png" | grep -v crashers | \
+     xargs zip $OUT/libpng_read_fuzzer_seed_corpus.zip
+
+cp $SRC/libpng/contrib/oss-fuzz/*.dict \
+     $SRC/libpng/contrib/oss-fuzz/*.options $OUT/
diff --git a/contrib/oss-fuzz/libpng_read_fuzzer.cc b/contrib/oss-fuzz/libpng_read_fuzzer.cc
new file mode 100644 (file)
index 0000000..7b30550
--- /dev/null
@@ -0,0 +1,190 @@
+
+// libpng_read_fuzzer.cc
+// Copyright 2017-2018 Glenn Randers-Pehrson
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that may
+// be found in the LICENSE file https://cs.chromium.org/chromium/src/LICENSE
+
+// Last changed in libpng 1.6.35 [July 15, 2018]
+
+// The modifications in 2017 by Glenn Randers-Pehrson include
+// 1. addition of a PNG_CLEANUP macro,
+// 2. setting the option to ignore ADLER32 checksums,
+// 3. adding "#include <string.h>" which is needed on some platforms
+//    to provide memcpy().
+// 4. adding read_end_info() and creating an end_info structure.
+// 5. adding calls to png_set_*() transforms commonly used by browsers.
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <vector>
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#define PNG_CLEANUP \
+  if(png_handler.png_ptr) \
+  { \
+    if (png_handler.row_ptr) \
+      png_free(png_handler.png_ptr, png_handler.row_ptr); \
+    if (png_handler.end_info_ptr) \
+      png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\
+        &png_handler.end_info_ptr); \
+    else if (png_handler.info_ptr) \
+      png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\
+        nullptr); \
+    else \
+      png_destroy_read_struct(&png_handler.png_ptr, nullptr, nullptr); \
+    png_handler.png_ptr = nullptr; \
+    png_handler.row_ptr = nullptr; \
+    png_handler.info_ptr = nullptr; \
+    png_handler.end_info_ptr = nullptr; \
+  }
+
+struct BufState {
+  const uint8_t* data;
+  size_t bytes_left;
+};
+
+struct PngObjectHandler {
+  png_infop info_ptr = nullptr;
+  png_structp png_ptr = nullptr;
+  png_infop end_info_ptr = nullptr;
+  png_voidp row_ptr = nullptr;
+  BufState* buf_state = nullptr;
+
+  ~PngObjectHandler() {
+    if (row_ptr)
+      png_free(png_ptr, row_ptr);
+    if (end_info_ptr)
+      png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
+    else if (info_ptr) 
+      png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
+    else
+      png_destroy_read_struct(&png_ptr, nullptr, nullptr);
+    delete buf_state;
+  }
+};
+
+void user_read_data(png_structp png_ptr, png_bytep data, size_t length) {
+  BufState* buf_state = static_cast<BufState*>(png_get_io_ptr(png_ptr));
+  if (length > buf_state->bytes_left) {
+    png_error(png_ptr, "read error");
+  }
+  memcpy(data, buf_state->data, length);
+  buf_state->bytes_left -= length;
+  buf_state->data += length;
+}
+
+static const int kPngHeaderSize = 8;
+
+// Entry point for LibFuzzer.
+// Roughly follows the libpng book example:
+// http://www.libpng.org/pub/png/book/chapter13.html
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  if (size < kPngHeaderSize) {
+    return 0;
+  }
+
+  std::vector<unsigned char> v(data, data + size);
+  if (png_sig_cmp(v.data(), 0, kPngHeaderSize)) {
+    // not a PNG.
+    return 0;
+  }
+
+  PngObjectHandler png_handler;
+  png_handler.png_ptr = nullptr;
+  png_handler.row_ptr = nullptr;
+  png_handler.info_ptr = nullptr;
+  png_handler.end_info_ptr = nullptr;
+
+  png_handler.png_ptr = png_create_read_struct
+    (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+  if (!png_handler.png_ptr) {
+    return 0;
+  }
+
+  png_handler.info_ptr = png_create_info_struct(png_handler.png_ptr);
+  if (!png_handler.info_ptr) {
+    PNG_CLEANUP
+    return 0;
+  }
+
+  png_handler.end_info_ptr = png_create_info_struct(png_handler.png_ptr);
+  if (!png_handler.end_info_ptr) {
+    PNG_CLEANUP
+    return 0;
+  }
+
+  png_set_crc_action(png_handler.png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
+#ifdef PNG_IGNORE_ADLER32
+  png_set_option(png_handler.png_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
+#endif
+
+  // Setting up reading from buffer.
+  png_handler.buf_state = new BufState();
+  png_handler.buf_state->data = data + kPngHeaderSize;
+  png_handler.buf_state->bytes_left = size - kPngHeaderSize;
+  png_set_read_fn(png_handler.png_ptr, png_handler.buf_state, user_read_data);
+  png_set_sig_bytes(png_handler.png_ptr, kPngHeaderSize);
+
+  if (setjmp(png_jmpbuf(png_handler.png_ptr))) {
+    PNG_CLEANUP
+    return 0;
+  }
+
+  // Reading.
+  png_read_info(png_handler.png_ptr, png_handler.info_ptr);
+
+  // reset error handler to put png_deleter into scope.
+  if (setjmp(png_jmpbuf(png_handler.png_ptr))) {
+    PNG_CLEANUP
+    return 0;
+  }
+
+  png_uint_32 width, height;
+  int bit_depth, color_type, interlace_type, compression_type;
+  int filter_type;
+
+  if (!png_get_IHDR(png_handler.png_ptr, png_handler.info_ptr, &width,
+                    &height, &bit_depth, &color_type, &interlace_type,
+                    &compression_type, &filter_type)) {
+    PNG_CLEANUP
+    return 0;
+  }
+
+  // This is going to be too slow.
+  if (width && height > 100000000 / width) {
+    PNG_CLEANUP
+    return 0;
+  }
+
+  // Set several transforms that browsers typically use:
+  png_set_gray_to_rgb(png_handler.png_ptr);
+  png_set_expand(png_handler.png_ptr);
+  png_set_packing(png_handler.png_ptr);
+  png_set_scale_16(png_handler.png_ptr);
+  png_set_tRNS_to_alpha(png_handler.png_ptr);
+
+  int passes = png_set_interlace_handling(png_handler.png_ptr);
+
+  png_read_update_info(png_handler.png_ptr, png_handler.info_ptr);
+
+  png_handler.row_ptr = png_malloc(
+      png_handler.png_ptr, png_get_rowbytes(png_handler.png_ptr,
+                                            png_handler.info_ptr));
+
+  for (int pass = 0; pass < passes; ++pass) {
+    for (png_uint_32 y = 0; y < height; ++y) {
+      png_read_row(png_handler.png_ptr,
+                   static_cast<png_bytep>(png_handler.row_ptr), nullptr);
+    }
+  }
+
+  png_read_end(png_handler.png_ptr, png_handler.end_info_ptr);
+
+  PNG_CLEANUP
+  return 0;
+}
diff --git a/contrib/oss-fuzz/libpng_read_fuzzer.options b/contrib/oss-fuzz/libpng_read_fuzzer.options
new file mode 100644 (file)
index 0000000..2005291
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+dict = png.dict
diff --git a/contrib/oss-fuzz/png.dict b/contrib/oss-fuzz/png.dict
new file mode 100644 (file)
index 0000000..3a8a113
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# AFL dictionary for PNG images
+# -----------------------------
+#
+# Just the basic, standard-originating sections; does not include vendor
+# extensions.
+#
+# Created by Michal Zalewski <lcamtuf@google.com>
+#
+
+header_png="\x89PNG\x0d\x0a\x1a\x0a"
+
+section_IDAT="IDAT"
+section_IEND="IEND"
+section_IHDR="IHDR"
+section_PLTE="PLTE"
+section_bKGD="bKGD"
+section_cHRM="cHRM"
+section_eXIf="eXIf"
+section_fRAc="fRAc"
+section_gAMA="gAMA"
+section_gIFg="gIFg"
+section_gIFt="gIFt"
+section_gIFx="gIFx"
+section_hIST="hIST"
+section_iCCP="iCCP"
+section_iTXt="iTXt"
+section_oFFs="oFFs"
+section_pCAL="pCAL"
+section_pHYs="pHYs"
+section_sBIT="sBIT"
+section_sCAL="sCAL"
+section_sPLT="sPLT"
+section_sRGB="sRGB"
+section_sTER="sTER"
+section_tEXt="tEXt"
+section_tIME="tIME"
+section_tRNS="tRNS"
+section_zTXt="zTXt"
index bbe7407..23614a8 100644 (file)
@@ -17,7 +17,7 @@ express or implied warranty.
 Some history
 ------------
 Soon after the creation of PNG in 1995, the need was felt for a set of
-pnmtopng / pngtopnm utilities. Independantly Alexander Lehmann and I
+pnmtopng / pngtopnm utilities. Independently Alexander Lehmann and I
 (Willem van Schaik) started such a project. Luckily we discovered this
 and merged the two together into pnmtopng.tar.gz, which is available
 from a/o ftp://ftp.simplesystems.org/pub/libpng/png/.
@@ -146,7 +146,7 @@ The Turbo bug
 The end
 -------
 Willem van Schaik
-mailto:willem@schaik.com
+mailto:willem at schaik.com
 http://www.schaik.com/png/
 -------
 Oct 1999
index 449cf36..a2798c3 100755 (executable)
@@ -7,7 +7,7 @@ png2pnm.exe -noraw ..\pngsuite\basn0g16.png basn0g16.pgm
 REM -- full-color
 png2pnm.exe -noraw ..\pngsuite\basn2c08.png basn2c08.ppm
 png2pnm.exe -noraw ..\pngsuite\basn2c16.png basn2c16.ppm
-REM -- palletted
+REM -- paletted
 png2pnm.exe -noraw ..\pngsuite\basn3p01.png basn3p01.ppm
 png2pnm.exe -noraw ..\pngsuite\basn3p02.png basn3p02.ppm
 png2pnm.exe -noraw ..\pngsuite\basn3p04.png basn3p04.ppm
@@ -27,7 +27,7 @@ png2pnm.exe -raw ..\pngsuite\basn0g16.png rawn0g16.pgm
 REM -- full-color
 png2pnm.exe -raw ..\pngsuite\basn2c08.png rawn2c08.ppm
 png2pnm.exe -raw ..\pngsuite\basn2c16.png rawn2c16.ppm
-REM -- palletted
+REM -- paletted
 png2pnm.exe -raw ..\pngsuite\basn3p01.png rawn3p01.ppm
 png2pnm.exe -raw ..\pngsuite\basn3p02.png rawn3p02.ppm
 png2pnm.exe -raw ..\pngsuite\basn3p04.png rawn3p04.ppm
index f68d7ff..1420a78 100644 (file)
@@ -1,8 +1,12 @@
 /*
  *  png2pnm.c --- conversion from PNG-file to PGM/PPM-file
- *  copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
+ *  copyright (C) 1999,2017 by Willem van Schaik <willem at schaik.com>
  *
  *  version 1.0 - 1999.10.15 - First version.
+ *          1.1 - 2017.04.22 - Add buffer-size check (Glenn Randers-Pehrson)
+ *          1.2 - 2017.08.24 - Fix potential overflow in buffer-size check
+ *                             (Glenn Randers-Pehrson)
+ *          1.3 - 2017.08.28 - Add PNGMINUS_UNUSED (Christian Hesse)
  *
  *  Permission to use, copy, modify, and distribute this software and
  *  its documentation for any purpose and without fee is hereby granted,
@@ -41,6 +45,7 @@
 #define PNG_DEBUG 0
 #endif
 
+
 #include "png.h"
 
 /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
 #  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
 #endif
 
+#ifndef PNGMINUS_UNUSED
+/* Unused formal parameter warnings are silenced using the following macro
+ * which is expected to have no bad effects on performance (optimizing
+ * compilers will probably remove it entirely).
+ */
+#  define PNGMINUS_UNUSED(param) (void)param
+#endif
+
 /* function prototypes */
 
 int  main (int argc, char *argv[]);
@@ -320,14 +333,21 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
   /* row_bytes is the width x number of channels x (bit-depth / 8) */
   row_bytes = png_get_rowbytes (png_ptr, info_ptr);
 
+  if ((row_bytes == 0 || (size_t)height > ((size_t)(-1))/(size_t)row_bytes))
+  {
+    /* too big */ 
+    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+    return FALSE;
+  }
   if ((png_pixels = (png_byte *)
-     malloc (row_bytes * height * sizeof (png_byte))) == NULL) {
+     malloc ((size_t)row_bytes * (size_t)height * sizeof (png_byte))) == NULL)
+  {
     png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
     return FALSE;
   }
 
   if ((row_pointers = (png_byte **)
-     malloc (height * sizeof (png_bytep))) == NULL)
+     malloc ((size_t)height * sizeof (png_bytep))) == NULL)
   {
     png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
     free (png_pixels);
@@ -408,7 +428,8 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
           if (raw)
             fputc ((int) *pix_ptr++ , alpha_file);
           else
-            if (bit_depth == 16){
+            if (bit_depth == 16)
+            {
               dep_16 = (long) *pix_ptr++;
               fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++);
             }
@@ -432,6 +453,7 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
   if (png_pixels != (unsigned char*) NULL)
     free (png_pixels);
 
+  PNGMINUS_UNUSED(raw); /* to quiet a Coverity defect */
   return TRUE;
 
 } /* end of source */
index b1c0537..756126a 100755 (executable)
@@ -8,7 +8,7 @@
 # -- full-color
 ./png2pnm -noraw ../pngsuite/basn2c08.png basn2c08.ppm
 ./png2pnm -noraw ../pngsuite/basn2c16.png basn2c16.ppm
-# -- palletted
+# -- paletted
 ./png2pnm -noraw ../pngsuite/basn3p01.png basn3p01.ppm
 ./png2pnm -noraw ../pngsuite/basn3p02.png basn3p02.ppm
 ./png2pnm -noraw ../pngsuite/basn3p04.png basn3p04.ppm
@@ -28,7 +28,7 @@
 # -- full-color
 ./png2pnm -raw ../pngsuite/basn2c08.png rawn2c08.ppm
 ./png2pnm -raw ../pngsuite/basn2c16.png rawn2c16.ppm
-# -- palletted
+# -- paletted
 ./png2pnm -raw ../pngsuite/basn3p01.png rawn3p01.ppm
 ./png2pnm -raw ../pngsuite/basn3p02.png rawn3p02.ppm
 ./png2pnm -raw ../pngsuite/basn3p04.png rawn3p04.ppm
index f756cb8..c02b80b 100755 (executable)
@@ -7,7 +7,7 @@ pnm2png.exe basn0g16.pgm basn0g16.png
 REM -- full-color
 pnm2png.exe basn2c08.ppm basn2c08.png
 pnm2png.exe basn2c16.ppm basn2c16.png
-REM -- palletted
+REM -- paletted
 pnm2png.exe basn3p01.ppm basn3p01.png
 pnm2png.exe basn3p02.ppm basn3p02.png
 pnm2png.exe basn3p04.ppm basn3p04.png
@@ -27,7 +27,7 @@ pnm2png.exe rawn0g16.pgm rawn0g16.png
 REM -- full-color
 pnm2png.exe rawn2c08.ppm rawn2c08.png
 pnm2png.exe rawn2c16.ppm rawn2c16.png
-REM -- palletted
+REM -- paletted
 pnm2png.exe rawn3p01.ppm rawn3p01.png
 pnm2png.exe rawn3p02.ppm rawn3p02.png
 pnm2png.exe rawn3p04.ppm rawn3p04.png
index 8fa64cd..0d2caef 100644 (file)
@@ -1,9 +1,13 @@
 /*
  *  pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file
- *  copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
+ *  copyright (C) 1999,2015,2017 by Willem van Schaik <willem at schaik.com>
  *
  *  version 1.0 - 1999.10.15 - First version.
  *  version 1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson)
+ *  version 1.2 - 2017.04.22 - Add buffer-size check
+ *          1.3 - 2017.08.24 - Fix potential overflow in buffer-size check
+ *                             (Glenn Randers-Pehrson)
+ *          1.4 - 2017.08.28 - Add PNGMINUS_UNUSED (Christian Hesse)
  *
  *  Permission to use, copy, modify, and distribute this software and
  *  its documentation for any purpose and without fee is hereby granted,
 #  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
 #endif
 
+#ifndef PNGMINUS_UNUSED
+/* Unused formal parameter warnings are silenced using the following macro
+ * which is expected to have no bad effects on performance (optimizing
+ * compilers will probably remove it entirely).
+ */
+#  define PNGMINUS_UNUSED(param) (void)param
+#endif
+
+
 /* function prototypes */
 
 int  main (int argc, char *argv[]);
@@ -370,11 +383,16 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
     row_bytes = (width * channels * bit_depth + 7) / 8;
   else
 #endif
-    /* row_bytes is the width x number of channels x (bit-depth / 8) */
+  /* row_bytes is the width x number of channels x (bit-depth / 8) */
     row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
 
+  if ((row_bytes == 0 || (size_t)height > ((size_t)(-1))/(size_t)row_bytes))
+  {
+    /* too big */ 
+    return FALSE;
+  }
   if ((png_pixels = (png_byte *)
-     malloc (row_bytes * height * sizeof (png_byte))) == NULL)
+     malloc ((size_t)row_bytes * (size_t)height * sizeof (png_byte))) == NULL)
     return FALSE;
 
   /* read data from PNM file */
@@ -383,7 +401,8 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
   for (row = 0; row < (int) height; row++)
   {
 #if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-    if (packed_bitmap) {
+    if (packed_bitmap)
+    {
       for (i = 0; i < (int) row_bytes; i++)
         /* png supports this format natively so no conversion is needed */
         *pix_ptr++ = get_data (pnm_file, 8);
@@ -504,6 +523,8 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace,
   if (png_pixels != (unsigned char*) NULL)
     free (png_pixels);
 
+  PNGMINUS_UNUSED(raw); /* Quiet a Coverity defect */
+
   return TRUE;
 } /* end of pnm2png */
 
@@ -520,7 +541,8 @@ void get_token(FILE *pnm_file, char *token)
   do
   {
     ret = fgetc(pnm_file);
-    if (ret == '#') {
+    if (ret == '#')
+    {
       /* the rest of this line is a comment */
       do
       {
index d79df2f..2ad17a6 100755 (executable)
@@ -8,7 +8,7 @@
 # -- full-color
 ./pnm2png basn2c08.ppm basn2c08.png
 ./pnm2png basn2c16.ppm basn2c16.png
-# -- palletted
+# -- paletted
 ./pnm2png basn3p01.ppm basn3p01.png
 ./pnm2png basn3p02.ppm basn3p02.png
 ./pnm2png basn3p04.ppm basn3p04.png
@@ -28,7 +28,7 @@
 # -- full-color
 ./pnm2png rawn2c08.ppm rawn2c08.png
 ./pnm2png rawn2c16.ppm rawn2c16.png
-# -- palletted
+# -- paletted
 ./pnm2png rawn3p01.ppm rawn3p01.png
 ./pnm2png rawn3p02.ppm rawn3p02.png
 ./pnm2png rawn3p04.ppm rawn3p04.png
index a7fde8f..d236b02 100644 (file)
@@ -16,6 +16,8 @@ chunks, etc.
 The "ft*.png" images are "free/libre" replacements for the transparent
 corresponding t*.png images in the PngSuite.
 
+The "i*.png" images are the same images, but interlaced.
+
 The images in this directory represent the basic PNG color-types:
 grayscale (1-16 bit deep), full color (8 or 16 bit), paletted
 (1-8 bit) and grayscale or color images with alpha channel. You
@@ -101,5 +103,5 @@ Testing basn6a16.png: PASS (1072 zero samples)
 libpng passes test
 
 Willem van Schaik
-<willem@schaik.com>
+<willem at schaik.com>
 October 1999
diff --git a/contrib/pngsuite/bad_interlace_conversions.txt b/contrib/pngsuite/bad_interlace_conversions.txt
new file mode 100644 (file)
index 0000000..8afbde7
--- /dev/null
@@ -0,0 +1,9 @@
+basn0g01.png
+basn0g02.png
+basn0g04.png
+basn3p01.png
+basn3p02.png
+basn3p04.png
+ftbbn0g01.png
+ftbbn0g02.png
+ftbbn0g04.png
diff --git a/contrib/pngsuite/ibasn0g08.png b/contrib/pngsuite/ibasn0g08.png
new file mode 100644 (file)
index 0000000..90b5305
Binary files /dev/null and b/contrib/pngsuite/ibasn0g08.png differ
diff --git a/contrib/pngsuite/ibasn0g16.png b/contrib/pngsuite/ibasn0g16.png
new file mode 100644 (file)
index 0000000..c82f230
Binary files /dev/null and b/contrib/pngsuite/ibasn0g16.png differ
diff --git a/contrib/pngsuite/ibasn2c08.png b/contrib/pngsuite/ibasn2c08.png
new file mode 100644 (file)
index 0000000..05d4688
Binary files /dev/null and b/contrib/pngsuite/ibasn2c08.png differ
diff --git a/contrib/pngsuite/ibasn2c16.png b/contrib/pngsuite/ibasn2c16.png
new file mode 100644 (file)
index 0000000..399f1be
Binary files /dev/null and b/contrib/pngsuite/ibasn2c16.png differ
diff --git a/contrib/pngsuite/ibasn3p08.png b/contrib/pngsuite/ibasn3p08.png
new file mode 100644 (file)
index 0000000..6df8370
Binary files /dev/null and b/contrib/pngsuite/ibasn3p08.png differ
diff --git a/contrib/pngsuite/ibasn4a08.png b/contrib/pngsuite/ibasn4a08.png
new file mode 100644 (file)
index 0000000..bda8e3c
Binary files /dev/null and b/contrib/pngsuite/ibasn4a08.png differ
diff --git a/contrib/pngsuite/ibasn4a16.png b/contrib/pngsuite/ibasn4a16.png
new file mode 100644 (file)
index 0000000..500f912
Binary files /dev/null and b/contrib/pngsuite/ibasn4a16.png differ
diff --git a/contrib/pngsuite/ibasn6a08.png b/contrib/pngsuite/ibasn6a08.png
new file mode 100644 (file)
index 0000000..258f940
Binary files /dev/null and b/contrib/pngsuite/ibasn6a08.png differ
diff --git a/contrib/pngsuite/ibasn6a16.png b/contrib/pngsuite/ibasn6a16.png
new file mode 100644 (file)
index 0000000..e4de69f
Binary files /dev/null and b/contrib/pngsuite/ibasn6a16.png differ
diff --git a/contrib/pngsuite/iftbbn2c16.png b/contrib/pngsuite/iftbbn2c16.png
new file mode 100644 (file)
index 0000000..64a9cdf
Binary files /dev/null and b/contrib/pngsuite/iftbbn2c16.png differ
diff --git a/contrib/pngsuite/iftbbn3p08.png b/contrib/pngsuite/iftbbn3p08.png
new file mode 100644 (file)
index 0000000..47d6eeb
Binary files /dev/null and b/contrib/pngsuite/iftbbn3p08.png differ
diff --git a/contrib/pngsuite/iftbgn2c16.png b/contrib/pngsuite/iftbgn2c16.png
new file mode 100644 (file)
index 0000000..64a9cdf
Binary files /dev/null and b/contrib/pngsuite/iftbgn2c16.png differ
diff --git a/contrib/pngsuite/iftbgn3p08.png b/contrib/pngsuite/iftbgn3p08.png
new file mode 100644 (file)
index 0000000..47d6eeb
Binary files /dev/null and b/contrib/pngsuite/iftbgn3p08.png differ
diff --git a/contrib/pngsuite/iftbrn2c08.png b/contrib/pngsuite/iftbrn2c08.png
new file mode 100644 (file)
index 0000000..08ebbae
Binary files /dev/null and b/contrib/pngsuite/iftbrn2c08.png differ
diff --git a/contrib/pngsuite/iftbwn0g16.png b/contrib/pngsuite/iftbwn0g16.png
new file mode 100644 (file)
index 0000000..4b7537e
Binary files /dev/null and b/contrib/pngsuite/iftbwn0g16.png differ
diff --git a/contrib/pngsuite/iftbwn3p08.png b/contrib/pngsuite/iftbwn3p08.png
new file mode 100644 (file)
index 0000000..47d6eeb
Binary files /dev/null and b/contrib/pngsuite/iftbwn3p08.png differ
diff --git a/contrib/pngsuite/iftbyn3p08.png b/contrib/pngsuite/iftbyn3p08.png
new file mode 100644 (file)
index 0000000..47d6eeb
Binary files /dev/null and b/contrib/pngsuite/iftbyn3p08.png differ
diff --git a/contrib/pngsuite/iftp0n0g08.png b/contrib/pngsuite/iftp0n0g08.png
new file mode 100644 (file)
index 0000000..aa826b8
Binary files /dev/null and b/contrib/pngsuite/iftp0n0g08.png differ
diff --git a/contrib/pngsuite/iftp0n2c08.png b/contrib/pngsuite/iftp0n2c08.png
new file mode 100644 (file)
index 0000000..b12bd0a
Binary files /dev/null and b/contrib/pngsuite/iftp0n2c08.png differ
diff --git a/contrib/pngsuite/iftp0n3p08.png b/contrib/pngsuite/iftp0n3p08.png
new file mode 100644 (file)
index 0000000..37aa0cb
Binary files /dev/null and b/contrib/pngsuite/iftp0n3p08.png differ
diff --git a/contrib/pngsuite/iftp1n3p08.png b/contrib/pngsuite/iftp1n3p08.png
new file mode 100644 (file)
index 0000000..47d6eeb
Binary files /dev/null and b/contrib/pngsuite/iftp1n3p08.png differ
diff --git a/contrib/pngsuite/interlaced/README b/contrib/pngsuite/interlaced/README
new file mode 100644 (file)
index 0000000..f171eee
--- /dev/null
@@ -0,0 +1,2 @@
+
+These images fail the "pngimage-quick" and "pngimage-full" tests.
diff --git a/contrib/pngsuite/interlaced/ibasn0g01.png b/contrib/pngsuite/interlaced/ibasn0g01.png
new file mode 100644 (file)
index 0000000..828fa76
Binary files /dev/null and b/contrib/pngsuite/interlaced/ibasn0g01.png differ
diff --git a/contrib/pngsuite/interlaced/ibasn0g02.png b/contrib/pngsuite/interlaced/ibasn0g02.png
new file mode 100644 (file)
index 0000000..7fc17e3
Binary files /dev/null and b/contrib/pngsuite/interlaced/ibasn0g02.png differ
diff --git a/contrib/pngsuite/interlaced/ibasn0g04.png b/contrib/pngsuite/interlaced/ibasn0g04.png
new file mode 100644 (file)
index 0000000..1beade2
Binary files /dev/null and b/contrib/pngsuite/interlaced/ibasn0g04.png differ
diff --git a/contrib/pngsuite/interlaced/ibasn3p01.png b/contrib/pngsuite/interlaced/ibasn3p01.png
new file mode 100644 (file)
index 0000000..f91e723
Binary files /dev/null and b/contrib/pngsuite/interlaced/ibasn3p01.png differ
diff --git a/contrib/pngsuite/interlaced/ibasn3p02.png b/contrib/pngsuite/interlaced/ibasn3p02.png
new file mode 100644 (file)
index 0000000..0f9ce76
Binary files /dev/null and b/contrib/pngsuite/interlaced/ibasn3p02.png differ
diff --git a/contrib/pngsuite/interlaced/ibasn3p04.png b/contrib/pngsuite/interlaced/ibasn3p04.png
new file mode 100644 (file)
index 0000000..b2ca720
Binary files /dev/null and b/contrib/pngsuite/interlaced/ibasn3p04.png differ
diff --git a/contrib/pngsuite/interlaced/iftbbn0g01.png b/contrib/pngsuite/interlaced/iftbbn0g01.png
new file mode 100644 (file)
index 0000000..6eb27d1
Binary files /dev/null and b/contrib/pngsuite/interlaced/iftbbn0g01.png differ
diff --git a/contrib/pngsuite/interlaced/iftbbn0g02.png b/contrib/pngsuite/interlaced/iftbbn0g02.png
new file mode 100644 (file)
index 0000000..46ba497
Binary files /dev/null and b/contrib/pngsuite/interlaced/iftbbn0g02.png differ
diff --git a/contrib/pngsuite/interlaced/iftbbn0g04.png b/contrib/pngsuite/interlaced/iftbbn0g04.png
new file mode 100644 (file)
index 0000000..e9db0ad
Binary files /dev/null and b/contrib/pngsuite/interlaced/iftbbn0g04.png differ
diff --git a/contrib/powerpc-vsx/README b/contrib/powerpc-vsx/README
new file mode 100644 (file)
index 0000000..4970a52
--- /dev/null
@@ -0,0 +1,81 @@
+OPERATING SYSTEM SPECIFIC POWERPC DETECTION
+--------------------------------------------
+
+Detection of the ability to execute POWERPC on processor requires
+operating system support.  (The information is not available in user mode.)
+
+Currently only this feature is supported only for linux platform.
+
+HOW TO USE THIS
+---------------
+
+This directory contains C code fragments that can be included in powerpc/powerpc_init.c
+by setting the macro PNG_POWERPC_VSX_FILE to the file name in "" or <> at build
+time.  This setting is not recorded in pnglibconf.h and can be changed simply by
+rebuilding arm/arm_init.o with the required macro definition.
+
+For any of this code to be used the POWERPC code must be enabled and run time
+checks must be supported.  I.e.:
+
+#if PNG_POWERPC_VSX_OPT > 0
+#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED
+
+This is done in a 'configure' build by passing configure the argument:
+
+   --enable-powerpc-vsx=check
+
+FILE FORMAT
+-----------
+
+Each file documents its testing status as of the last time it was tested (which
+may have been a long time ago):
+
+STATUS: one of:
+   SUPPORTED: This indicates that the file is included in the regularly
+         performed test builds and bugs are fixed when discovered.
+   COMPILED: This indicates that the code did compile at least once.  See the
+         more detailed description for the extent to which the result was
+         successful.
+   TESTED: This means the code was fully compiled into the libpng test programs
+         and these were run at least once.
+
+BUG REPORTS: an email address to which to send reports of problems
+
+The file is a fragment of C code. It should not define any 'extern' symbols;
+everything should be static.  It must define the function:
+
+static int png_have_vsx(png_structp png_ptr);
+
+That function must return 1 if POWERPC_VSX instructions are supported, 0 if not.
+It must not execute png_error unless it detects a bug.  A png_error will prevent
+the reading of the PNG and in the future, writing too.
+
+BUG REPORTS
+-----------
+
+If you mail a bug report for any file that is not SUPPORTED there may only be
+limited response.  Consider fixing it and sending a patch to fix the problem -
+this is more likely to result in action.
+
+CONTRIBUTIONS
+-------------
+
+You may send contributions of new implementations to
+png-mng-implement@sourceforge.net.  Please write code in strict C90 C where
+possible.  Obviously OS dependencies are to be expected.  If you submit code you
+must have the authors permission and it must have a license that is acceptable
+to the current maintainer; in particular that license must permit modification
+and redistribution.
+
+Please try to make the contribution a single file and give the file a clear and
+unambiguous name that identifies the target OS.  If multiple files really are
+required put them all in a sub-directory.
+
+You must also be prepared to handle bug reports from users of the code, either
+by joining the png-mng-implement mailing list or by providing an email for the
+"BUG REPORTS" entry or both.  Please make sure that the header of the file
+contains the STATUS and BUG REPORTS fields as above.
+
+Please list the OS requirements as precisely as possible.  Ideally you should
+also list the environment in which the code has been tested and certainly list
+any environments where you suspect it might not work.
diff --git a/contrib/powerpc-vsx/linux.c b/contrib/powerpc-vsx/linux.c
new file mode 100644 (file)
index 0000000..32ed9d7
--- /dev/null
@@ -0,0 +1,57 @@
+/* contrib/powerpc-vsx/linux.c
+ *
+ * Copyright (c) 2017 Glenn Randers-Pehrson
+ * Written by Vadim Barkov, 2017.
+ * Last changed in libpng 1.6.29 [March 16, 2017]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * STATUS: TESTED
+ * BUG REPORTS: png-mng-implement@sourceforge.net
+ *
+ * png_have_vsx implemented for Linux by reading the widely available
+ * pseudo-file /proc/cpuinfo. 
+ *
+ * This code is strict ANSI-C and is probably moderately portable; it does
+ * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "png.h"
+
+#ifndef MAXLINE
+#  define MAXLINE 1024
+#endif
+
+static int
+png_have_vsx(png_structp png_ptr)
+{
+   FILE *f;
+
+   const char *string = "altivec supported";
+   char input[MAXLINE];
+   char *token = NULL;
+
+   PNG_UNUSED(png_ptr)
+
+   f = fopen("/proc/cpuinfo", "r");
+   if (f != NULL)
+   {
+      memset(input,0,MAXLINE);
+      while(fgets(input,MAXLINE,f) != NULL)
+      {
+         token = strstr(input,string);
+         if(token != NULL)
+            return 1;
+      }
+   }
+#ifdef PNG_WARNINGS_SUPPORTED
+   else
+      png_warning(png_ptr, "/proc/cpuinfo open failed");
+#endif
+   return 0;
+}
diff --git a/contrib/powerpc-vsx/linux_aux.c b/contrib/powerpc-vsx/linux_aux.c
new file mode 100644 (file)
index 0000000..7828aca
--- /dev/null
@@ -0,0 +1,34 @@
+/* contrib/powerpc-vsx/linux_aux.c
+ *
+ * Copyright (c) 2017 Glenn Randers-Pehrson
+ * Written by Vadim Barkov, 2017.
+ * Last changed in libpng 1.6.29 [March 16, 2017]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * STATUS: TESTED
+ * BUG REPORTS: png-mng-implement@sourceforge.net
+ *
+ * png_have_vsx implemented for Linux by using the auxiliary vector mechanism.
+ *
+ * This code is strict ANSI-C and is probably moderately portable; it does
+ * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
+ */
+
+#include "sys/auxv.h"
+#include "png.h"
+
+static int
+png_have_vsx(png_structp png_ptr)
+{
+   unsigned long auxv = getauxval(AT_HWCAP);
+
+   PNG_UNUSED(png_ptr)
+
+   if(auxv & (PPC_FEATURE_HAS_ALTIVEC|PPC_FEATURE_HAS_VSX))
+      return 1;
+   else
+      return 0;
+}
diff --git a/contrib/testpngs/crashers/bad_iCCP.png b/contrib/testpngs/crashers/bad_iCCP.png
new file mode 100644 (file)
index 0000000..0b7b863
Binary files /dev/null and b/contrib/testpngs/crashers/bad_iCCP.png differ
diff --git a/contrib/testpngs/crashers/badadler.png b/contrib/testpngs/crashers/badadler.png
new file mode 100644 (file)
index 0000000..2bcbcc9
Binary files /dev/null and b/contrib/testpngs/crashers/badadler.png differ
diff --git a/contrib/testpngs/crashers/badcrc.png b/contrib/testpngs/crashers/badcrc.png
new file mode 100644 (file)
index 0000000..45d0268
Binary files /dev/null and b/contrib/testpngs/crashers/badcrc.png differ
diff --git a/contrib/testpngs/crashers/empty_ancillary_chunks.png b/contrib/testpngs/crashers/empty_ancillary_chunks.png
new file mode 100644 (file)
index 0000000..d76477c
Binary files /dev/null and b/contrib/testpngs/crashers/empty_ancillary_chunks.png differ
diff --git a/contrib/testpngs/crashers/huge_IDAT.png b/contrib/testpngs/crashers/huge_IDAT.png
new file mode 100644 (file)
index 0000000..efee66c
Binary files /dev/null and b/contrib/testpngs/crashers/huge_IDAT.png differ
diff --git a/contrib/testpngs/crashers/huge_bKGD_chunk.png b/contrib/testpngs/crashers/huge_bKGD_chunk.png
new file mode 100644 (file)
index 0000000..fd571fd
Binary files /dev/null and b/contrib/testpngs/crashers/huge_bKGD_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_cHRM_chunk.png b/contrib/testpngs/crashers/huge_cHRM_chunk.png
new file mode 100644 (file)
index 0000000..698e7c4
Binary files /dev/null and b/contrib/testpngs/crashers/huge_cHRM_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_eXIf_chunk.png b/contrib/testpngs/crashers/huge_eXIf_chunk.png
new file mode 100644 (file)
index 0000000..7d41601
Binary files /dev/null and b/contrib/testpngs/crashers/huge_eXIf_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_gAMA_chunk.png b/contrib/testpngs/crashers/huge_gAMA_chunk.png
new file mode 100644 (file)
index 0000000..b089c18
Binary files /dev/null and b/contrib/testpngs/crashers/huge_gAMA_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_hIST_chunk.png b/contrib/testpngs/crashers/huge_hIST_chunk.png
new file mode 100644 (file)
index 0000000..6d6fcb5
Binary files /dev/null and b/contrib/testpngs/crashers/huge_hIST_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_iCCP_chunk.png b/contrib/testpngs/crashers/huge_iCCP_chunk.png
new file mode 100644 (file)
index 0000000..fbcb761
Binary files /dev/null and b/contrib/testpngs/crashers/huge_iCCP_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_iTXt_chunk.png b/contrib/testpngs/crashers/huge_iTXt_chunk.png
new file mode 100644 (file)
index 0000000..0982620
Binary files /dev/null and b/contrib/testpngs/crashers/huge_iTXt_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png b/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png
new file mode 100644 (file)
index 0000000..0cb106f
Binary files /dev/null and b/contrib/testpngs/crashers/huge_juNK_unsafe_to_copy.png differ
diff --git a/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png b/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png
new file mode 100644 (file)
index 0000000..85252b7
Binary files /dev/null and b/contrib/testpngs/crashers/huge_juNk_safe_to_copy.png differ
diff --git a/contrib/testpngs/crashers/huge_pCAL_chunk.png b/contrib/testpngs/crashers/huge_pCAL_chunk.png
new file mode 100644 (file)
index 0000000..bc12a8f
Binary files /dev/null and b/contrib/testpngs/crashers/huge_pCAL_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_pHYs_chunk.png b/contrib/testpngs/crashers/huge_pHYs_chunk.png
new file mode 100644 (file)
index 0000000..343b977
Binary files /dev/null and b/contrib/testpngs/crashers/huge_pHYs_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_sCAL_chunk.png b/contrib/testpngs/crashers/huge_sCAL_chunk.png
new file mode 100644 (file)
index 0000000..61f2f82
Binary files /dev/null and b/contrib/testpngs/crashers/huge_sCAL_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_sPLT_chunk.png b/contrib/testpngs/crashers/huge_sPLT_chunk.png
new file mode 100644 (file)
index 0000000..75d383a
Binary files /dev/null and b/contrib/testpngs/crashers/huge_sPLT_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_sRGB_chunk.png b/contrib/testpngs/crashers/huge_sRGB_chunk.png
new file mode 100644 (file)
index 0000000..bc1db33
Binary files /dev/null and b/contrib/testpngs/crashers/huge_sRGB_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_sTER_chunk.png b/contrib/testpngs/crashers/huge_sTER_chunk.png
new file mode 100644 (file)
index 0000000..39219fe
Binary files /dev/null and b/contrib/testpngs/crashers/huge_sTER_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_tEXt_chunk.png b/contrib/testpngs/crashers/huge_tEXt_chunk.png
new file mode 100644 (file)
index 0000000..947fc37
Binary files /dev/null and b/contrib/testpngs/crashers/huge_tEXt_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_tIME_chunk.png b/contrib/testpngs/crashers/huge_tIME_chunk.png
new file mode 100644 (file)
index 0000000..16452fb
Binary files /dev/null and b/contrib/testpngs/crashers/huge_tIME_chunk.png differ
diff --git a/contrib/testpngs/crashers/huge_zTXt_chunk.png b/contrib/testpngs/crashers/huge_zTXt_chunk.png
new file mode 100644 (file)
index 0000000..52f0953
Binary files /dev/null and b/contrib/testpngs/crashers/huge_zTXt_chunk.png differ
index 8187587..eb1c15f 100755 (executable)
@@ -5,7 +5,7 @@
 
 # Copyright (c) 2015 John Cunningham Bowler
 
-# Last changed in libpng 1.7.0 [(PENDING RELEASE)]
+# Last changed in libpng 1.6.20 [December 3, 2015]
 
 # This code is released under the libpng license.
 # For conditions of distribution and use, see the disclaimer
@@ -74,7 +74,7 @@ case "$1" in
    --coverage)
       # Comments below indicate cases known to be required and not duplicated
       # in other (required) cases; the aim is to get a minimal set that gives
-      # the maxium code coverage.
+      # the maximum code coverage.
       mpg none gray-alpha 8 # required: code coverage, sRGB opaque component
       mpg none palette 8 # required: basic palette read
       mpg 1.8 gray 2 # required: tests gamma threshold code
index 5ddae02..f53be6d 100644 (file)
@@ -23,4 +23,5 @@ ORIGINAL AUTHORS
     of the people below claim any rights with regard to the contents of this
     directory.
 
-    John Bowler <jbowler@acm.org>
+    John Bowler <jbowler at acm.org>
+    Glenn Randers-Pehrson <glennrp at users.sourceforge.net>
index 9da6475..95181fd 100755 (executable)
@@ -1,4 +1,11 @@
 #!/bin/sh
+
+# chkfmt
+#
+# COPYRIGHT: Written by John Cunningham Bowler, 2010.
+# To the extent possible under law, the author has waived all copyright and
+# related or neighboring rights to this work.  This work is published from:
+# United States.
 #
 # Check the format of the source files in the current directory - checks for a
 # line length of 80 characters max and no tab characters.
@@ -47,7 +54,7 @@ doed(){
 }
 
 # In beta versions the version string which appears in files can be a little
-# long and cause spuriously overlong lines.  To avoid this subtitute the version
+# long and cause spuriously overlong lines.  To avoid this substitute the version
 # string with a 'standard' version a.b.cc before checking for long lines.
 if test -r png.h
 then
index ce43260..0b3f981 100644 (file)
@@ -1,7 +1,8 @@
 /*- genpng
  *
  * COPYRIGHT: Written by John Cunningham Bowler, 2015.
- * To the extent possible under law, the author has waived all copyright and
+ * Revised by Glenn Randers-Pehrson, 2017, to add buffer-size check.
+ * To the extent possible under law, the authors have waived all copyright and
  * related or neighboring rights to this work.  This work is published from:
  * United States.
  *
@@ -783,6 +784,19 @@ main(int argc, const char **argv)
          return 1;
       }
 
+#if 1
+     /* TO do: determine whether this guard against overflow is necessary.
+      * This comment in png.h indicates that it should be safe: "libpng will
+      * refuse to process an image where such an overflow would occur", but
+      * I don't see where the image gets rejected when the buffer is too
+      * large before the malloc is attempted.
+      */
+      if (image.height > ((size_t)(-1))/(8*image.width)) {
+         fprintf(stderr, "genpng: image buffer would be too big");
+         return 1;
+      }
+#endif
+
       /* Create the buffer: */
       buffer = malloc(PNG_IMAGE_SIZE(image));
 
index e66c9f1..d0c0ca9 100644 (file)
@@ -388,7 +388,7 @@ main(int argc, char **argv)
 
    if (!test_only)
    {
-      printf("PNG_CONST png_uint_16 png_sRGB_table[256] =\n{\n   ");
+      printf("const png_uint_16 png_sRGB_table[256] =\n{\n   ");
       for (i=0; i<255; )
       {
          do
@@ -401,7 +401,7 @@ main(int argc, char **argv)
       printf("%d\n};\n\n", png_sRGB_table[i]);
 
 
-      printf("PNG_CONST png_uint_16 png_sRGB_base[512] =\n{\n   ");
+      printf("const png_uint_16 png_sRGB_base[512] =\n{\n   ");
       for (i=0; i<511; )
       {
          do
@@ -413,7 +413,7 @@ main(int argc, char **argv)
       }
       printf("%d\n};\n\n", png_sRGB_base[i]);
 
-      printf("PNG_CONST png_byte png_sRGB_delta[512] =\n{\n   ");
+      printf("const png_byte png_sRGB_delta[512] =\n{\n   ");
       for (i=0; i<511; )
       {
          do
diff --git a/contrib/tools/pngcp.c b/contrib/tools/pngcp.c
new file mode 100644 (file)
index 0000000..16d4e7f
--- /dev/null
@@ -0,0 +1,2453 @@
+/* pngcp.c
+ *
+ * Copyright (c) 2016 John Cunningham Bowler
+ *
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This is an example of copying a PNG without changes using the png_read_png
+ * and png_write_png interfaces.  A considerable number of options are provided
+ * to manipulate the compression of the PNG data and other compressed chunks.
+ *
+ * For a more extensive example that uses the transforms see
+ * contrib/libtests/pngimage.c in the libpng distribution.
+ */
+#include "pnglibconf.h" /* To find how libpng was configured. */
+
+#ifdef PNG_PNGCP_TIMING_SUPPORTED
+   /* WARNING:
+    *
+    * This test is here to allow POSIX.1b extensions to be used if enabled in
+    * the compile; specifically the code requires_POSIX_C_SOURCE support of
+    * 199309L or later to enable clock_gettime use.
+    *
+    * IF this causes problems THEN compile with a strict ANSI C compiler and let
+    * this code turn on the POSIX features that it minimally requires.
+    *
+    * IF this does not work there is probably a bug in your ANSI C compiler or
+    * your POSIX implementation.
+    */
+#  define _POSIX_C_SOURCE 199309L
+#else /* No timing support required */
+#  define _POSIX_SOURCE 1
+#endif
+
+#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+
+/* Define the following to use this test against your installed libpng, rather
+ * than the one being built here:
+ */
+#ifdef PNG_FREESTANDING_TESTS
+#  include <png.h>
+#else
+#  include "../../png.h"
+#endif
+
+#if PNG_LIBPNG_VER < 10700
+   /* READ_PNG and WRITE_PNG were not defined, so: */
+#  ifdef PNG_INFO_IMAGE_SUPPORTED
+#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#        define PNG_READ_PNG_SUPPORTED
+#     endif /* SEQUENTIAL_READ */
+#     ifdef PNG_WRITE_SUPPORTED
+#        define PNG_WRITE_PNG_SUPPORTED
+#     endif /* WRITE */
+#  endif /* INFO_IMAGE */
+#endif /* pre 1.7.0 */
+
+#if (defined(PNG_READ_PNG_SUPPORTED)) && (defined(PNG_WRITE_PNG_SUPPORTED))
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <assert.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <zlib.h>
+
+#ifndef PNG_SETJMP_SUPPORTED
+#  include <setjmp.h> /* because png.h did *not* include this */
+#endif
+
+#ifdef __cplusplus
+#  define voidcast(type, value) static_cast<type>(value)
+#else
+#  define voidcast(type, value) (value)
+#endif /* __cplusplus */
+
+#ifdef __GNUC__
+   /* Many versions of GCC erroneously report that local variables unmodified
+    * within the scope of a setjmp may be clobbered.  This hacks round the
+    * problem (sometimes) without harming other compilers.
+    */
+#  define gv volatile
+#else
+#  define gv
+#endif
+
+/* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime.  It
+ * need not be supported even when clock_gettime is available.  It returns the
+ * 'CPU' time the process has consumed.  'CPU' time is assumed to include time
+ * when the CPU is actually blocked by a pending cache fill but not time
+ * waiting for page faults.  The attempt is to get a measure of the actual time
+ * the implementation takes to read a PNG ignoring the potentially very large IO
+ * overhead.
+ */
+#ifdef PNG_PNGCP_TIMING_SUPPORTED
+#  include <time.h>   /* clock_gettime and associated definitions */
+#  ifndef CLOCK_PROCESS_CPUTIME_ID
+      /* Prevent inclusion of the spurious code: */
+#     undef PNG_PNGCP_TIMING_SUPPORTED
+#  endif
+#endif /* PNGCP_TIMING */
+
+/* So if the timing feature has been activated: */
+
+/* This structure is used to control the test of a single file. */
+typedef enum
+{
+   VERBOSE,        /* switches on all messages */
+   INFORMATION,
+   WARNINGS,       /* switches on warnings */
+   LIBPNG_WARNING,
+   APP_WARNING,
+   ERRORS,         /* just errors */
+   APP_FAIL,       /* continuable error - no need to longjmp */
+   LIBPNG_ERROR,   /* this and higher cause a longjmp */
+   LIBPNG_BUG,     /* erroneous behavior in libpng */
+   APP_ERROR,      /* such as out-of-memory in a callback */
+   QUIET,          /* no normal messages */
+   USER_ERROR,     /* such as file-not-found */
+   INTERNAL_ERROR
+} error_level;
+#define LEVEL_MASK      0xf   /* where the level is in 'options' */
+
+#define STRICT          0x010 /* Fail on warnings as well as errors */
+#define LOG             0x020 /* Log pass/fail to stdout */
+#define CONTINUE        0x040 /* Continue on APP_FAIL errors */
+#define SIZES           0x080 /* Report input and output sizes */
+#define SEARCH          0x100 /* Search IDAT compression options */
+#define NOWRITE         0x200 /* Do not write an output file */
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#  define IGNORE_INDEX  0x400 /* Ignore out of range palette indices (BAD!) */
+#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+#     define FIX_INDEX  0x800 /* 'Fix' out of range palette indices (OK) */
+#  endif /* GET_PALETTE_MAX */
+#endif /* CHECK_FOR_INVALID_INDEX */
+#define OPTION     0x80000000 /* Used for handling options */
+#define LIST       0x80000001 /* Used for handling options */
+
+/* Result masks apply to the result bits in the 'results' field below; these
+ * bits are simple 1U<<error_level.  A pass requires either nothing worse than
+ * warnings (--relaxes) or nothing worse than information (--strict)
+ */
+#define RESULT_STRICT(r)   (((r) & ~((1U<<WARNINGS)-1)) == 0)
+#define RESULT_RELAXED(r)  (((r) & ~((1U<<ERRORS)-1)) == 0)
+
+/* OPTION DEFINITIONS */
+static const char range_lo[] = "low";
+static const char range_hi[] = "high";
+static const char all[] = "all";
+#define RANGE(lo,hi) { range_lo, lo }, { range_hi, hi }
+typedef struct value_list
+{
+   const char *name;  /* the command line name of the value */
+   int         value; /* the actual value to use */
+}  value_list;
+
+static const value_list
+#ifdef PNG_SW_COMPRESS_png_level
+vl_compression[] =
+{
+   /* Overall compression control.  The order controls the search order for
+    * 'all'.  Since the search is for the smallest the order used is low memory
+    * then high speed.
+    */
+   { "low-memory",      PNG_COMPRESSION_LOW_MEMORY },
+   { "high-speed",      PNG_COMPRESSION_HIGH_SPEED },
+   { "high-read-speed", PNG_COMPRESSION_HIGH_READ_SPEED },
+   { "low",             PNG_COMPRESSION_LOW },
+   { "medium",          PNG_COMPRESSION_MEDIUM },
+   { "old",             PNG_COMPRESSION_COMPAT },
+   { "high",            PNG_COMPRESSION_HIGH },
+   { all, 0 }
+},
+#endif /* SW_COMPRESS_png_level */
+
+#if defined(PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED) ||\
+    defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED)
+vl_strategy[] =
+{
+   /* This controls the order of search. */
+   { "huffman", Z_HUFFMAN_ONLY },
+   { "RLE", Z_RLE },
+   { "fixed", Z_FIXED }, /* the remainder do window searches */
+   { "filtered", Z_FILTERED },
+   { "default", Z_DEFAULT_STRATEGY },
+   { all, 0 }
+},
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+vl_windowBits_text[] =
+{
+   { "default", MAX_WBITS/*from zlib*/ },
+   { "minimum", 8 },
+   RANGE(8, MAX_WBITS/*from zlib*/),
+   { all, 0 }
+},
+#endif /* text compression */
+vl_level[] =
+{
+   { "default", Z_DEFAULT_COMPRESSION /* this is -1 */ },
+   { "none", Z_NO_COMPRESSION },
+   { "speed", Z_BEST_SPEED },
+   { "best", Z_BEST_COMPRESSION },
+   { "0", Z_NO_COMPRESSION },
+   RANGE(1, 9), /* this deliberately excludes '0' */
+   { all, 0 }
+},
+vl_memLevel[] =
+{
+   { "max", MAX_MEM_LEVEL }, /* zlib maximum */
+   { "1", 1 }, /* zlib minimum */
+   { "default", 8 }, /* zlib default */
+   { "2", 2 },
+   { "3", 3 },
+   { "4", 4 },
+   { "5", 5 }, /* for explicit testing */
+   RANGE(6, MAX_MEM_LEVEL/*zlib*/), /* exclude 5 and below: zlib bugs */
+   { all, 0 }
+},
+#endif /* WRITE_CUSTOMIZE_*COMPRESSION */
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+vl_filter[] =
+{
+   { all,      PNG_ALL_FILTERS   },
+   { "off",    PNG_NO_FILTERS    },
+   { "none",   PNG_FILTER_NONE   },
+   { "sub",    PNG_FILTER_SUB    },
+   { "up",     PNG_FILTER_UP     },
+   { "avg",    PNG_FILTER_AVG    },
+   { "paeth",  PNG_FILTER_PAETH  }
+},
+#endif /* WRITE_FILTER */
+#ifdef PNG_PNGCP_TIMING_SUPPORTED
+#  define PNGCP_TIME_READ  1
+#  define PNGCP_TIME_WRITE 2
+vl_time[] =
+{
+   { "both",  PNGCP_TIME_READ+PNGCP_TIME_WRITE },
+   { "off",   0 },
+   { "read",  PNGCP_TIME_READ },
+   { "write", PNGCP_TIME_WRITE }
+},
+#endif /* PNGCP_TIMING */
+vl_IDAT_size[] = /* for png_set_IDAT_size */
+{
+   { "default", 0x7FFFFFFF },
+   { "minimal", 1 },
+   RANGE(1, 0x7FFFFFFF)
+},
+#ifndef PNG_SW_IDAT_size
+   /* Pre 1.7 API: */
+#  define png_set_IDAT_size(p,v) png_set_compression_buffer_size(p, v)
+#endif /* !SW_IDAT_size */
+#define SL 8 /* stack limit in display, below */
+vl_log_depth[] = { { "on", 1 }, { "off", 0 }, RANGE(0, SL) },
+vl_on_off[] = { { "on", 1 }, { "off", 0 } };
+
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+static value_list
+vl_windowBits_IDAT[] =
+{
+   { "default", MAX_WBITS },
+   { "small", 9 },
+   RANGE(8, MAX_WBITS), /* modified by set_windowBits_hi */
+   { all, 0 }
+};
+#endif /* IDAT compression */
+
+typedef struct option
+{
+   const char       *name;         /* name of the option */
+   png_uint_32       opt;          /* an option, or OPTION or LIST */
+   png_byte          search;       /* Search on --search */
+   png_byte          value_count;  /* length of the list of values: */
+   const value_list *values;       /* values for OPTION or LIST */
+}  option;
+
+static const option options[] =
+{
+   /* struct display options, these are set when the command line is read */
+#  define S(n,v) { #n, v, 0, 2, vl_on_off },
+   S(verbose,  VERBOSE)
+   S(warnings, WARNINGS)
+   S(errors,   ERRORS)
+   S(quiet,    QUIET)
+   S(strict,   STRICT)
+   S(log,      LOG)
+   S(continue, CONTINUE)
+   S(sizes,    SIZES)
+   S(search,   SEARCH)
+   S(nowrite,  NOWRITE)
+#  ifdef IGNORE_INDEX
+      S(ignore-palette-index, IGNORE_INDEX)
+#  endif /* IGNORE_INDEX */
+#  ifdef FIX_INDEX
+      S(fix-palette-index, FIX_INDEX)
+#  endif /* FIX_INDEX */
+#  undef S
+
+   /* OPTION settings, these and LIST settings are read on demand */
+#  define VLNAME(name) vl_ ## name
+#  define VLSIZE(name) voidcast(png_byte,\
+                           (sizeof VLNAME(name))/(sizeof VLNAME(name)[0]))
+#  define VL(oname, name, type, search)\
+   { oname, type, search, VLSIZE(name), VLNAME(name) },
+#  define VLO(oname, name, search) VL(oname, name, OPTION, search)
+
+#  ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+#     define VLCIDAT(name) VLO(#name, name, 1/*search*/)
+#     ifdef PNG_SW_COMPRESS_level
+#        define VLCiCCP(name) VLO("ICC-profile-" #name, name, 0/*search*/)
+#     else
+#        define VLCiCCP(name)
+#     endif
+#  else
+#     define VLCIDAT(name)
+#     define VLCiCCP(name)
+#  endif /* WRITE_CUSTOMIZE_COMPRESSION */
+
+#  ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+#     define VLCzTXt(name) VLO("text-" #name, name, 0/*search*/)
+#  else
+#     define VLCzTXt(name)
+#  endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+
+#  define VLC(name) VLCIDAT(name) VLCiCCP(name) VLCzTXt(name)
+
+#  ifdef PNG_SW_COMPRESS_png_level
+      /* The libpng compression level isn't searched because it justs sets the
+       * other things that are searched!
+       */
+      VLO("compression", compression, 0)
+      VLO("text-compression", compression, 0)
+      VLO("ICC-profile-compression", compression, 0)
+#  endif /* SW_COMPRESS_png_level */
+   VLC(strategy)
+   VLO("windowBits", windowBits_IDAT, 1)
+#  ifdef PNG_SW_COMPRESS_windowBits
+      VLO("ICC-profile-windowBits", windowBits_text/*sic*/, 0)
+#  endif
+   VLO("text-windowBits", windowBits_text, 0)
+   VLC(level)
+   VLC(memLevel)
+   VLO("IDAT-size", IDAT_size, 0)
+   VLO("log-depth", log_depth, 0)
+
+#  undef VLO
+
+   /* LIST settings */
+#  define VLL(name, search) VL(#name, name, LIST, search)
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+   VLL(filter, 0)
+#endif /* WRITE_FILTER */
+#ifdef PNG_PNGCP_TIMING_SUPPORTED
+   VLL(time, 0)
+#endif /* PNGCP_TIMING */
+#  undef VLL
+#  undef VL
+};
+
+#ifdef __cplusplus
+   static const size_t option_count((sizeof options)/(sizeof options[0]));
+#else /* !__cplusplus */
+#  define option_count ((sizeof options)/(sizeof options[0]))
+#endif /* !__cplusplus */
+
+static const char *
+cts(int ct)
+{
+   switch (ct)
+   {
+      case PNG_COLOR_TYPE_PALETTE:     return "P";
+      case PNG_COLOR_TYPE_GRAY:        return "G";
+      case PNG_COLOR_TYPE_GRAY_ALPHA:  return "GA";
+      case PNG_COLOR_TYPE_RGB:         return "RGB";
+      case PNG_COLOR_TYPE_RGB_ALPHA:   return "RGBA";
+      default:                         return "INVALID";
+   }
+}
+
+struct display
+{
+   jmp_buf          error_return;      /* Where to go to on error */
+   unsigned int     errset;            /* error_return is set */
+
+   const char      *operation;         /* What is happening */
+   const char      *filename;          /* The name of the original file */
+   const char      *output_file;       /* The name of the output file */
+
+   /* Used on both read and write: */
+   FILE            *fp;
+
+   /* Used on a read, both the original read and when validating a written
+    * image.
+    */
+   png_alloc_size_t read_size;
+   png_structp      read_pp;
+   png_infop        ip;
+#  if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
+      png_textp     text_ptr; /* stash of text chunks */
+      int           num_text;
+      int           text_stashed;
+#  endif /* pre 1.7 */
+
+#  ifdef PNG_PNGCP_TIMING_SUPPORTED
+      struct timespec   read_time;
+      struct timespec   read_time_total;
+      struct timespec   write_time;
+      struct timespec   write_time_total;
+#  endif /* PNGCP_TIMING */
+
+   /* Used to write a new image (the original info_ptr is used) */
+#  define MAX_SIZE ((png_alloc_size_t)(-1))
+   png_alloc_size_t write_size;
+   png_alloc_size_t best_size;
+   png_structp      write_pp;
+
+   /* Base file information */
+   png_alloc_size_t size;
+   png_uint_32      w;
+   png_uint_32      h;
+   int              bpp;
+   png_byte         ct;
+   int              no_warnings;       /* Do not output libpng warnings */
+   int              min_windowBits;    /* The windowBits range is 8..8 */
+
+   /* Options handling */
+   png_uint_32      results;             /* A mask of errors seen */
+   png_uint_32      options;             /* See display_log below */
+   png_byte         entry[option_count]; /* The selected entry+1 of an option
+                                          * that appears on the command line, or
+                                          * 0 if it was not given. */
+   int              value[option_count]; /* Corresponding value */
+
+   /* Compression exhaustive testing */
+   /* Temporary variables used only while testing a single collection of
+    * settings:
+    */
+   unsigned int     csp;               /* next stack entry to use */
+   unsigned int     nsp;               /* highest active entry+1 found so far */
+
+   /* Values used while iterating through all the combinations of settings for a
+    * single file:
+    */
+   unsigned int     tsp;               /* nsp from the last run; this is the
+                                        * index+1 of the highest active entry on
+                                        * this run; this entry will be advanced.
+                                        */
+   int              opt_string_start;  /* Position in buffer for the first
+                                        * searched option; non-zero if earlier
+                                        * options were set on the command line.
+                                        */
+   struct stack
+   {
+      png_alloc_size_t best_size;      /* Best so far for this option */
+      png_alloc_size_t lo_size;
+      png_alloc_size_t hi_size;
+      int              lo, hi;         /* For binary chop of a range */
+      int              best_val;       /* Best value found so far */
+      int              opt_string_end; /* End of the option string in 'curr' */
+      png_byte         opt;            /* The option being tested */
+      png_byte         entry;          /* The next value entry to be tested */
+      png_byte         end;            /* This is the last entry */
+   }                stack[SL];         /* Stack of entries being tested */
+   char             curr[32*SL];       /* current options being tested */
+   char             best[32*SL];       /* best options */
+
+   char             namebuf[FILENAME_MAX]; /* output file name */
+};
+
+static void
+display_init(struct display *dp)
+   /* Call this only once right at the start to initialize the control
+    * structure, the (struct buffer) lists are maintained across calls - the
+    * memory is not freed.
+    */
+{
+   memset(dp, 0, sizeof *dp);
+   dp->operation = "internal error";
+   dp->filename = "command line";
+   dp->output_file = "no output file";
+   dp->options = WARNINGS; /* default to !verbose, !quiet */
+   dp->fp = NULL;
+   dp->read_pp = NULL;
+   dp->ip = NULL;
+   dp->write_pp = NULL;
+   dp->min_windowBits = -1; /* this is an OPTIND, so -1 won't match anything */
+#  if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
+      dp->text_ptr = NULL;
+      dp->num_text = 0;
+      dp->text_stashed = 0;
+#  endif /* pre 1.7 */
+}
+
+static void
+display_clean_read(struct display *dp)
+{
+   if (dp->read_pp != NULL)
+      png_destroy_read_struct(&dp->read_pp, NULL, NULL);
+
+   if (dp->fp != NULL)
+   {
+      FILE *fp = dp->fp;
+      dp->fp = NULL;
+      (void)fclose(fp);
+   }
+}
+
+static void
+display_clean_write(struct display *dp)
+{
+   if (dp->fp != NULL)
+   {
+      FILE *fp = dp->fp;
+      dp->fp = NULL;
+      (void)fclose(fp);
+   }
+
+   if (dp->write_pp != NULL)
+      png_destroy_write_struct(&dp->write_pp, dp->tsp > 0 ? NULL : &dp->ip);
+}
+
+static void
+display_clean(struct display *dp)
+{
+   display_clean_read(dp);
+   display_clean_write(dp);
+   dp->output_file = NULL;
+
+#  if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
+      /* This is actually created and used by the write code, but only
+       * once; it has to be retained for subsequent writes of the same file.
+       */
+      if (dp->text_stashed)
+      {
+         dp->text_stashed = 0;
+         dp->num_text = 0;
+         free(dp->text_ptr);
+         dp->text_ptr = NULL;
+      }
+#  endif /* pre 1.7 */
+
+   /* leave the filename for error detection */
+   dp->results = 0; /* reset for next time */
+}
+
+static void
+display_destroy(struct display *dp)
+{
+   /* Release any memory held in the display. */
+   display_clean(dp);
+}
+
+static struct display *
+get_dp(png_structp pp)
+   /* The display pointer is always stored in the png_struct error pointer */
+{
+   struct display *dp = (struct display*)png_get_error_ptr(pp);
+
+   if (dp == NULL)
+   {
+      fprintf(stderr, "pngcp: internal error (no display)\n");
+      exit(99); /* prevents a crash */
+   }
+
+   return dp;
+}
+
+/* error handling */
+#ifdef __GNUC__
+#  define VGATTR __attribute__((__format__ (__printf__,3,4)))
+   /* Required to quiet GNUC warnings when the compiler sees a stdarg function
+    * that calls one of the stdio v APIs.
+    */
+#else
+#  define VGATTR
+#endif
+static void VGATTR
+display_log(struct display *dp, error_level level, const char *fmt, ...)
+   /* 'level' is as above, fmt is a stdio style format string.  This routine
+    * does not return if level is above LIBPNG_WARNING
+    */
+{
+   dp->results |= 1U << level;
+
+   if (level > (error_level)(dp->options & LEVEL_MASK))
+   {
+      const char *lp;
+      va_list ap;
+
+      switch (level)
+      {
+         case INFORMATION:    lp = "information"; break;
+         case LIBPNG_WARNING: lp = "warning(libpng)"; break;
+         case APP_WARNING:    lp = "warning(pngcp)"; break;
+         case APP_FAIL:       lp = "error(continuable)"; break;
+         case LIBPNG_ERROR:   lp = "error(libpng)"; break;
+         case LIBPNG_BUG:     lp = "bug(libpng)"; break;
+         case APP_ERROR:      lp = "error(pngcp)"; break;
+         case USER_ERROR:     lp = "error(user)"; break;
+
+         case INTERNAL_ERROR: /* anything unexpected is an internal error: */
+         case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
+         default:             lp = "bug(pngcp)"; break;
+      }
+
+      fprintf(stderr, "%s: %s: %s",
+         dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);
+
+      fprintf(stderr, ": ");
+
+      va_start(ap, fmt);
+      vfprintf(stderr, fmt, ap);
+      va_end(ap);
+
+      fputc('\n', stderr);
+   }
+   /* else do not output any message */
+
+   /* Errors cause this routine to exit to the fail code */
+   if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
+   {
+      if (dp->errset)
+         longjmp(dp->error_return, level);
+
+      else
+         exit(99);
+   }
+}
+
+#if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
+static void
+text_stash(struct display *dp)
+{
+   /* libpng 1.6 and earlier fixed a bug whereby text chunks were written
+    * multiple times by png_write_png; the issue was that png_write_png passed
+    * the same png_info to both png_write_info and png_write_end.  Rather than
+    * fixing it by recording the information in the png_struct, or by recording
+    * where to write the chunks, the fix made was to change the 'compression'
+    * field of the chunk to invalid values, rendering the png_info somewhat
+    * useless.
+    *
+    * The only fix for this given that we use the png_info more than once is to
+    * make a copy of the text chunks and png_set_text it each time.  This adds a
+    * text chunks, so they get replicated, but only the new set gets written
+    * each time.  This uses memory like crazy but there is no way to delete the
+    * useless chunks from the png_info.
+    *
+    * To make this slightly more efficient only the top level structure is
+    * copied; since the old strings are actually preserved (in 1.6 and earlier)
+    * this happens to work.
+    */
+   png_textp chunks = NULL;
+
+   dp->num_text = png_get_text(dp->write_pp, dp->ip, &chunks, NULL);
+
+   if (dp->num_text > 0)
+   {
+      dp->text_ptr = voidcast(png_textp, malloc(dp->num_text * sizeof *chunks));
+
+      if (dp->text_ptr == NULL)
+         display_log(dp, APP_ERROR, "text chunks: stash malloc failed");
+
+      else
+         memcpy(dp->text_ptr, chunks, dp->num_text * sizeof *chunks);
+   }
+
+   dp->text_stashed = 1; /* regardless of whether there are chunks or not */
+}
+
+#define text_stash(dp) if (!dp->text_stashed) text_stash(dp)
+
+static void
+text_restore(struct display *dp)
+{
+   /* libpng makes a copy, so this is fine: */
+   if (dp->text_ptr != NULL)
+      png_set_text(dp->write_pp, dp->ip, dp->text_ptr, dp->num_text);
+}
+
+#define text_restore(dp) if (dp->text_stashed) text_restore(dp)
+
+#else
+#define text_stash(dp) ((void)0)
+#define text_restore(dp) ((void)0)
+#endif /* pre 1.7 */
+
+/* OPTIONS:
+ *
+ * The command handles options of the forms:
+ *
+ *    --option
+ *       Turn an option on (Option)
+ *    --no-option
+ *       Turn an option off (Option)
+ *    --option=value
+ *       Set an option to a value (Value)
+ *    --option=val1,val2,val3
+ *       Set an option to a bitmask constructed from the values (List)
+ */
+static png_byte
+option_index(struct display *dp, const char *opt, size_t len)
+   /* Return the index (in options[]) of the given option, outputs an error if
+    * it does not exist.  Takes the name of the option and a length (number of
+    * characters in the name).
+    */
+{
+   png_byte j;
+
+   for (j=0; j<option_count; ++j)
+      if (strncmp(options[j].name, opt, len) == 0 && options[j].name[len] == 0)
+         return j;
+
+   /* If the setjmp buffer is set the code is asking for an option index; this
+    * is bad.  Otherwise this is the command line option parsing.
+    */
+   display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
+         "%.*s: unknown option", (int)/*SAFE*/len, opt);
+   abort(); /* NOT REACHED */
+}
+
+/* This works for an option name (no quotes): */
+#define OPTIND(dp, name) option_index(dp, #name, (sizeof #name)-1)
+
+static int
+get_option(struct display *dp, const char *opt, int *value)
+{
+   png_byte i = option_index(dp, opt, strlen(opt));
+
+   if (dp->entry[i]) /* option was set on command line */
+   {
+      *value = dp->value[i];
+      return 1;
+   }
+
+   else
+      return 0;
+}
+
+static int
+set_opt_string_(struct display *dp, unsigned int sp, png_byte opt,
+      const char *entry_name)
+   /* Add the appropriate option string to dp->curr. */
+{
+   int offset, add;
+
+   if (sp > 0)
+      offset = dp->stack[sp-1].opt_string_end;
+
+   else
+      offset = dp->opt_string_start;
+
+   if (entry_name == range_lo)
+      add = sprintf(dp->curr+offset, " --%s=%d", options[opt].name,
+            dp->value[opt]);
+
+   else
+      add = sprintf(dp->curr+offset, " --%s=%s", options[opt].name, entry_name);
+
+   if (add < 0)
+      display_log(dp, INTERNAL_ERROR, "sprintf failed");
+
+   assert(offset+add < (int)/*SAFE*/sizeof dp->curr);
+   return offset+add;
+}
+
+static void
+set_opt_string(struct display *dp, unsigned int sp)
+   /* Add the appropriate option string to dp->curr. */
+{
+   dp->stack[sp].opt_string_end = set_opt_string_(dp, sp, dp->stack[sp].opt, 
+      options[dp->stack[sp].opt].values[dp->stack[sp].entry].name);
+}
+
+static void
+record_opt(struct display *dp, png_byte opt, const char *entry_name)
+   /* Record this option in dp->curr; called for an option not being searched,
+    * the caller passes in the name of the value, or range_lo to use the
+    * numerical value.
+    */
+{
+   unsigned int sp = dp->csp; /* stack entry of next searched option */
+
+   if (sp >= dp->tsp)
+   {
+      /* At top of stack; add the opt string for this entry to the previous
+       * searched entry or the start of the dp->curr buffer if there is nothing
+       * on the stack yet (sp == 0).
+       */
+      int offset = set_opt_string_(dp, sp, opt, entry_name);
+
+      if (sp > 0)
+         dp->stack[sp-1].opt_string_end = offset;
+
+      else
+         dp->opt_string_start = offset;
+   }
+
+   /* else do nothing: option already recorded */
+}
+
+static int
+opt_list_end(struct display *dp, png_byte opt, png_byte entry)
+{
+   if (options[opt].values[entry].name == range_lo)
+      return entry+1U >= options[opt].value_count /* missing range_hi */ ||
+         options[opt].values[entry+1U].name != range_hi /* likewise */ ||
+         options[opt].values[entry+1U].value <= dp->value[opt] /* range end */;
+
+   else
+      return entry+1U >= options[opt].value_count /* missing 'all' */ ||
+         options[opt].values[entry+1U].name == all /* last entry */;
+}
+
+static void
+push_opt(struct display *dp, unsigned int sp, png_byte opt, int search)
+   /* Push a new option onto the stack, initializing the new stack entry
+    * appropriately; this does all the work of next_opt (setting end/nsp) for
+    * the first entry in the list.
+    */
+{
+   png_byte entry;
+   const char *entry_name;
+
+   assert(sp == dp->tsp && sp < SL);
+
+   /* The starting entry is entry 0 unless there is a range in which case it is
+    * the entry corresponding to range_lo:
+    */
+   entry = options[opt].value_count;
+   assert(entry > 0U);
+
+   do
+   {
+      entry_name = options[opt].values[--entry].name;
+      if (entry_name == range_lo)
+         break;
+   }
+   while (entry > 0U);
+
+   dp->tsp = sp+1U;
+   dp->stack[sp].best_size =
+      dp->stack[sp].lo_size =
+      dp->stack[sp].hi_size = MAX_SIZE;
+
+   if (search && entry_name == range_lo) /* search this range */
+   {
+      dp->stack[sp].lo = options[opt].values[entry].value;
+      /* check for a mal-formed RANGE above: */
+      assert(entry+1 < options[opt].value_count &&
+             options[opt].values[entry+1].name == range_hi);
+      dp->stack[sp].hi = options[opt].values[entry+1].value;
+   }
+
+   else
+   {
+      /* next_opt will just iterate over the range. */
+      dp->stack[sp].lo = INT_MAX;
+      dp->stack[sp].hi = INT_MIN; /* Prevent range chop */
+   }
+
+   dp->stack[sp].opt = opt;
+   dp->stack[sp].entry = entry;
+   dp->stack[sp].best_val = dp->value[opt] = options[opt].values[entry].value;
+
+   set_opt_string(dp, sp);
+
+   /* This works for the search case too; if the range has only one entry 'end'
+    * will be marked here.
+    */
+   if (opt_list_end(dp, opt, entry))
+   {
+      dp->stack[sp].end = 1;
+      /* Skip the warning if pngcp did this itself.  See the code in
+       * set_windowBits_hi.
+       */
+      if (opt != dp->min_windowBits)
+         display_log(dp, APP_WARNING, "%s: only testing one value",
+               options[opt].name);
+   }
+
+   else
+   {
+      dp->stack[sp].end = 0;
+      dp->nsp = dp->tsp;
+   }
+
+   /* Do a lazy cache of the text chunks for libpng 1.6 and earlier; this is
+    * because they can only be written once(!) so if we are going to re-use the
+    * png_info we need a copy.
+    */
+   text_stash(dp);
+}
+
+static void
+next_opt(struct display *dp, unsigned int sp)
+   /* Return the next value for this option.  When called 'sp' is expected to be
+    * the topmost stack entry - only the topmost entry changes each time round -
+    * and there must be a valid entry to return.  next_opt will set dp->nsp to
+    * sp+1 if more entries are available, otherwise it will not change it and
+    * set dp->stack[s].end to true.
+    */
+{
+   int search = 0;
+   png_byte entry, opt;
+   const char *entry_name;
+
+   /* dp->stack[sp] must be the top stack entry and it must be active: */
+   assert(sp+1U == dp->tsp && !dp->stack[sp].end);
+
+   opt = dp->stack[sp].opt;
+   entry = dp->stack[sp].entry;
+   assert(entry+1U < options[opt].value_count);
+   entry_name = options[opt].values[entry].name;
+   assert(entry_name != NULL);
+
+   /* For ranges increment the value but don't change the entry, for all other
+    * cases move to the next entry and load its value:
+    */
+   if (entry_name == range_lo) /* a range */
+   {
+      /* A range can be iterated over or searched.  The default iteration option
+       * is indicated by hi < lo on the stack, otherwise the range being search
+       * is [lo..hi] (inclusive).
+       */
+      if (dp->stack[sp].lo > dp->stack[sp].hi)
+         dp->value[opt]++;
+
+      else
+      {
+         /* This is the best size found for this option value: */
+         png_alloc_size_t best_size = dp->stack[sp].best_size;
+         int lo = dp->stack[sp].lo;
+         int hi = dp->stack[sp].hi;
+         int val = dp->value[opt];
+
+         search = 1; /* end is determined here */
+         assert(best_size < MAX_SIZE);
+
+         if (val == lo)
+         {
+            /* Finding the best for the low end of the range: */
+            dp->stack[sp].lo_size = best_size;
+            assert(hi > val);
+
+            if (hi == val+1) /* only 2 entries */
+               dp->stack[sp].end = 1;
+
+            val = hi;
+         }
+
+         else if (val == hi)
+         {
+            dp->stack[sp].hi_size = best_size;
+            assert(val > lo+1); /* else 'end' set above */
+
+            if (val == lo+2) /* only three entries to test */
+               dp->stack[sp].end = 1;
+
+            val = (lo + val)/2;
+         }
+
+         else
+         {
+            png_alloc_size_t lo_size = dp->stack[sp].lo_size;
+            png_alloc_size_t hi_size = dp->stack[sp].hi_size;
+
+            /* lo and hi should have been tested. */
+            assert(lo_size < MAX_SIZE && hi_size < MAX_SIZE);
+
+            /* These cases arise with the 'probe' handling below when there is a
+             * dip or peak in the size curve.
+             */
+            if (val < lo) /* probing a new lo */
+            {
+               /* Swap lo and val: */
+               dp->stack[sp].lo = val;
+               dp->stack[sp].lo_size = best_size;
+               val = lo;
+               best_size = lo_size;
+               lo = dp->stack[sp].lo;
+               lo_size = dp->stack[sp].lo_size;
+            }
+
+            else if (val > hi) /* probing a new hi */
+            {
+               /* Swap hi and val: */
+               dp->stack[sp].hi = val;
+               dp->stack[sp].hi_size = best_size;
+               val = hi;
+               best_size = hi_size;
+               hi = dp->stack[sp].hi;
+               hi_size = dp->stack[sp].hi_size;
+            }
+
+            /* The following should be true or something got messed up above. */
+            assert(lo < val && val < hi);
+
+            /* If there are only four entries (lo, val, hi plus one more) just
+             * test the remaining entry.
+             */
+            if (hi == lo+3)
+            {
+               /* Because of the 'probe' code val can either be lo+1 or hi-1; we
+                * need to test the other.
+                */
+               val = lo + ((val == lo+1) ? 2 : 1);
+               assert(lo < val && val < hi);
+               dp->stack[sp].end = 1;
+            }
+
+            else
+            {
+               /* There are at least 2 entries still untested between lo and hi,
+                * i.e. hi >= lo+4.  'val' is the midpoint +/- 0.5
+                *
+                * Separate out the four easy cases when lo..val..hi are
+                * monotonically decreased or (more weird) increasing:
+                */
+               assert(hi > lo+3);
+
+               if (lo_size <= best_size && best_size <= hi_size)
+               {
+                  /* Select the low range; testing this first favours the low
+                   * range over the high range when everything comes out equal.
+                   * Because of the probing 'val' may be lo+1.  In that case end
+                   * the search and set 'val' to lo+2.
+                   */
+                  if (val == lo+1)
+                  {
+                     ++val;
+                     dp->stack[sp].end = 1;
+                  }
+
+                  else
+                  {
+                     dp->stack[sp].hi = hi = val;
+                     dp->stack[sp].hi_size = best_size;
+                     val = (lo + val) / 2;
+                  }
+               }
+
+               else if (lo_size >= best_size && best_size >= hi_size)
+               {
+                  /* Monotonically decreasing size; this is the expected case.
+                   * Select the high end of the range.  As above, val may be
+                   * hi-1.
+                   */
+                  if (val == hi-1)
+                  {
+                     --val;
+                     dp->stack[sp].end = 1;
+                  }
+
+                  else
+                  {
+                     dp->stack[sp].lo = lo = val;
+                     dp->stack[sp].lo_size = best_size;
+                     val = (val + hi) / 2;
+                  }
+               }
+
+               /* If both those tests failed 'best_size' is either greater than
+                * or less than both lo_size and hi_size.  There is a peak or dip
+                * in the curve of sizes from lo to hi and val is on the peak or
+                * dip.
+                *
+                * Because the ranges being searched as so small (level is 1..9,
+                * windowBits 8..15, memLevel 1..9) there will only be at most
+                * three untested values between lo..val and val..hi, so solve
+                * the problem by probing down from hi or up from lo, whichever
+                * is the higher.
+                *
+                * This is the place where 'val' is set to outside the range
+                * lo..hi, described as 'probing', though maybe 'narrowing' would
+                * be more accurate.
+                */
+               else if (lo_size <= hi_size) /* down from hi */
+               {
+                  dp->stack[sp].hi = val;
+                  dp->stack[sp].hi_size = best_size;
+                  val = --hi;
+               }
+
+               else /* up from low */
+               {
+                  dp->stack[sp].lo = val;
+                  dp->stack[sp].lo_size = best_size;
+                  val = ++lo;
+               }
+
+               /* lo and hi are still the true range limits, check for the end
+                * condition.
+                */
+               assert(hi > lo+1);
+               if (hi <= lo+2)
+                  dp->stack[sp].end = 1;
+            }
+         }
+
+         assert(val != dp->stack[sp].best_val); /* should be a new value */
+         dp->value[opt] = val;
+         dp->stack[sp].best_size = MAX_SIZE;
+      }
+   }
+
+   else
+   {
+      /* Increment 'entry' */
+      dp->value[opt] = options[opt].values[++entry].value;
+      dp->stack[sp].entry = entry;
+   }
+
+   set_opt_string(dp, sp);
+
+   if (!search && opt_list_end(dp, opt, entry)) /* end of list */
+      dp->stack[sp].end = 1;
+
+   else if (!dp->stack[sp].end) /* still active after all these tests */
+      dp->nsp = dp->tsp;
+}
+
+static int
+compare_option(const struct display *dp, unsigned int sp)
+{
+   int opt = dp->stack[sp].opt;
+
+   /* If the best so far is numerically less than the current value the
+    * current set of options is invariably worse.
+    */
+   if (dp->stack[sp].best_val < dp->value[opt])
+      return -1;
+
+   /* Lists of options are searched out of numerical order (currently only
+    * strategy), so only return +1 here when a range is being searched.
+    */
+   else if (dp->stack[sp].best_val > dp->value[opt])
+   {
+      if (dp->stack[sp].lo <= dp->stack[sp].hi /*searching*/)
+         return 1;
+
+      else
+         return -1;
+   }
+
+   else
+      return 0; /* match; current value is the best one */
+}
+
+static int
+advance_opt(struct display *dp, png_byte opt, int search)
+{
+   unsigned int sp = dp->csp++; /* my stack entry */
+
+   assert(sp >= dp->nsp); /* nsp starts off zero */
+
+   /* If the entry was active in the previous run dp->stack[sp] is already
+    * set up and dp->tsp will be greater than sp, otherwise a new entry
+    * needs to be created.
+    *
+    * dp->nsp is handled this way:
+    *
+    * 1) When an option is pushed onto the stack dp->nsp and dp->tsp are
+    *    both set (by push_opt) to the next stack entry *unless* there is
+    *    only one entry in the new list, in which case dp->stack[sp].end
+    *    is set.
+    *
+    * 2) For the top stack entry next_opt is called.  The entry must be
+    *    active (dp->stack[sp].end is not set) and either 'nsp' or 'end'
+    *    will be updated as appropriate.
+    *
+    * 3) For lower stack entries nsp is set unless the stack entry is
+    *    already at the end.  This means that when all the higher entries
+    *    are popped this entry will be too.
+    */
+   if (sp >= dp->tsp)
+   {
+      push_opt(dp, sp, opt, search); /* This sets tsp to sp+1 */
+      return 1; /* initialized */
+   }
+
+   else
+   {
+      int ret = 0; /* unchanged */
+
+      /* An option that is already on the stack; update best_size and best_val
+       * if appropriate.  On the first run there are no previous values and
+       * dp->write_size will be MAX_SIZE, however on the first run dp->tsp
+       * starts off as 0.
+       */
+      assert(dp->write_size > 0U && dp->write_size < MAX_SIZE);
+
+      if (dp->stack[sp].best_size > dp->write_size ||
+          (dp->stack[sp].best_size == dp->write_size &&
+           compare_option(dp, sp) > 0))
+      {
+         dp->stack[sp].best_size = dp->write_size;
+         dp->stack[sp].best_val = dp->value[opt];
+      }
+
+      if (sp+1U >= dp->tsp)
+      {
+         next_opt(dp, sp);
+         ret = 1; /* advanced */
+      }
+
+      else if (!dp->stack[sp].end) /* Active, not at top of stack */
+         dp->nsp = sp+1U;
+
+      return ret; /* advanced || unchanged */
+   }
+}
+
+static int
+getallopts_(struct display *dp, png_byte opt, int *value, int record)
+   /* Like getop but iterate over all the values if the option was set to "all".
+    */
+{
+   if (dp->entry[opt]) /* option was set on command line */
+   {
+      /* Simple, single value, entries don't have a stack frame and have a fixed
+       * value (it doesn't change once set on the command line).  Otherwise the
+       * value (entry) selected from the command line is 'all':
+       */
+      const char *entry_name = options[opt].values[dp->entry[opt]-1].name;
+
+      if (entry_name == all)
+         (void)advance_opt(dp, opt, 0/*do not search; iterate*/);
+
+      else if (record)
+         record_opt(dp, opt, entry_name);
+
+      *value = dp->value[opt];
+      return 1; /* set */
+   }
+
+   else
+      return 0; /* not set */
+}
+
+static int
+getallopts(struct display *dp, const char *opt_str, int *value)
+{
+   return getallopts_(dp, option_index(dp, opt_str, strlen(opt_str)), value, 0);
+}
+
+static int
+getsearchopts(struct display *dp, const char *opt_str, int *value)
+   /* As above except that if the option was not set try a search */
+{
+   png_byte istrat;
+   png_byte opt = option_index(dp, opt_str, strlen(opt_str));
+   int record = options[opt].search;
+   const char *entry_name;
+
+   /* If it was set on the command line honour the setting, including 'all'
+    * which will override the built in search:
+    */
+   if (getallopts_(dp, opt, value, record))
+      return 1;
+
+   else if (!record) /* not a search option */
+      return 0; /* unset and not searched */
+
+   /* Otherwise decide what to do here. */
+   istrat = OPTIND(dp, strategy);
+   entry_name = range_lo; /* record the value, not the name */
+
+   if (opt == istrat) /* search all strategies */
+      (void)advance_opt(dp, opt, 0/*iterate*/), record=0;
+
+   else if (opt == OPTIND(dp, level))
+   {
+      /* Both RLE and HUFFMAN don't benefit from level increases */
+      if (dp->value[istrat] == Z_RLE || dp->value[istrat] == Z_HUFFMAN_ONLY)
+         dp->value[opt] = 1;
+
+      else /* fixed, filtered or default */
+         (void)advance_opt(dp, opt, 1/*search*/), record=0;
+   }
+
+   else if (opt == OPTIND(dp, windowBits))
+   {
+      /* Changing windowBits for strategies that do not search the window is
+       * pointless.  Huffman-only does not search, RLE only searches backwards
+       * one byte, so given that the maximum string length is 258, a windowBits
+       * of 9 is always sufficient.
+       */
+      if (dp->value[istrat] == Z_HUFFMAN_ONLY)
+         dp->value[opt] = 8;
+
+      else if (dp->value[istrat] == Z_RLE)
+         dp->value[opt] = 9;
+
+      else /* fixed, filtered or default */
+         (void)advance_opt(dp, opt, 1/*search*/), record=0;
+   }
+
+   else if (opt == OPTIND(dp, memLevel))
+   {
+#     if 0
+         (void)advance_opt(dp, opt, 0/*all*/), record=0;
+#     else
+         dp->value[opt] = MAX_MEM_LEVEL;
+#     endif
+   }
+
+   else /* something else */
+      assert(0=="reached");
+
+   if (record)
+      record_opt(dp, opt, entry_name);
+
+   /* One of the above searched options: */
+   *value = dp->value[opt];
+   return 1;
+}
+
+static int
+find_val(struct display *dp, png_byte opt, const char *str, size_t len)
+   /* Like option_index but sets (index+i) of the entry in options[opt] that
+    * matches str[0..len-1] into dp->entry[opt] as well as returning the actual
+    * value.
+    */
+{
+   int rlo = INT_MAX, rhi = INT_MIN;
+   png_byte j, irange = 0;
+
+   for (j=1U; j<=options[opt].value_count; ++j)
+   {
+      if (strncmp(options[opt].values[j-1U].name, str, len) == 0 &&
+          options[opt].values[j-1U].name[len] == 0)
+      {
+         dp->entry[opt] = j;
+         return options[opt].values[j-1U].value;
+      }
+      else if (options[opt].values[j-1U].name == range_lo)
+         rlo = options[opt].values[j-1U].value, irange = j;
+      else if (options[opt].values[j-1U].name == range_hi)
+         rhi = options[opt].values[j-1U].value;
+   }
+
+   /* No match on the name, but there may be a range. */
+   if (irange > 0)
+   {
+      char *ep = NULL;
+      long l = strtol(str, &ep, 0);
+
+      if (ep == str+len && l >= rlo && l <= rhi)
+      {
+         dp->entry[opt] = irange; /* range_lo */
+         return (int)/*SAFE*/l;
+      }
+   }
+
+   display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
+         "%s: unknown value setting '%.*s'", options[opt].name,
+         (int)/*SAFE*/len, str);
+   abort(); /* NOT REACHED */
+}
+
+static int
+opt_check(struct display *dp, const char *arg)
+{
+   assert(dp->errset == 0);
+
+   if (arg != NULL && arg[0] == '-' && arg[1] == '-')
+   {
+      int i = 0, negate = (strncmp(arg+2, "no-", 3) == 0), val;
+      png_byte j;
+
+      if (negate)
+         arg += 5; /* --no- */
+
+      else
+         arg += 2; /* -- */
+
+      /* Find the length (expect arg\0 or arg=) */
+      while (arg[i] != 0 && arg[i] != '=') ++i;
+
+      /* So arg[0..i-1] is the argument name, this does not return if this isn't
+       * a valid option name.
+       */
+      j = option_index(dp, arg, i);
+
+      /* It matcheth an option; check the remainder. */
+      if (arg[i] == 0) /* no specified value, use the default */
+      {
+         val = options[j].values[negate].value;
+         dp->entry[j] = (png_byte)/*SAFE*/(negate + 1U);
+      }
+
+      else
+      {
+         const char *list = arg + (i+1);
+
+         /* Expect a single value here unless this is a list, in which case
+          * multiple values are combined.
+          */
+         if (options[j].opt != LIST)
+         {
+            /* find_val sets 'dp->entry[j]' to a non-zero value: */
+            val = find_val(dp, j, list, strlen(list));
+
+            if (negate)
+            {
+               if (options[j].opt < OPTION)
+                  val = !val;
+
+               else
+               {
+                  display_log(dp, USER_ERROR,
+                        "%.*s: option=arg cannot be negated", i, arg);
+                  abort(); /* NOT REACHED */
+               }
+            }
+         }
+
+         else /* multiple options separated by ',' characters */
+         {
+            /* --no-option negates list values from the default, which should
+             * therefore be 'all'.  Notice that if the option list is empty in
+             * this case nothing will be removed and therefore --no-option= is
+             * the same as --option.
+             */
+            if (negate)
+               val = options[j].values[0].value;
+
+            else
+               val = 0;
+
+            while (*list != 0) /* allows option= which sets 0 */
+            {
+               /* A value is terminated by the end of the list or a ','
+                * character.
+                */
+               int v, iv;
+
+               iv = 0; /* an index into 'list' */
+               while (list[++iv] != 0 && list[iv] != ',') {}
+
+               v = find_val(dp, j, list, iv);
+
+               if (negate)
+                  val &= ~v;
+
+               else
+                  val |= v;
+
+               list += iv;
+               if (*list != 0)
+                  ++list; /* skip the ',' */
+            }
+         }
+      }
+
+      /* 'val' is the new value, store it for use later and debugging: */
+      dp->value[j] = val;
+
+      if (options[j].opt < LEVEL_MASK)
+      {
+         /* The handling for error levels is to set the level. */
+         if (val) /* Set this level */
+            dp->options = (dp->options & ~LEVEL_MASK) | options[j].opt;
+
+         else
+            display_log(dp, USER_ERROR,
+      "%.*s: messages cannot be turned off individually; set a message level",
+                  i, arg);
+      }
+
+      else if (options[j].opt < OPTION)
+      {
+         if (val)
+            dp->options |= options[j].opt;
+
+         else
+            dp->options &= ~options[j].opt;
+      }
+
+      return 1; /* this is an option */
+   }
+
+   else
+      return 0; /* not an option */
+}
+
+#ifdef PNG_PNGCP_TIMING_SUPPORTED
+static void
+set_timer(struct display *dp, struct timespec *timer)
+{
+   /* Do the timing using clock_gettime and the per-process timer. */
+   if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, timer))
+   {
+      display_log(dp, APP_ERROR,
+            "CLOCK_PROCESS_CPUTIME_ID: %s: timing disabled\n", strerror(errno));
+      dp->value[OPTIND(dp,time)] = 0; /* i.e. off */
+   }
+}
+
+static void
+start_timer(struct display *dp, int what)
+{
+   if ((dp->value[OPTIND(dp,time)] & what) != 0)
+      set_timer(dp, what == PNGCP_TIME_READ ? &dp->read_time : &dp->write_time);
+}
+
+static void
+end_timer(struct display *dp, int what)
+{
+   if ((dp->value[OPTIND(dp,time)] & what) != 0)
+   {
+      struct timespec t, tmp;
+
+      set_timer(dp, &t);
+
+      if (what == PNGCP_TIME_READ)
+         tmp = dp->read_time;
+
+      else
+         tmp = dp->write_time;
+
+      t.tv_sec -= tmp.tv_sec;
+      t.tv_nsec -= tmp.tv_nsec;
+
+      if (t.tv_nsec < 0)
+      {
+         --(t.tv_sec);
+         t.tv_nsec += 1000000000L;
+      }
+
+      if (what == PNGCP_TIME_READ)
+         dp->read_time = t, tmp = dp->read_time_total;
+
+      else
+         dp->write_time = t, tmp = dp->write_time_total;
+
+      tmp.tv_sec += t.tv_sec;
+      tmp.tv_nsec += t.tv_nsec;
+
+      if (tmp.tv_nsec >= 1000000000L)
+      {
+         ++(tmp.tv_sec);
+         tmp.tv_nsec -= 1000000000L;
+      }
+
+      if (what == PNGCP_TIME_READ)
+         dp->read_time_total = tmp;
+
+      else
+         dp->write_time_total = tmp;
+   }
+}
+
+static void
+print_time(const char *what, struct timespec t)
+{
+   printf("%s %.2lu.%.9ld", what, (unsigned long)t.tv_sec, t.tv_nsec);
+}
+#else /* !PNGCP_TIMING */
+#define start_timer(dp, what) ((void)0)
+#define end_timer(dp, what) ((void)0)
+#endif /* !PNGCP_TIMING */
+
+/* The following is used in main to verify that the final argument is a
+ * directory:
+ */
+static int
+checkdir(const char *pathname)
+{
+   struct stat buf;
+   return stat(pathname, &buf) == 0 && S_ISDIR(buf.st_mode);
+}
+
+/* Work out whether a path is valid (if not a display_log occurs), a directory
+ * (1 is returned) or a file *or* non-existent (0 is returned).
+ *
+ * Used for a write path.
+ */
+static int
+isdir(struct display *dp, const char *pathname)
+{
+   if (pathname == NULL)
+      return 0; /* stdout */
+
+   else if (pathname[0] == 0)
+      return 1; /* empty string */
+
+   else
+   {
+      struct stat buf;
+      int ret = stat(pathname, &buf);
+
+      if (ret == 0) /* the entry exists */
+      {
+         if (S_ISDIR(buf.st_mode))
+            return 1;
+
+         /* Else expect an object that exists and can be written: */
+         if (access(pathname, W_OK) != 0)
+            display_log(dp, USER_ERROR, "%s: cannot be written (%s)", pathname,
+                  strerror(errno));
+
+         return 0; /* file (exists, can be written) */
+      }
+
+      else /* an error */
+      {
+         /* Non-existence is fine, other errors are not: */
+         if (errno != ENOENT)
+            display_log(dp, USER_ERROR, "%s: invalid output name (%s)",
+                  pathname, strerror(errno));
+
+         return 0; /* file (does not exist) */
+      }
+   }
+}
+
+static void
+makename(struct display *dp, const char *dir, const char *infile)
+{
+   /* Make a name for an output file (and check it). */
+   dp->namebuf[0] = 0;
+
+   if (dir == NULL || infile == NULL)
+      display_log(dp, INTERNAL_ERROR, "NULL name to makename");
+
+   else
+   {
+      size_t dsize = strlen(dir);
+
+      if (dsize <= (sizeof dp->namebuf)-2) /* Allow for name + '/' + '\0' */
+      {
+         size_t isize = strlen(infile);
+         size_t istart = isize-1;
+
+         /* This should fail before here: */
+         if (infile[istart] == '/')
+            display_log(dp, INTERNAL_ERROR, "infile with trailing /");
+
+         memcpy(dp->namebuf, dir, dsize);
+         if (dsize > 0 && dp->namebuf[dsize-1] != '/')
+            dp->namebuf[dsize++] = '/';
+
+         /* Find the rightmost non-/ character: */
+         while (istart > 0 && infile[istart-1] != '/')
+            --istart;
+
+         isize -= istart;
+         infile += istart;
+
+         if (dsize+isize < (sizeof dp->namebuf)) /* dsize + infile + '\0' */
+         {
+            memcpy(dp->namebuf+dsize, infile, isize+1);
+
+            if (isdir(dp, dp->namebuf))
+               display_log(dp, USER_ERROR, "%s: output file is a directory",
+                     dp->namebuf);
+         }
+
+         else
+         {
+            dp->namebuf[dsize] = 0; /* allowed for: -2 at start */
+            display_log(dp, USER_ERROR, "%s%s: output file name too long",
+                  dp->namebuf, infile);
+         }
+      }
+
+      else
+         display_log(dp, USER_ERROR, "%s: output directory name too long", dir);
+   }
+}
+
+/* error handler callbacks for libpng */
+static void PNGCBAPI
+display_warning(png_structp pp, png_const_charp warning)
+{
+   struct display *dp = get_dp(pp);
+
+   /* This is used to prevent repeated warnings while searching */
+   if (!dp->no_warnings)
+      display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
+}
+
+static void PNGCBAPI
+display_error(png_structp pp, png_const_charp error)
+{
+   struct display *dp = get_dp(pp);
+
+   display_log(dp, LIBPNG_ERROR, "%s", error);
+}
+
+static void
+display_start_read(struct display *dp, const char *filename)
+{
+   if (filename != NULL)
+   {
+      dp->filename = filename;
+      dp->fp = fopen(filename, "rb");
+   }
+
+   else
+   {
+      dp->filename = "<stdin>";
+      dp->fp = stdin;
+   }
+
+   dp->w = dp->h = 0U;
+   dp->bpp = 0U;
+   dp->size = 0U;
+   dp->read_size = 0U;
+
+   if (dp->fp == NULL)
+      display_log(dp, USER_ERROR, "file open failed (%s)", strerror(errno));
+}
+
+static void PNGCBAPI
+read_function(png_structp pp, png_bytep data, size_t size)
+{
+   struct display *dp = get_dp(pp);
+
+   if (size == 0U || fread(data, size, 1U, dp->fp) == 1U)
+      dp->read_size += size;
+
+   else
+   {
+      if (feof(dp->fp))
+         display_log(dp, LIBPNG_ERROR, "PNG file truncated");
+      else
+         display_log(dp, LIBPNG_ERROR, "PNG file read failed (%s)",
+               strerror(errno));
+   }
+}
+
+static void
+read_png(struct display *dp, const char *filename)
+{
+   display_clean_read(dp); /* safety */
+   display_start_read(dp, filename);
+
+   dp->read_pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
+      display_error, display_warning);
+   if (dp->read_pp == NULL)
+      display_log(dp, LIBPNG_ERROR, "failed to create read struct");
+
+#  ifdef PNG_BENIGN_ERRORS_SUPPORTED
+      png_set_benign_errors(dp->read_pp, 1/*allowed*/);
+#  endif /* BENIGN_ERRORS */
+
+#  ifdef FIX_INDEX
+      if ((dp->options & FIX_INDEX) != 0)
+         png_set_check_for_invalid_index(dp->read_pp, 1/*on, no warning*/);
+#     ifdef IGNORE_INDEX
+         else
+#     endif /* IGNORE_INDEX */
+#  endif /* FIX_INDEX */
+#  ifdef IGNORE_INDEX
+      if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
+         png_set_check_for_invalid_index(dp->read_pp, -1/*off completely*/);
+#  endif /* IGNORE_INDEX */
+
+   /* The png_read_png API requires us to make the info struct, but it does the
+    * call to png_read_info.
+    */
+   dp->ip = png_create_info_struct(dp->read_pp);
+   if (dp->ip == NULL)
+      png_error(dp->read_pp, "failed to create info struct");
+
+   /* Set the IO handling */
+   png_set_read_fn(dp->read_pp, dp, read_function);
+
+#  ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      png_set_keep_unknown_chunks(dp->read_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
+            0);
+#  endif /* HANDLE_AS_UNKNOWN */
+
+#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
+      /* Remove the user limits, if any */
+      png_set_user_limits(dp->read_pp, 0x7fffffff, 0x7fffffff);
+#  endif /* SET_USER_LIMITS */
+
+   /* Now read the PNG. */
+   start_timer(dp, PNGCP_TIME_READ);
+   png_read_png(dp->read_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
+   end_timer(dp, PNGCP_TIME_READ);
+   dp->w = png_get_image_width(dp->read_pp, dp->ip);
+   dp->h = png_get_image_height(dp->read_pp, dp->ip);
+   dp->ct = png_get_color_type(dp->read_pp, dp->ip);
+   dp->bpp = png_get_bit_depth(dp->read_pp, dp->ip) *
+             png_get_channels(dp->read_pp, dp->ip);
+   {
+      /* png_get_rowbytes should never return 0 because the value is set by the
+       * first call to png_set_IHDR, which should have happened by now, but just
+       * in case:
+       */
+      png_alloc_size_t rb = png_get_rowbytes(dp->read_pp, dp->ip);
+
+      if (rb == 0)
+         png_error(dp->read_pp, "invalid row byte count from libpng");
+
+      /* The size calc can overflow. */
+      if ((MAX_SIZE-dp->h)/rb < dp->h)
+         png_error(dp->read_pp, "image too large");
+
+      dp->size = rb * dp->h + dp->h/*filter byte*/;
+   }
+
+#ifdef FIX_INDEX
+   if (dp->ct == PNG_COLOR_TYPE_PALETTE && (dp->options & FIX_INDEX) != 0)
+   {
+      int max = png_get_palette_max(dp->read_pp, dp->ip);
+      png_colorp palette = NULL;
+      int num = -1;
+
+      if (png_get_PLTE(dp->read_pp, dp->ip, &palette, &num) != PNG_INFO_PLTE
+          || max < 0 || num <= 0 || palette == NULL)
+         display_log(dp, LIBPNG_ERROR, "invalid png_get_PLTE result");
+
+      if (max >= num)
+      {
+         /* 'Fix' the palette. */
+         int i;
+         png_color newpal[256];
+
+         for (i=0; i<num; ++i)
+            newpal[i] = palette[i];
+
+         /* Fill in any remainder with a warning color: */
+         for (; i<=max; ++i)
+         {
+            newpal[i].red = 0xbe;
+            newpal[i].green = 0xad;
+            newpal[i].blue = 0xed;
+         }
+
+         png_set_PLTE(dp->read_pp, dp->ip, newpal, i);
+      }
+   }
+#endif /* FIX_INDEX */
+
+   display_clean_read(dp);
+   dp->operation = "none";
+}
+
+static void
+display_start_write(struct display *dp, const char *filename)
+{
+   assert(dp->fp == NULL);
+
+   if ((dp->options & NOWRITE) != 0)
+      dp->output_file = "<no write>";
+
+   else
+   {
+      if (filename != NULL)
+      {
+         dp->output_file = filename;
+         dp->fp = fopen(filename, "wb");
+      }
+
+      else
+      {
+         dp->output_file = "<stdout>";
+         dp->fp = stdout;
+      }
+
+      if (dp->fp == NULL)
+         display_log(dp, USER_ERROR, "%s: file open failed (%s)",
+               dp->output_file, strerror(errno));
+   }
+}
+
+static void PNGCBAPI
+write_function(png_structp pp, png_bytep data, size_t size)
+{
+   struct display *dp = get_dp(pp);
+
+   /* The write fail is classed as a USER_ERROR, so --quiet does not turn it
+    * off, this seems more likely to be correct.
+    */
+   if (dp->fp == NULL || fwrite(data, size, 1U, dp->fp) == 1U)
+   {
+      dp->write_size += size;
+      if (dp->write_size < size || dp->write_size == MAX_SIZE)
+         png_error(pp, "IDAT size overflow");
+   }
+
+   else
+      display_log(dp, USER_ERROR, "%s: PNG file write failed (%s)",
+            dp->output_file, strerror(errno));
+}
+
+/* Compression option, 'method' is never set: there is no choice.
+ *
+ * IMPORTANT: the order of the entries in this macro determines the preference
+ * order when two different combos of two of these options produce an IDAT of
+ * the same size.  The logic here is to put the things that affect the decoding
+ * of the PNG image ahead of those that are relevant only to the encoding.
+ */
+#define SET_COMPRESSION\
+   SET(strategy, strategy);\
+   SET(windowBits, window_bits);\
+   SET(level, level);\
+   SET(memLevel, mem_level);
+
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+static void
+search_compression(struct display *dp)
+{
+   /* Like set_compression below but use a more restricted search than 'all' */
+   int val;
+
+#  define SET(name, func) if (getsearchopts(dp, #name, &val))\
+      png_set_compression_ ## func(dp->write_pp, val);
+   SET_COMPRESSION
+#  undef SET
+}
+
+static void
+set_compression(struct display *dp)
+{
+   int val;
+
+#  define SET(name, func) if (getallopts(dp, #name, &val))\
+      png_set_compression_ ## func(dp->write_pp, val);
+   SET_COMPRESSION
+#  undef SET
+}
+
+#ifdef PNG_SW_COMPRESS_level /* 1.7.0+ */
+static void
+set_ICC_profile_compression(struct display *dp)
+{
+   int val;
+
+#  define SET(name, func) if (getallopts(dp, "ICC-profile-" #name, &val))\
+      png_set_ICC_profile_compression_ ## func(dp->write_pp, val);
+   SET_COMPRESSION
+#  undef SET
+}
+#else
+#  define set_ICC_profile_compression(dp) ((void)0)
+#endif
+#else
+#  define search_compression(dp) ((void)0)
+#  define set_compression(dp) ((void)0)
+#  define set_ICC_profile_compression(dp) ((void)0)
+#endif /* WRITE_CUSTOMIZE_COMPRESSION */
+
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+static void
+set_text_compression(struct display *dp)
+{
+   int val;
+
+#  define SET(name, func) if (getallopts(dp, "text-" #name, &val))\
+      png_set_text_compression_ ## func(dp->write_pp, val);
+   SET_COMPRESSION
+#  undef SET
+}
+#else
+#  define set_text_compression(dp) ((void)0)
+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+
+static void
+write_png(struct display *dp, const char *destname)
+{
+   display_clean_write(dp); /* safety */
+   display_start_write(dp, destname);
+
+   dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
+      display_error, display_warning);
+
+   if (dp->write_pp == NULL)
+      display_log(dp, LIBPNG_ERROR, "failed to create write png_struct");
+
+#  ifdef PNG_BENIGN_ERRORS_SUPPORTED
+      png_set_benign_errors(dp->write_pp, 1/*allowed*/);
+#  endif /* BENIGN_ERRORS */
+
+   png_set_write_fn(dp->write_pp, dp, write_function, NULL/*flush*/);
+
+#ifdef IGNORE_INDEX
+   if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
+      png_set_check_for_invalid_index(dp->write_pp, -1/*off completely*/);
+#endif /* IGNORE_INDEX */
+
+   /* Restore the text chunks when using libpng 1.6 or less; this is a macro
+    * which expands to nothing in 1.7+  In earlier versions it tests
+    * dp->text_stashed, which is only set (below) *after* the first write.
+    */
+   text_restore(dp);
+
+#  ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+      png_set_keep_unknown_chunks(dp->write_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
+            0);
+#  endif /* HANDLE_AS_UNKNOWN */
+
+#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
+      /* Remove the user limits, if any */
+      png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
+#  endif
+
+   /* OPTION HANDLING */
+   /* compression outputs, IDAT and zTXt/iTXt: */
+   dp->tsp = dp->nsp;
+   dp->nsp = dp->csp = 0;
+#  ifdef PNG_SW_COMPRESS_png_level
+      {
+         int val;
+
+         /* This sets everything, but then the following options just override
+          * the specific settings for ICC profiles and text.
+          */
+         if (getallopts(dp, "compression", &val))
+            png_set_compression(dp->write_pp, val);
+
+         if (getallopts(dp, "ICC-profile-compression", &val))
+            png_set_ICC_profile_compression(dp->write_pp, val);
+
+         if (getallopts(dp, "text-compression", &val))
+            png_set_text_compression(dp->write_pp, val);
+      }
+#  endif /* png_level support */
+   if (dp->options & SEARCH)
+      search_compression(dp);
+   else
+      set_compression(dp);
+   set_ICC_profile_compression(dp);
+   set_text_compression(dp);
+
+   {
+      int val;
+
+      /* The permitted range is 1..0x7FFFFFFF, so the cast is safe */
+      if (get_option(dp, "IDAT-size", &val))
+         png_set_IDAT_size(dp->write_pp, val);
+   }
+
+   /* filter handling */
+#  ifdef PNG_WRITE_FILTER_SUPPORTED
+      {
+         int val;
+
+         if (get_option(dp, "filter", &val))
+            png_set_filter(dp->write_pp, PNG_FILTER_TYPE_BASE, val);
+      }
+#  endif /* WRITE_FILTER */
+
+   /* This just uses the 'read' info_struct directly, it contains the image. */
+   dp->write_size = 0U;
+   start_timer(dp, PNGCP_TIME_WRITE);
+   png_write_png(dp->write_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
+   end_timer(dp, PNGCP_TIME_WRITE);
+
+   /* Make sure the file was written ok: */
+   if (dp->fp != NULL)
+   {
+      FILE *fp = dp->fp;
+      dp->fp = NULL;
+      if (fclose(fp))
+         display_log(dp, APP_ERROR, "%s: write failed (%s)",
+               destname == NULL ? "stdout" : destname, strerror(errno));
+   }
+
+   /* Clean it on the way out - if control returns to the caller then the
+    * written_file contains the required data.
+    */
+   display_clean_write(dp);
+   dp->operation = "none";
+}
+
+static void
+set_windowBits_hi(struct display *dp)
+{
+   /* windowBits is in the range 8..15 but zlib maps '8' to '9' so it is only
+    * worth using if the data size is 256 byte or less.
+    */
+   int wb = MAX_WBITS; /* for large images */
+   int i = VLSIZE(windowBits_IDAT);
+
+   while (wb > 8 && dp->size <= 1U<<(wb-1)) --wb;
+
+   while (--i >= 0) if (VLNAME(windowBits_IDAT)[i].name == range_hi) break;
+
+   assert(i > 1); /* vl_windowBits_IDAT always has a RANGE() */
+   VLNAME(windowBits_IDAT)[i].value = wb;
+
+   assert(VLNAME(windowBits_IDAT)[--i].name == range_lo);
+   VLNAME(windowBits_IDAT)[i].value = wb > 8 ? 9 : 8;
+
+   /* If wb == 8 then any search has been restricted to just one windowBits
+    * entry.  Record that here to avoid producing a spurious app-level warning
+    * above.
+    */
+   if (wb == 8)
+      dp->min_windowBits = OPTIND(dp, windowBits);
+}
+
+static int
+better_options(const struct display *dp)
+{
+   /* Are these options better than the best found so far?  Normally the
+    * options are tested in preference order, best first, however when doing a
+    * search operation on a range the range values are tested out of order.  In
+    * that case preferable options will get tested later.
+    *
+    * This function looks through the stack from the bottom up looking for an
+    * option that does not match the current best value.  When it finds one it
+    * checks to see if it is more or less desirable and returns true or false
+    * as appropriate.
+    *
+    * Notice that this means that the order options are pushed onto the stack
+    * conveys a priority; lower/earlier options are more important than later
+    * ones.
+    */
+   unsigned int sp;
+
+   for (sp=0; sp<dp->csp; ++sp)
+   {
+      int c = compare_option(dp, sp);
+
+      if (c < 0)
+         return 0; /* worse */
+
+      else if (c > 0)
+         return 1; /* better */
+   }
+
+   assert(0 && "unreached");
+}
+
+static void
+print_search_results(struct display *dp)
+{
+   assert(dp->filename != NULL);
+   printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu with '%s'\n",
+      dp->filename, (unsigned long)dp->w, (unsigned long)dp->h, dp->bpp,
+      cts(dp->ct), (unsigned long)dp->size, (unsigned long)dp->read_size,
+      (unsigned long)dp->best_size, dp->best);
+   fflush(stdout);
+}
+
+static void
+log_search(struct display *dp, unsigned int log_depth)
+{
+   /* Log, and reset, the search so far: */
+   if (dp->nsp/*next entry to change*/ <= log_depth)
+   {
+      print_search_results(dp);
+      /* Start again with this entry: */
+      dp->best_size = MAX_SIZE;
+   }
+}
+
+static void
+cp_one_file(struct display *dp, const char *filename, const char *destname)
+{
+   unsigned int log_depth;
+
+   dp->filename = filename;
+   dp->operation = "read";
+   dp->no_warnings = 0;
+
+   /* Read it then write it: */
+   if (filename != NULL && access(filename, R_OK) != 0)
+      display_log(dp, USER_ERROR, "%s: invalid file name (%s)",
+            filename, strerror(errno));
+
+   read_png(dp, filename);
+
+   /* But 'destname' may be a directory. */
+   dp->operation = "write";
+
+   /* Limit the upper end of the windowBits range for this file */
+   set_windowBits_hi(dp);
+
+   /* For logging, depth to log: */
+   {
+      int val;
+
+      if (get_option(dp, "log-depth", &val) && val >= 0)
+         log_depth = (unsigned int)/*SAFE*/val;
+
+      else
+         log_depth = 0U;
+   }
+
+   if (destname != NULL) /* else stdout */
+   {
+      if (isdir(dp, destname))
+      {
+         makename(dp, destname, filename);
+         destname = dp->namebuf;
+      }
+
+      else if (access(destname, W_OK) != 0 && errno != ENOENT)
+         display_log(dp, USER_ERROR, "%s: invalid output name (%s)", destname,
+               strerror(errno));
+   }
+
+   dp->nsp = 0;
+   dp->curr[0] = 0; /* acts as a flag for the caller */
+   dp->opt_string_start = 0;
+   dp->best[0] = 0; /* safety */
+   dp->best_size = MAX_SIZE;
+   write_png(dp, destname);
+
+   /* Initialize the 'best' fields: */
+   strcpy(dp->best, dp->curr);
+   dp->best_size = dp->write_size;
+
+   if (dp->nsp > 0) /* iterating over lists */
+   {
+      char *tmpname, tmpbuf[(sizeof dp->namebuf) + 4];
+      assert(dp->curr[0] == ' ' && dp->tsp > 0);
+
+      /* Cancel warnings on subsequent writes */
+      log_search(dp, log_depth);
+      dp->no_warnings = 1;
+
+      /* Make a temporary name for the subsequent tests: */
+      if (destname != NULL)
+      {
+         strcpy(tmpbuf, destname);
+         strcat(tmpbuf, ".tmp"); /* space for .tmp allocated above */
+         tmpname = tmpbuf;
+      }
+
+      else
+         tmpname = NULL; /* stdout */
+
+      /* Loop to find the best option. */
+      do
+      {
+         write_png(dp, tmpname);
+
+         /* And compare the sizes (the write function makes sure write_size
+          * doesn't overflow.)
+          */
+         assert(dp->csp > 0);
+
+         if (dp->write_size < dp->best_size ||
+             (dp->write_size == dp->best_size && better_options(dp)))
+         {
+            if (destname != NULL && rename(tmpname, destname) != 0)
+               display_log(dp, APP_ERROR, "rename %s %s failed (%s)", tmpname,
+                     destname, strerror(errno));
+
+            strcpy(dp->best, dp->curr);
+            dp->best_size = dp->write_size;
+         }
+
+         else if (tmpname != NULL && unlink(tmpname) != 0)
+            display_log(dp, APP_WARNING, "unlink %s failed (%s)", tmpname,
+                  strerror(errno));
+
+         log_search(dp, log_depth);
+      }
+      while (dp->nsp > 0);
+
+      /* Do this for the 'sizes' option so that it reports the correct size. */
+      dp->write_size = dp->best_size;
+   }
+}
+
+static int
+cppng(struct display *dp, const char *file, const char *gv dest)
+   /* Exists solely to isolate the setjmp clobbers which some versions of GCC
+    * erroneously generate.
+    */
+{
+   int ret = setjmp(dp->error_return);
+
+   if (ret == 0)
+   {
+      dp->errset = 1;
+      cp_one_file(dp, file, dest);
+      dp->errset = 0;
+      return 0;
+   }
+
+   else
+   {
+      dp->errset = 0;
+
+      if (ret < ERRORS) /* shouldn't longjmp on warnings */
+         display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
+
+      return ret;
+   }
+}
+
+int
+main(int argc, char **argv)
+{
+   /* For each file on the command line test it with a range of transforms */
+   int option_end;
+   struct display d;
+
+   display_init(&d);
+
+   d.operation = "options";
+   for (option_end = 1;
+        option_end < argc && opt_check(&d, argv[option_end]);
+        ++option_end)
+   {
+   }
+
+   /* Do a quick check on the directory target case; when there are more than
+    * two arguments the last one must be a directory.
+    */
+   if (!(d.options & NOWRITE) && option_end+2 < argc && !checkdir(argv[argc-1]))
+   {
+      fprintf(stderr,
+            "pngcp: %s: directory required with more than two arguments\n",
+            argv[argc-1]);
+      return 99;
+   }
+
+   {
+      int errors = 0;
+      int i = option_end;
+
+      /* Do this at least once; if there are no arguments stdin/stdout are used.
+       */
+      d.operation = "files";
+      do
+      {
+         const char *infile = NULL;
+         const char *outfile = NULL;
+         int ret;
+
+         if (i < argc)
+         {
+            infile = argv[i++];
+            if (!(d.options & NOWRITE) && i < argc)
+               outfile = argv[argc-1];
+         }
+
+         ret = cppng(&d, infile, outfile);
+
+         if (ret)
+         {
+            if (ret > QUIET) /* abort on user or internal error */
+               return 99;
+
+            /* An error: the output is meaningless */
+         }
+
+         else if (d.best[0] != 0)
+         {
+            /* This result may already have been output, in which case best_size
+             * has been reset.
+             */
+            if (d.best_size < MAX_SIZE)
+               print_search_results(&d);
+         }
+
+         else if (d.options & SIZES)
+         {
+            printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu [0x%lx]\n",
+                  infile, (unsigned long)d.w, (unsigned long)d.h, d.bpp,
+                  cts(d.ct), (unsigned long)d.size, (unsigned long)d.read_size,
+                  (unsigned long)d.write_size, (unsigned long)d.results);
+            fflush(stdout);
+         }
+
+         /* Here on any return, including failures, except user/internal issues
+          */
+         {
+            int pass = (d.options & STRICT) ?
+               RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
+
+            if (!pass)
+               ++errors;
+
+            if (d.options & LOG)
+            {
+               int j;
+
+               printf("%s: pngcp", pass ? "PASS" : "FAIL");
+
+               for (j=1; j<option_end; ++j)
+                  printf(" %s", argv[j]);
+
+               if (infile != NULL)
+                  printf(" %s", infile);
+
+#              ifdef PNG_PNGCP_TIMING_SUPPORTED
+                  /* When logging output the files for each file, if enabled. */
+                  if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
+                     print_time(" read", d.read_time);
+
+                  if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
+                     print_time(" write", d.write_time);
+#              endif /* PNGCP_TIMING */
+
+               printf("\n");
+               fflush(stdout);
+            }
+         }
+
+         display_clean(&d);
+      }
+      while (i+!(d.options & NOWRITE) < argc);
+         /* I.e. for write cases after the first time through the loop require
+          * there to be at least two arguments left and for the last one to be a
+          * directory (this was checked above).
+          */
+
+      /* Release allocated memory */
+      display_destroy(&d);
+
+#     ifdef PNG_PNGCP_TIMING_SUPPORTED
+         {
+            int output = 0;
+
+            if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
+               print_time("read", d.read_time_total), output = 1;
+
+            if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
+            {
+               if (output) putchar(' ');
+               print_time("write", d.write_time_total);
+               output = 1;
+            }
+
+            if (output) putchar('\n');
+         }
+#     endif /* PNGCP_TIMING */
+
+      return errors != 0;
+   }
+}
+#else /* !READ_PNG || !WRITE_PNG */
+int
+main(void)
+{
+   fprintf(stderr, "pngcp: no support for png_read/write_image\n");
+   return 77;
+}
+#endif /* !READ_PNG || !WRITE_PNG */
index b2043e3..2fa5d13 100644 (file)
@@ -1,8 +1,7 @@
 /* pngfix.c
  *
- * Copyright (c) 2014-2016 John Cunningham Bowler
- *
- * Last changed in libpng 1.6.21 [January 15, 2016]
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Copyright (c) 2014-2017 John Cunningham Bowler
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -773,7 +772,7 @@ skip_chunk_type(const struct global *global, png_uint_32 type)
          return 0;
 
       /* Chunks that specify gamma encoding which should therefore only be
-       * removed the the user insists:
+       * removed if the user insists:
        */
       case png_gAMA: case png_sRGB:
          if (global->skip >= SKIP_ALL)
@@ -1824,7 +1823,7 @@ IDAT_init(struct IDAT * const idat, struct file * const file)
 }
 
 static png_uint_32
-rechunk_length(struct IDAT *idat)
+rechunk_length(struct IDAT *idat, int start)
    /* Return the length for the next IDAT chunk, taking into account
     * rechunking.
     */
@@ -1836,7 +1835,7 @@ rechunk_length(struct IDAT *idat)
       const struct IDAT_list *cur;
       unsigned int count;
 
-      if (idat->idat_index == 0) /* at the new chunk (first time) */
+      if (start)
          return idat->idat_length; /* use the cache */
 
       /* Otherwise rechunk_length is called at the end of a chunk for the length
@@ -1995,7 +1994,7 @@ process_IDAT(struct file *file)
       idat->idat_index = 0; /* Index into chunk data */
 
       /* Update the chunk length to the correct value for the IDAT chunk: */
-      file->chunk->chunk_length = rechunk_length(idat);
+      file->chunk->chunk_length = rechunk_length(idat, 1/*start*/);
 
       /* Change the state to writing IDAT chunks */
       file->state = STATE_IDAT;
@@ -2364,7 +2363,7 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes)
       flush = Z_NO_FLUSH;
       out_bytes = 0;
 
-      /* NOTE: expression 3 is only evaluted on 'continue', because of the
+      /* NOTE: expression 3 is only evaluated on 'continue', because of the
        * 'break' at the end of this loop below.
        */
       for (;endrc == ZLIB_OK;
@@ -2416,7 +2415,7 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes)
                   endrc = ZLIB_TOO_FAR_BACK;
                   break;
                }
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             default:
                zlib_message(zlib, 0/*stream error*/);
@@ -2515,7 +2514,7 @@ zlib_run(struct zlib *zlib)
        */
       for (;;)
       {
-         const unsigned int count = list->count;
+         unsigned int count = list->count;
          unsigned int i;
 
          for (i = 0; i<count; ++i)
@@ -2570,7 +2569,7 @@ zlib_run(struct zlib *zlib)
                   list->lengths[i] -= zlib->extra_bytes;
                   list->count = i+1;
                   zlib->idat->idat_list_tail = list;
-                  /* FALL THROUGH */
+                  /* FALLTHROUGH */
 
                default:
                   return rc;
@@ -2665,7 +2664,7 @@ zlib_check(struct file *file, png_uint_32 offset)
              * this case, so do the optimization anyway.
              */
             if (zlib.cksum)
-               chunk_message(zlib.chunk, "zlib checkum");
+               chunk_message(zlib.chunk, "zlib checksum");
             break;
 
 
@@ -2673,7 +2672,7 @@ zlib_check(struct file *file, png_uint_32 offset)
             /* Truncated stream; unrecoverable, gets converted to ZLIB_FATAL */
             zlib.z.msg = PNGZ_MSG_CAST("[truncated]");
             zlib_message(&zlib, 0/*expected*/);
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
          default:
             /* Unrecoverable error; skip the chunk; a zlib_message has already
@@ -2792,7 +2791,7 @@ process_chunk(struct file *file, png_uint_32 file_crc, png_uint_32 next_length,
     * to read_chunk.
     */
 {
-   const png_uint_32 type = file->type;
+   png_uint_32 type = file->type;
 
    if (file->global->verbose > 1)
    {
@@ -3153,7 +3152,7 @@ read_chunk(struct file *file)
       }
    }
 
-   /* Control gets to here if the the stream seems invalid or damaged in some
+   /* Control gets to here if the stream seems invalid or damaged in some
     * way.  Either there was a problem reading all the expected data (this
     * chunk's data, its CRC and the length and type of the next chunk) or the
     * next chunk length/type are invalid.  Notice that the cases that end up
@@ -3341,7 +3340,7 @@ read_callback(png_structp png_ptr, png_bytep buffer, size_t count)
                if (file->state != STATE_IDAT && length > 0)
                   setpos(chunk);
             }
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
          default:
             assert(chunk != NULL);
@@ -3473,7 +3472,8 @@ read_callback(png_structp png_ptr, png_bytep buffer, size_t count)
                      /* Write another IDAT chunk.  Call rechunk_length to
                       * calculate the length required.
                       */
-                     length = chunk->chunk_length = rechunk_length(file->idat);
+                     length = chunk->chunk_length =
+                         rechunk_length(file->idat, 0/*end*/);
                      assert(type == png_IDAT);
                      file->write_count = 0; /* for the new chunk */
                      --(file->write_count); /* fake out the increment below */
@@ -3678,7 +3678,7 @@ usage(const char *prog)
    size_t i;
    static const char *usage_string[] = {
 "  Tests, optimizes and optionally fixes the zlib header in PNG files.",
-"  Optionally, when fixing, strips ancilliary chunks from the file.",
+"  Optionally, when fixing, strips ancillary chunks from the file.",
 0,
 "OPTIONS",
 "  OPERATION",
@@ -3710,7 +3710,7 @@ usage(const char *prog)
 "            practice most programs will ignore it.",
 "        bKGD [transform]: This is used by libpng transforms."
 "    --max=<number>:",
-"      Use IDAT chunks sized <number>.  If no number is given the the IDAT",
+"      Use IDAT chunks sized <number>.  If no number is given the IDAT",
 "      chunks will be the maximum size permitted; 2^31-1 bytes.  If the option",
 "      is omitted the original chunk sizes will not be changed.  When the",
 "      option is given --strip=unsafe is set automatically. This may be",
diff --git a/contrib/tools/reindent b/contrib/tools/reindent
new file mode 100755 (executable)
index 0000000..f4df309
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# reindent a libpng C source
+
+# COPYRIGHT: Written by Glenn Randers-Pehrson, 2016.
+# To the extent possible under law, the author has waived all copyright and
+# related or neighboring rights to this work.  This work is published from:
+# United States.
+
+# Usage:
+# reindent inputtabsize outputtabsize inputcontinuestring outputcontinuestring
+#
+# Assumes that continued lines begin with indentation plus one space, and
+# that continued comments begin with indentation plus " *".
+#
+# eg, to change libpng coding style from 3-space indentation with 4-space
+# continuations to 4-space indentation with 2-space continuations:
+#
+#  reindent 3 4 "\t " "  " < example.c > example.c_4_2
+# and to restore the file back to libpng coding style
+#  reindent 4 3 "  " "    " < example.c_4_2 > example.c_3_4
+
+unexpand --first-only --t $1 | \
+   sed -e "/^  *$3[^\*]/{s/$3/$4/}" | \
+   expand -t $2
index 22c8f7c..d1ece51 100644 (file)
@@ -14,7 +14,7 @@
  * All routines take and return a floating point value in the range
  * 0 to 1.0, doing a calculation according to the sRGB specification
  * (in fact the source of the numbers is the wikipedia article at
- * http://en.wikipedia.org/wiki/SRGB).
+ * https://en.wikipedia.org/wiki/SRGB).
  */
 static double
 sRGB_from_linear(double l)
index dcde18a..cf943f3 100644 (file)
@@ -2,7 +2,7 @@
  *  PNGFILE.C -- Image File Functions
  *-------------------------------------
  *
- * Copyright 2000, Willem van Schaik.
+ * Copyright 2000,2017 Willem van Schaik.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -236,6 +236,10 @@ BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,
             free (pbImageData);
             pbImageData = NULL;
         }
+        if ((*piHeight) > ((size_t)(-1))/ulRowBytes) {
+        {
+            png_error(png_ptr, "Visual PNG: image is too big");
+        }
         if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight)
                             * sizeof(png_byte))) == NULL)
         {
@@ -406,15 +410,14 @@ BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,
 #ifndef PNG_STDIO_SUPPORTED
 
 static void
-png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+png_read_data(png_structp png_ptr, png_bytep data, size_t length)
 {
-   png_size_t check;
+   size_t check;
 
-   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+   /* fread() returns 0 on error, so it is OK to store this in a size_t
     * instead of an int, which is what fread() actually returns.
     */
-   check = (png_size_t)fread(data, (png_size_t)1, length,
-      (FILE *)png_ptr->io_ptr);
+   check = fread(data, 1, length, (FILE *)png_ptr->io_ptr);
 
    if (check != length)
    {
@@ -423,7 +426,7 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
 }
 
 static void
-png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+png_write_data(png_structp png_ptr, png_bytep data, size_t length)
 {
    png_uint_32 check;
 
index 474426c..1b7b9be 100644 (file)
@@ -23,8 +23,8 @@ BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,
                    int iWidth, int iHeight, png_color BkgColor);
 
 #ifndef PNG_STDIO_SUPPORTED
-static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length);
-static void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length);
+static void png_read_data(png_structp png_ptr, png_bytep data, size_t length);
+static void png_write_data(png_structp png_ptr, png_bytep data, size_t length);
 static void png_flush(png_structp png_ptr);
 #endif
 
index 236525a..6baa3b6 100644 (file)
@@ -2,7 +2,7 @@
  *  VisualPng.C -- Shows a PNG image
  *------------------------------------
  *
- * Copyright 2000, Willem van Schaik.
+ * Copyright 2000,2017 Willem van Schaik.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -716,7 +716,7 @@ BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
     png_color                   bkgGray  = {127, 127, 127};
     png_color                   bkgWhite = {255, 255, 255};
 
-    /* allocate memory for the Device Independant bitmap */
+    /* allocate memory for the Device Independent bitmap */
 
     wDIRowBytes = (WORD) ((3 * cxWinSize + 3L) >> 2) << 2;
 
@@ -726,6 +726,10 @@ BOOL DisplayImage (HWND hwnd, BYTE **ppDib,
         pDib = NULL;
     }
 
+    if (cyWinSize > ((size_t)(-1))/wDIRowBytes) {
+    {
+        MessageBox (hwnd, TEXT ("Visual PNG: image is too big");
+    }
     if (!(pDib = (BYTE *) malloc (sizeof(BITMAPINFOHEADER) +
         wDIRowBytes * cyWinSize)))
     {
@@ -847,6 +851,10 @@ BOOL FillBitmap (
             cxImgPos = (cxWinSize - cxNewSize) / 2;
         }
 
+        if (cyNewSize > ((size_t)(-1))/(cImgChannels * cxNewSize)) {
+        {
+            MessageBox (hwnd, TEXT ("Visual PNG: stretched image is too big");
+        }
         pStretchedImage = malloc (cImgChannels * cxNewSize * cyNewSize);
         pImg = pStretchedImage;
 
diff --git a/depcomp b/depcomp
index fc98710..65cbf70 100755 (executable)
--- a/depcomp
+++ b/depcomp
@@ -1,9 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2013-05-30.07; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ scriptversion=2013-05-30.07; # UTC
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -783,9 +783,9 @@ exit 0
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
index f8591e6..2e2afaa 100644 (file)
--- a/example.c
+++ b/example.c
@@ -2,18 +2,20 @@
 #if 0 /* in case someone actually tries to compile this */
 
 /* example.c - an example of using libpng
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Maintained 1998-2014 Glenn Randers-Pehrson
- * Maintained 1996, 1997 Andreas Dilger)
- * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Maintained 2018 Cosmin Truta
+ * Maintained 1998-2016 Glenn Randers-Pehrson
+ * Maintained 1996-1997 Andreas Dilger
+ * Written 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ *
  * To the extent possible under law, the authors have waived
  * all copyright and related or neighboring rights to this file.
- * This work is published from: United States.
+ * This work is published from: United States, Canada.
  */
 
 /* This is an example of how to use libpng to read and write PNG files.
- * The file libpng-manual.txt is much more verbose then this.  If you have not
- * read it, do so first.  This was designed to be a starting point of an
+ * The file libpng-manual.txt is much more verbose then this.  If you have
+ * not read it, do so first.  This was designed to be a starting point of an
  * implementation.  This is not officially part of libpng, is hereby placed
  * in the public domain, and therefore does not require a copyright notice.
  *
  * see also the programs in the contrib directory.
  */
 
-/* The simple, but restricted, approach to reading a PNG file or data stream
- * just requires two function calls, as in the following complete program.
- * Writing a file just needs one function call, so long as the data has an
+/* The simple, but restricted approach to reading a PNG file or data stream
+ * requires just two function calls, as in the following complete program.
+ * Writing a file needs just one function call, so long as the data has an
  * appropriate layout.
  *
  * The following code reads PNG image data from a file and writes it, in a
- * potentially new format, to a new file.  While this code will compile there is
- * minimal (insufficient) error checking; for a more realistic version look at
- * contrib/examples/pngtopng.c
+ * potentially new format, to a new file.  While this code will compile, there
+ * is minimal (insufficient) error checking.  For a more realistic version,
+ * see contrib/examples/pngtopng.c
  */
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
@@ -68,28 +71,28 @@ int main(int argc, const char **argv)
           */
          buffer = malloc(PNG_IMAGE_SIZE(image));
 
-         /* If enough memory was available read the image in the desired format
-          * then write the result out to the new file.  'background' is not
-          * necessary when reading the image because the alpha channel is
+         /* If enough memory was available, read the image in the desired
+          * format, then write the result out to the new file.  'background' is
+          * not necessary when reading the image, because the alpha channel is
           * preserved; if it were to be removed, for example if we requested
           * PNG_FORMAT_RGB, then either a solid background color would have to
-          * be supplied or the output buffer would have to be initialized to the
-          * actual background of the image.
+          * be supplied, or the output buffer would have to be initialized to
+          * the actual background of the image.
           *
           * The fourth argument to png_image_finish_read is the 'row_stride' -
           * this is the number of components allocated for the image in each
           * row.  It has to be at least as big as the value returned by
           * PNG_IMAGE_ROW_STRIDE, but if you just allocate space for the
-          * default, minimum, size using PNG_IMAGE_SIZE as above you can pass
+          * default, minimum size, using PNG_IMAGE_SIZE as above, you can pass
           * zero.
           *
           * The final argument is a pointer to a buffer for the colormap;
-          * colormaps have exactly the same format as a row of image pixels (so
-          * you choose what format to make the colormap by setting
+          * colormaps have exactly the same format as a row of image pixels
+          * (so you choose what format to make the colormap by setting
           * image.format).  A colormap is only returned if
           * PNG_FORMAT_FLAG_COLORMAP is also set in image.format, so in this
           * case NULL is passed as the final argument.  If you do want to force
-          * all images into an index/color-mapped format then you can use:
+          * all images into an index/color-mapped format, then you can use:
           *
           *    PNG_IMAGE_COLORMAP_SIZE(image)
           *
@@ -97,7 +100,7 @@ int main(int argc, const char **argv)
           */
          if (buffer != NULL &&
             png_image_finish_read(&image, NULL/*background*/, buffer,
-               0/*row_stride*/, NULL/*colormap*/) != 0)
+                0/*row_stride*/, NULL/*colormap*/) != 0)
          {
             /* Now write the image out to the second argument.  In the write
              * call 'convert_to_8bit' allows 16-bit data to be squashed down to
@@ -105,23 +108,21 @@ int main(int argc, const char **argv)
              * to the 8-bit format.
              */
             if (png_image_write_to_file(&image, argv[2], 0/*convert_to_8bit*/,
-               buffer, 0/*row_stride*/, NULL/*colormap*/) != 0)
+                buffer, 0/*row_stride*/, NULL/*colormap*/) != 0)
             {
                /* The image has been written successfully. */
                exit(0);
             }
          }
-
          else
          {
-            /* Calling png_free_image is optional unless the simplified API was
-             * not run to completion.  In this case if there wasn't enough
-             * memory for 'buffer' we didn't complete the read, so we must free
-             * the image:
+            /* Calling png_image_free is optional unless the simplified API was
+             * not run to completion.  In this case, if there wasn't enough
+             * memory for 'buffer', we didn't complete the read, so we must
+             * free the image:
              */
             if (buffer == NULL)
-               png_free_image(&image);
-
+               png_image_free(&image);
             else
                free(buffer);
       }
@@ -130,65 +131,67 @@ int main(int argc, const char **argv)
        * textual message in the 'png_image' structure:
        */
       fprintf(stderr, "pngtopng: error: %s\n", image.message);
-      exit (1);
+      exit(1);
    }
 
    fprintf(stderr, "pngtopng: usage: pngtopng input-file output-file\n");
-   exit(1);
+   exit(2);
 }
 
 /* That's it ;-)  Of course you probably want to do more with PNG files than
  * just converting them all to 32-bit RGBA PNG files; you can do that between
  * the call to png_image_finish_read and png_image_write_to_file.  You can also
- * ask for the image data to be presented in a number of different formats.  You
- * do this by simply changing the 'format' parameter set before allocating the
- * buffer.
+ * ask for the image data to be presented in a number of different formats.
+ * You do this by simply changing the 'format' parameter set before allocating
+ * the buffer.
  *
  * The format parameter consists of five flags that define various aspects of
- * the image, you can simply add these together to get the format or you can use
- * one of the predefined macros from png.h (as above):
+ * the image.  You can simply add these together to get the format, or you can
+ * use one of the predefined macros from png.h (as above):
  *
- * PNG_FORMAT_FLAG_COLOR: if set the image will have three color components per
- *    pixel (red, green and blue), if not set the image will just have one
+ * PNG_FORMAT_FLAG_COLOR: if set, the image will have three color components
+ *    per pixel (red, green and blue); if not set, the image will just have one
  *    luminance (grayscale) component.
  *
- * PNG_FORMAT_FLAG_ALPHA: if set each pixel in the image will have an additional
- *    alpha value; a linear value that describes the degree the image pixel
- *    covers (overwrites) the contents of the existing pixel on the display.
+ * PNG_FORMAT_FLAG_ALPHA: if set, each pixel in the image will have an
+ *    additional alpha value; a linear value that describes the degree the
+ *    image pixel covers (overwrites) the contents of the existing pixel on the
+ *    display.
  *
- * PNG_FORMAT_FLAG_LINEAR: if set the components of each pixel will be returned
- *    as a series of 16-bit linear values, if not set the components will be
- *    returned as a series of 8-bit values encoded according to the 'sRGB'
- *    standard.  The 8-bit format is the normal format for images intended for
- *    direct display, because almost all display devices do the inverse of the
- *    sRGB transformation to the data they receive.  The 16-bit format is more
- *    common for scientific data and image data that must be further processed;
- *    because it is linear simple math can be done on the component values.
- *    Regardless of the setting of this flag the alpha channel is always linear,
- *    although it will be 8 bits or 16 bits wide as specified by the flag.
+ * PNG_FORMAT_FLAG_LINEAR: if set, the components of each pixel will be
+ *    returned as a series of 16-bit linear values; if not set, the components
+ *    will be returned as a series of 8-bit values encoded according to the
+ *    sRGB standard.  The 8-bit format is the normal format for images intended
+ *    for direct display, because almost all display devices do the inverse of
+ *    the sRGB transformation to the data they receive.  The 16-bit format is
+ *    more common for scientific data and image data that must be further
+ *    processed; because it is linear, simple math can be done on the component
+ *    values.  Regardless of the setting of this flag, the alpha channel is
+ *    always linear, although it will be 8 bits or 16 bits wide as specified by
+ *    the flag.
  *
- * PNG_FORMAT_FLAG_BGR: if set the components of a color pixel will be returned
- *    in the order blue, then green, then red.  If not set the pixel components
- *    are in the order red, then green, then blue.
+ * PNG_FORMAT_FLAG_BGR: if set, the components of a color pixel will be
+ *    returned in the order blue, then green, then red.  If not set, the pixel
+ *    components are in the order red, then green, then blue.
  *
- * PNG_FORMAT_FLAG_AFIRST: if set the alpha channel (if present) precedes the
- *    color or grayscale components.  If not set the alpha channel follows the
+ * PNG_FORMAT_FLAG_AFIRST: if set, the alpha channel (if present) precedes the
+ *    color or grayscale components.  If not set, the alpha channel follows the
  *    components.
  *
  * You do not have to read directly from a file.  You can read from memory or,
  * on systems that support it, from a <stdio.h> FILE*.  This is controlled by
- * the particular png_image_read_from_ function you call at the start.  Likewise
- * on write you can write to a FILE* if your system supports it.  Check the
- * macro PNG_STDIO_SUPPORTED to see if stdio support has been included in your
- * libpng build.
+ * the particular png_image_read_from_ function you call at the start.
+ * Likewise, on write, you can write to a FILE* if your system supports it.
+ * Check the macro PNG_STDIO_SUPPORTED to see if stdio support has been
+ * included in your libpng build.
  *
- * If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data you may need to write it in
- * the 8-bit format for display.  You do this by setting the convert_to_8bit
+ * If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data, you may need to write it
+ * in the 8-bit format for display.  You do this by setting the convert_to_8bit
  * flag to 'true'.
  *
  * Don't repeatedly convert between the 8-bit and 16-bit forms.  There is
- * significant data loss when 16-bit data is converted to the 8-bit encoding and
- * the current libpng implementation of conversion to 16-bit is also
+ * significant data loss when 16-bit data is converted to the 8-bit encoding,
+ * and the current libpng implementation of conversion to 16-bit is also
  * significantly lossy.  The latter will be fixed in the future, but the former
  * is unavoidable - the 8-bit format just doesn't have enough resolution.
  */
@@ -199,10 +202,10 @@ int main(int argc, const char **argv)
  * interfaces.
  *
  * All these interfaces require that you do your own error handling - your
- * program must be able to arrange for control to return to your own code any
- * time libpng encounters a problem.  There are several ways to do this, but the
- * standard way is to use the ANSI-C (C90) <setjmp.h> interface to establish a
- * return point within your own code.  You must do this if you do not use the
+ * program must be able to arrange for control to return to your own code, any
+ * time libpng encounters a problem.  There are several ways to do this, but
+ * the standard way is to use the <setjmp.h> interface to establish a return
+ * point within your own code.  You must do this if you do not use the
  * simplified interface (above).
  *
  * The first step is to include the header files you need, including the libpng
@@ -214,7 +217,7 @@ int main(int argc, const char **argv)
  /* The png_jmpbuf() macro, used in error handling, became available in
   * libpng version 1.0.6.  If you want to be able to run your code with older
   * versions of libpng, you must define the macro yourself (but only if it
-  * is not already defined by libpng!).
+  * is not already defined by libpng!)
   */
 
 #ifndef png_jmpbuf
@@ -222,10 +225,10 @@ int main(int argc, const char **argv)
 #endif
 
 /* Check to see if a file is a PNG file using png_sig_cmp().  png_sig_cmp()
- * returns zero if the image is a PNG and nonzero if it isn't a PNG.
+ * returns zero if the image is a PNG, and nonzero otherwise.
  *
  * The function check_if_png() shown here, but not used, returns nonzero (true)
- * if the file can be opened and is a PNG, 0 (false) otherwise.
+ * if the file can be opened and is a PNG, and 0 (false) otherwise.
  *
  * If this call is successful, and you are going to keep the file open,
  * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
@@ -238,7 +241,7 @@ int main(int argc, const char **argv)
  *
  * Many applications already read the first 2 or 4 bytes from the start
  * of the image to determine the file type, so it would be easiest just
- * to pass the bytes to png_sig_cmp() or even skip that if you know
+ * to pass the bytes to png_sig_cmp(), or even skip that if you know
  * you have a PNG file, and call png_set_sig_bytes().
  */
 #define PNG_BYTES_TO_CHECK 4
@@ -250,14 +253,14 @@ int check_if_png(char *file_name, FILE **fp)
    if ((*fp = fopen(file_name, "rb")) == NULL)
       return 0;
 
-   /* Read in some of the signature bytes */
+   /* Read in some of the signature bytes. */
    if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
       return 0;
 
    /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
-      Return nonzero (true) if they match */
-
-   return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
+    * Return nonzero (true) if they match.
+    */
+   return(!png_sig_cmp(buf, 0, PNG_BYTES_TO_CHECK));
 }
 
 /* Read a PNG file.  You may want to return an error code if the read
@@ -267,7 +270,7 @@ int check_if_png(char *file_name, FILE **fp)
  * some or all of the magic bytes read - see comments above).
  */
 #ifdef open_file /* prototype 1 */
-void read_png(char *file_name)  /* We need to open the file */
+void read_png(char *file_name) /* We need to open the file */
 {
    png_structp png_ptr;
    png_infop info_ptr;
@@ -280,7 +283,7 @@ void read_png(char *file_name)  /* We need to open the file */
       return (ERROR);
 
 #else no_open_file /* prototype 2 */
-void read_png(FILE *fp, int sig_read)  /* File is already open */
+void read_png(FILE *fp, int sig_read) /* File is already open */
 {
    png_structp png_ptr;
    png_infop info_ptr;
@@ -292,10 +295,10 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
     * functions.  If you want to use the default stderr and longjump method,
     * you can supply NULL for the last three parameters.  We also supply the
     * the compiler header file version, so that we know if the application
-    * was compiled with a compatible version of the library.  REQUIRED
+    * was compiled with a compatible version of the library.  REQUIRED.
     */
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
-      png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+       png_voidp user_error_ptr, user_error_fn, user_warning_fn);
 
    if (png_ptr == NULL)
    {
@@ -316,35 +319,33 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
     * the normal method of doing things with libpng).  REQUIRED unless you
     * set up your own error handlers in the png_create_read_struct() earlier.
     */
-
    if (setjmp(png_jmpbuf(png_ptr)))
    {
-      /* Free all of the memory associated with the png_ptr and info_ptr */
+      /* Free all of the memory associated with the png_ptr and info_ptr. */
       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
       fclose(fp);
-      /* If we get here, we had a problem reading the file */
+      /* If we get here, we had a problem reading the file. */
       return (ERROR);
    }
 
-   /* One of the following I/O initialization methods is REQUIRED */
+   /* One of the following I/O initialization methods is REQUIRED. */
 #ifdef streams /* PNG file I/O method 1 */
-   /* Set up the input control if you are using standard C streams */
+   /* Set up the input control if you are using standard C streams. */
    png_init_io(png_ptr, fp);
 
 #else no_streams /* PNG file I/O method 2 */
    /* If you are using replacement read functions, instead of calling
-    * png_init_io() here you would call:
+    * png_init_io(), you would call:
     */
    png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
-   /* where user_io_ptr is a structure you want available to the callbacks */
+   /* where user_io_ptr is a structure you want available to the callbacks. */
 #endif no_streams /* Use only one I/O method! */
 
    /* If we have already read some of the signature */
    png_set_sig_bytes(png_ptr, sig_read);
 
 #ifdef hilevel
-   /*
-    * If you have enough memory to read in the entire image at once,
+   /* If you have enough memory to read in the entire image at once,
     * and you need to specify only transforms that can be controlled
     * with one of the PNG_TRANSFORM_* bits (this presently excludes
     * quantizing, filling, setting background, and doing gamma
@@ -354,10 +355,10 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
    png_read_png(png_ptr, info_ptr, png_transforms, NULL);
 
 #else
-   /* OK, you're doing it the hard way, with the lower-level functions */
+   /* OK, you're doing it the hard way, with the lower-level functions. */
 
    /* The call to png_read_info() gives us all of the information from the
-    * PNG file before the first IDAT (image data chunk).  REQUIRED
+    * PNG file before the first IDAT (image data chunk).  REQUIRED.
     */
    png_read_info(png_ptr, info_ptr);
 
@@ -375,7 +376,7 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
     * low byte.
     */
 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-    png_set_scale_16(png_ptr);
+   png_set_scale_16(png_ptr);
 #else
    png_set_strip_16(png_ptr);
 #endif
@@ -385,20 +386,21 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
     */
    png_set_strip_alpha(png_ptr);
 
-   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+   /* Extract multiple pixels with bit depths of 1, 2 or 4 from a single
     * byte into separate bytes (useful for paletted and grayscale images).
     */
    png_set_packing(png_ptr);
 
    /* Change the order of packed pixels to least significant bit first
-    * (not useful if you are using png_set_packing). */
+    * (not useful if you are using png_set_packing).
+    */
    png_set_packswap(png_ptr);
 
-   /* Expand paletted colors into true RGB triplets */
+   /* Expand paletted colors into true RGB triplets. */
    if (color_type == PNG_COLOR_TYPE_PALETTE)
       png_set_palette_to_rgb(png_ptr);
 
-   /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
+   /* Expand grayscale images to the full 8 bits from 1, 2 or 4 bits/pixel. */
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
       png_set_expand_gray_1_2_4_to_8(png_ptr);
 
@@ -409,47 +411,43 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
       png_set_tRNS_to_alpha(png_ptr);
 
    /* Set the background color to draw transparent and alpha images over.
-    * It is possible to set the red, green, and blue components directly
-    * for paletted images instead of supplying a palette index.  Note that
+    * It is possible to set the red, green and blue components directly
+    * for paletted images, instead of supplying a palette index.  Note that,
     * even if the PNG file supplies a background, you are not required to
     * use it - you should use the (solid) application background if it has one.
     */
-
    png_color_16 my_background, *image_background;
 
    if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0)
       png_set_background(png_ptr, image_background,
-                         PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
    else
       png_set_background(png_ptr, &my_background,
-                         PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
 
-   /* Some suggestions as to how to get a screen gamma value
+   /* Some suggestions as to how to get a screen gamma value.
     *
     * Note that screen gamma is the display_exponent, which includes
-    * the CRT_exponent and any correction for viewing conditions
+    * the CRT_exponent and any correction for viewing conditions.
     */
    if (/* We have a user-defined screen gamma value */)
-   {
       screen_gamma = user-defined screen_gamma;
-   }
-   /* This is one way that applications share the same screen gamma value */
+   /* This is one way that applications share the same screen gamma value. */
    else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
-   {
       screen_gamma = atof(gamma_str);
-   }
    /* If we don't have another value */
    else
    {
-      screen_gamma = PNG_DEFAULT_sRGB;  /* A good guess for a PC monitor
-                                           in a dimly lit room */
-      screen_gamma = PNG_GAMMA_MAC_18 or 1.0; /* Good guesses for Mac systems */
+      screen_gamma = PNG_DEFAULT_sRGB; /* A good guess for a PC monitor
+                                          in a dimly lit room */
+      screen_gamma = PNG_GAMMA_MAC_18 or 1.0; /* Good guesses for Mac
+                                                 systems */
    }
 
    /* Tell libpng to handle the gamma conversion for you.  The final call
     * is a good guess for PC generated images, but it should be configurable
-    * by the user at run time by the user.  It is strongly suggested that
-    * your application support gamma correction.
+    * by the user at run time.  Gamma correction support in your application
+    * is strongly recommended.
     */
 
    int intent;
@@ -466,7 +464,7 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
    }
 
 #ifdef PNG_READ_QUANTIZE_SUPPORTED
-   /* Quantize RGB files down to 8-bit palette or reduce palettes
+   /* Quantize RGB files down to 8-bit palette, or reduce palettes
     * to the number of colors available on your screen.
     */
    if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
@@ -474,29 +472,26 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
       int num_palette;
       png_colorp palette;
 
-      /* This reduces the image to the application supplied palette */
+      /* This reduces the image to the application-supplied palette. */
       if (/* We have our own palette */)
       {
-         /* An array of colors to which the image should be quantized */
+         /* An array of colors to which the image should be quantized. */
          png_color std_color_cube[MAX_SCREEN_COLORS];
-
          png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
-            MAX_SCREEN_COLORS, NULL, 0);
+             MAX_SCREEN_COLORS, NULL, 0);
       }
-      /* This reduces the image to the palette supplied in the file */
+      /* This reduces the image to the palette supplied in the file. */
       else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) != 0)
       {
          png_uint_16p histogram = NULL;
-
          png_get_hIST(png_ptr, info_ptr, &histogram);
-
          png_set_quantize(png_ptr, palette, num_palette,
-                        max_screen_colors, histogram, 0);
+             max_screen_colors, histogram, 0);
       }
    }
 #endif /* READ_QUANTIZE */
 
-   /* Invert monochrome files to have 0 as white and 1 as black */
+   /* Invert monochrome files to have 0 as white and 1 as black. */
    png_set_invert_mono(png_ptr);
 
    /* If you want to shift the pixel values from the range [0,255] or
@@ -506,22 +501,21 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT) != 0)
    {
       png_color_8p sig_bit_p;
-
       png_get_sBIT(png_ptr, info_ptr, &sig_bit_p);
       png_set_shift(png_ptr, sig_bit_p);
    }
 
-   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
+   /* Flip the RGB pixels to BGR (or RGBA to BGRA). */
    if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
       png_set_bgr(png_ptr);
 
-   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR). */
    png_set_swap_alpha(png_ptr);
 
-   /* Swap bytes of 16-bit files to least significant byte first */
+   /* Swap bytes of 16-bit files to least significant byte first. */
    png_set_swap(png_ptr);
 
-   /* Add filler (or alpha) byte (before/after each RGB triplet) */
+   /* Add filler (or alpha) byte (before/after each RGB triplet). */
    png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER);
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
@@ -530,75 +524,66 @@ void read_png(FILE *fp, int sig_read)  /* File is already open */
     * see the png_read_row() method below:
     */
    number_passes = png_set_interlace_handling(png_ptr);
-#else
+#else /* !READ_INTERLACING */
    number_passes = 1;
 #endif /* READ_INTERLACING */
 
-
    /* Optional call to gamma correct and add the background to the palette
     * and update info structure.  REQUIRED if you are expecting libpng to
-    * update the palette for you (ie you selected such a transform above).
+    * update the palette for you (i.e. you selected such a transform above).
     */
    png_read_update_info(png_ptr, info_ptr);
 
    /* Allocate the memory to hold the image using the fields of info_ptr. */
-
-   /* The easiest way to read the image: */
    png_bytep row_pointers[height];
-
-   /* Clear the pointer array */
    for (row = 0; row < height; row++)
-      row_pointers[row] = NULL;
-
+      row_pointers[row] = NULL; /* Clear the pointer array */
    for (row = 0; row < height; row++)
       row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
-         info_ptr));
+          info_ptr));
 
-   /* Now it's time to read the image.  One of these methods is REQUIRED */
+   /* Now it's time to read the image.  One of these methods is REQUIRED. */
 #ifdef entire /* Read the entire image in one go */
    png_read_image(png_ptr, row_pointers);
 
 #else no_entire /* Read the image one or more scanlines at a time */
    /* The other way to read images - deal with interlacing: */
-
    for (pass = 0; pass < number_passes; pass++)
    {
 #ifdef single /* Read the image a single row at a time */
       for (y = 0; y < height; y++)
-      {
          png_read_rows(png_ptr, &row_pointers[y], NULL, 1);
-      }
 
 #else no_single /* Read the image several rows at a time */
       for (y = 0; y < height; y += number_of_rows)
       {
 #ifdef sparkle /* Read the image using the "sparkle" effect. */
          png_read_rows(png_ptr, &row_pointers[y], NULL,
-            number_of_rows);
+             number_of_rows);
 #else no_sparkle /* Read the image using the "rectangle" effect */
          png_read_rows(png_ptr, NULL, &row_pointers[y],
-            number_of_rows);
+             number_of_rows);
 #endif no_sparkle /* Use only one of these two methods */
       }
 
-      /* If you want to display the image after every pass, do so here */
+      /* If you want to display the image after every pass, do so here. */
 #endif no_single /* Use only one of these two methods */
    }
 #endif no_entire /* Use only one of these two methods */
 
-   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+   /* Read rest of file, and get additional chunks in info_ptr.  REQUIRED. */
    png_read_end(png_ptr, info_ptr);
 #endif hilevel
 
-   /* At this point you have read the entire image */
+   /* At this point you have read the entire image. */
 
-   /* Clean up after the read, and free any memory allocated - REQUIRED */
+   /* Clean up after the read, and free any memory allocated.  REQUIRED. */
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
 
-   /* Close the file */
+   /* Close the file. */
    fclose(fp);
 
-   /* That's it */
+   /* That's it! */
    return (OK);
 }
 
@@ -610,34 +595,30 @@ initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
    /* Create and initialize the png_struct with the desired error handler
     * functions.  If you want to use the default stderr and longjump method,
     * you can supply NULL for the last three parameters.  We also check that
-    * the library version is compatible in case we are using dynamically
+    * the library version is compatible, in case we are using dynamically
     * linked libraries.
     */
    *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
-       png_voidp user_error_ptr, user_error_fn, user_warning_fn);
-
+        png_voidp user_error_ptr, user_error_fn, user_warning_fn);
    if (*png_ptr == NULL)
    {
       *info_ptr = NULL;
       return (ERROR);
    }
-
    *info_ptr = png_create_info_struct(png_ptr);
-
    if (*info_ptr == NULL)
    {
       png_destroy_read_struct(png_ptr, info_ptr, NULL);
       return (ERROR);
    }
-
    if (setjmp(png_jmpbuf((*png_ptr))))
    {
       png_destroy_read_struct(png_ptr, info_ptr, NULL);
       return (ERROR);
    }
 
-   /* This one's new.  You will need to provide all three
-    * function callbacks, even if you aren't using them all.
+   /* You will need to provide all three function callbacks,
+    * even if you aren't using all of them.
     * If you aren't using all functions, you can specify NULL
     * parameters.  Even when all three functions are NULL,
     * you need to call png_set_progressive_read_fn().
@@ -649,29 +630,28 @@ initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
     * the function png_get_progressive_ptr(png_ptr).
     */
    png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
-      info_callback, row_callback, end_callback);
-
+       info_callback, row_callback, end_callback);
    return (OK);
 }
 
 int
 process_data(png_structp *png_ptr, png_infop *info_ptr,
-   png_bytep buffer, png_uint_32 length)
+    png_bytep buffer, png_uint_32 length)
 {
    if (setjmp(png_jmpbuf((*png_ptr))))
    {
-      /* Free the png_ptr and info_ptr memory on error */
+      /* Free the png_ptr and info_ptr memory on error. */
       png_destroy_read_struct(png_ptr, info_ptr, NULL);
       return (ERROR);
    }
 
-   /* This one's new also.  Simply give it chunks of data as
-    * they arrive from the data stream (in order, of course).
+   /* Give chunks of data as they arrive from the data stream
+    * (in order, of course).
     * On segmented machines, don't give it any more than 64K.
     * The library seems to run fine with sizes of 4K, although
-    * you can give it much less if necessary (I assume you can
+    * you can give it much less if necessary. (I assume you can
     * give it chunks of 1 byte, but I haven't tried with less
-    * than 256 bytes yet).  When this function returns, you may
+    * than 256 bytes yet.)  When this function returns, you may
     * want to display any rows that were generated in the row
     * callback, if you aren't already displaying them there.
     */
@@ -691,10 +671,9 @@ info_callback(png_structp png_ptr, png_infop info)
 }
 
 row_callback(png_structp png_ptr, png_bytep new_row,
-   png_uint_32 row_num, int pass)
+    png_uint_32 row_num, int pass)
 {
-   /*
-    * This function is called for every row in the image.  If the
+   /* This function is called for every row in the image.  If the
     * image is interlaced, and you turned on the interlace handler,
     * this function will be called for every row in every pass.
     *
@@ -705,25 +684,22 @@ row_callback(png_structp png_ptr, png_bytep new_row,
     * The new row data pointer "new_row" may be NULL, indicating there is
     * no new data to be replaced (in cases of interlace loading).
     *
-    * If new_row is not NULL then you need to call
-    * png_progressive_combine_row() to replace the corresponding row as
+    * If new_row is not NULL, then you need to call
+    * png_progressive_combine_row(), to replace the corresponding row as
     * shown below:
     */
 
-   /* Get pointer to corresponding row in our
-    * PNG read buffer.
-    */
+   /* Get pointer to corresponding row in our PNG read buffer. */
    png_bytep old_row = ((png_bytep *)our_data)[row_num];
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
-   /* If both rows are allocated then copy the new row
+   /* If both rows are allocated, then copy the new row
     * data to the corresponding row data.
     */
-   if ((old_row != NULL) && (new_row != NULL))
-   png_progressive_combine_row(png_ptr, old_row, new_row);
+   if (old_row != NULL && new_row != NULL)
+      png_progressive_combine_row(png_ptr, old_row, new_row);
 
-   /*
-    * The rows and passes are called in order, so you don't really
+   /* The rows and passes are called in order, so you don't really
     * need the row_num and pass, but I'm supplying them because it
     * may make your life easier.
     *
@@ -734,7 +710,6 @@ row_callback(png_structp png_ptr, png_bytep new_row,
     * (it just does the memcpy for you) if it will make the code
     * easier.  Thus, you can just do this for all cases:
     */
-
    png_progressive_combine_row(png_ptr, old_row, new_row);
 
    /* where old_row is what was displayed for previous rows.  Note
@@ -780,15 +755,14 @@ void write_png(char *file_name /* , ... other image information ... */)
     * in case we are using dynamically linked libraries.  REQUIRED.
     */
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
-      png_voidp user_error_ptr, user_error_fn, user_warning_fn);
-
+       png_voidp user_error_ptr, user_error_fn, user_warning_fn);
    if (png_ptr == NULL)
    {
       fclose(fp);
       return (ERROR);
    }
 
-   /* Allocate/initialize the image information data.  REQUIRED */
+   /* Allocate/initialize the image information data.  REQUIRED. */
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
@@ -797,30 +771,30 @@ void write_png(char *file_name /* , ... other image information ... */)
       return (ERROR);
    }
 
-   /* Set error handling.  REQUIRED if you aren't supplying your own
+   /* Set up error handling.  REQUIRED if you aren't supplying your own
     * error handling functions in the png_create_write_struct() call.
     */
    if (setjmp(png_jmpbuf(png_ptr)))
    {
-      /* If we get here, we had a problem writing the file */
+      /* If we get here, we had a problem writing the file. */
       fclose(fp);
       png_destroy_write_struct(&png_ptr, &info_ptr);
       return (ERROR);
    }
 
-   /* One of the following I/O initialization functions is REQUIRED */
+   /* One of the following I/O initialization functions is REQUIRED. */
 
 #ifdef streams /* I/O initialization method 1 */
-   /* Set up the output control if you are using standard C streams */
+   /* Set up the output control if you are using standard C streams. */
    png_init_io(png_ptr, fp);
 
 #else no_streams /* I/O initialization method 2 */
    /* If you are using replacement write functions, instead of calling
-    * png_init_io() here you would call
+    * png_init_io(), you would call:
     */
    png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
-      user_IO_flush_function);
-   /* where user_io_ptr is a structure you want available to the callbacks */
+       user_IO_flush_function);
+   /* where user_io_ptr is a structure you want available to the callbacks. */
 #endif no_streams /* Only use one initialization method */
 
 #ifdef hilevel
@@ -831,30 +805,32 @@ void write_png(char *file_name /* , ... other image information ... */)
    png_write_png(png_ptr, info_ptr, png_transforms, NULL);
 
 #else
-   /* This is the hard way */
+   /* This is the hard way. */
 
    /* Set the image information here.  Width and height are up to 2^31,
-    * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
-    * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
+    * bit_depth is one of 1, 2, 4, 8 or 16, but valid values also depend on
+    * the color_type selected.  color_type is one of PNG_COLOR_TYPE_GRAY,
     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
-    * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
+    * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE.
+    * REQUIRED.
     */
-   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
-      PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+       PNG_COLOR_TYPE_???, PNG_INTERLACE_????,
+       PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
-   /* Set the palette if there is one.  REQUIRED for indexed-color images */
-   palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
-             * (sizeof (png_color)));
+   /* Set the palette if there is one.  REQUIRED for indexed-color images. */
+   palette = (png_colorp)png_malloc(png_ptr,
+       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)));
    /* ... Set palette colors ... */
    png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
-   /* You must not free palette here, because png_set_PLTE only makes a link to
-    * the palette that you malloced.  Wait until you are about to destroy
+   /* You must not free palette here, because png_set_PLTE only makes a link
+    * to the palette that you allocated.  Wait until you are about to destroy
     * the png structure.
     */
 
-   /* Optional significant bit (sBIT) chunk */
+   /* Optional significant bit (sBIT) chunk. */
    png_color_8 sig_bit;
 
    /* If we are dealing with a grayscale image then */
@@ -870,18 +846,17 @@ void write_png(char *file_name /* , ... other image information ... */)
 
    png_set_sBIT(png_ptr, info_ptr, &sig_bit);
 
-
    /* Optional gamma chunk is strongly suggested if you have any guess
     * as to the correct gamma of the image.
     */
    png_set_gAMA(png_ptr, info_ptr, gamma);
 
-   /* Optionally write comments into the image */
+   /* Optionally write comments into the image. */
    {
       png_text text_ptr[3];
 
-      char key0[]="Title";
-      char text0[]="Mona Lisa";
+      char key0[] = "Title";
+      char text0[] = "Mona Lisa";
       text_ptr[0].key = key0;
       text_ptr[0].text = text0;
       text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
@@ -889,8 +864,8 @@ void write_png(char *file_name /* , ... other image information ... */)
       text_ptr[0].lang = NULL;
       text_ptr[0].lang_key = NULL;
 
-      char key1[]="Author";
-      char text1[]="Leonardo DaVinci";
+      char key1[] = "Author";
+      char text1[] = "Leonardo DaVinci";
       text_ptr[1].key = key1;
       text_ptr[1].text = text1;
       text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
@@ -898,8 +873,8 @@ void write_png(char *file_name /* , ... other image information ... */)
       text_ptr[1].lang = NULL;
       text_ptr[1].lang_key = NULL;
 
-      char key2[]="Description";
-      char text2[]="<long text>";
+      char key2[] = "Description";
+      char text2[] = "<long text>";
       text_ptr[2].key = key2;
       text_ptr[2].text = text2;
       text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
@@ -910,14 +885,14 @@ void write_png(char *file_name /* , ... other image information ... */)
       png_set_text(write_ptr, write_info_ptr, text_ptr, 3);
    }
 
-   /* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs */
+   /* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs. */
 
-   /* Note that if sRGB is present the gAMA and cHRM chunks must be ignored
+   /* Note that if sRGB is present, the gAMA and cHRM chunks must be ignored
     * on read and, if your application chooses to write them, they must
-    * be written in accordance with the sRGB profile
+    * be written in accordance with the sRGB profile.
     */
 
-   /* Write the file header information.  REQUIRED */
+   /* Write the file header information.  REQUIRED. */
    png_write_info(png_ptr, info_ptr);
 
    /* If you want, you can write the info in two steps, in case you need to
@@ -941,7 +916,7 @@ void write_png(char *file_name /* , ... other image information ... */)
     * all optional.  Only call them if you want them.
     */
 
-   /* Invert monochrome pixels */
+   /* Invert monochrome pixels. */
    png_set_invert_mono(png_ptr);
 
    /* Shift the pixels up to a legal bit depth and fill in
@@ -949,30 +924,29 @@ void write_png(char *file_name /* , ... other image information ... */)
     */
    png_set_shift(png_ptr, &sig_bit);
 
-   /* Pack pixels into bytes */
+   /* Pack pixels into bytes. */
    png_set_packing(png_ptr);
 
-   /* Swap location of alpha bytes from ARGB to RGBA */
+   /* Swap location of alpha bytes from ARGB to RGBA. */
    png_set_swap_alpha(png_ptr);
 
    /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
-    * RGB (4 channels -> 3 channels). The second parameter is not used.
+    * RGB (4 channels -> 3 channels).  The second parameter is not used.
     */
    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
 
-   /* Flip BGR pixels to RGB */
+   /* Flip BGR pixels to RGB. */
    png_set_bgr(png_ptr);
 
-   /* Swap bytes of 16-bit files to most significant byte first */
+   /* Swap bytes of 16-bit files to most significant byte first. */
    png_set_swap(png_ptr);
 
-   /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */
+   /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats. */
    png_set_packswap(png_ptr);
 
-   /* Turn on interlace handling if you are not using png_write_image() */
+   /* Turn on interlace handling if you are not using png_write_image(). */
    if (interlacing != 0)
       number_passes = png_set_interlace_handling(png_ptr);
-
    else
       number_passes = 1;
 
@@ -982,24 +956,28 @@ void write_png(char *file_name /* , ... other image information ... */)
     */
    png_uint_32 k, height, width;
 
-   /* In this example, "image" is a one-dimensional array of bytes */
-   png_byte image[height*width*bytes_per_pixel];
+   /* In this example, "image" is a one-dimensional array of bytes. */
 
+   /* Guard against integer overflow. */
+   if (height > PNG_SIZE_MAX / (width * bytes_per_pixel))
+      png_error(png_ptr, "Image data buffer would be too large");
+
+   png_byte image[height * width * bytes_per_pixel];
    png_bytep row_pointers[height];
 
-   if (height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
-     png_error (png_ptr, "Image is too tall to process in memory");
+   if (height > PNG_UINT_32_MAX / (sizeof (png_bytep)))
+      png_error(png_ptr, "Image is too tall to process in memory");
 
-   /* Set up pointers into your "image" byte array */
+   /* Set up pointers into your "image" byte array. */
    for (k = 0; k < height; k++)
-     row_pointers[k] = image + k*width*bytes_per_pixel;
+      row_pointers[k] = image + k * width * bytes_per_pixel;
 
-   /* One of the following output methods is REQUIRED */
+   /* One of the following output methods is REQUIRED. */
 
 #ifdef entire /* Write out the entire image data in one call */
    png_write_image(png_ptr, row_pointers);
 
-   /* The other way to write the image - deal with interlacing */
+   /* The other way to write the image - deal with interlacing. */
 
 #else no_entire /* Write out the image data by one or more scanlines */
 
@@ -1011,27 +989,27 @@ void write_png(char *file_name /* , ... other image information ... */)
       /* Write a few rows at a time. */
       png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
 
-      /* If you are only writing one row at a time, this works */
+      /* If you are only writing one row at a time, this works. */
       for (y = 0; y < height; y++)
          png_write_rows(png_ptr, &row_pointers[y], 1);
    }
 #endif no_entire /* Use only one output method */
 
    /* You can write optional chunks like tEXt, zTXt, and tIME at the end
-    * as well.  Shouldn't be necessary in 1.2.0 and up as all the public
-    * chunks are supported and you can use png_set_unknown_chunks() to
+    * as well.  Shouldn't be necessary in 1.2.0 and up, as all the public
+    * chunks are supported, and you can use png_set_unknown_chunks() to
     * register unknown chunks into the info structure to be written out.
     */
 
-   /* It is REQUIRED to call this to finish writing the rest of the file */
+   /* It is REQUIRED to call this to finish writing the rest of the file. */
    png_write_end(png_ptr, info_ptr);
 #endif hilevel
 
-   /* If you png_malloced a palette, free it here (don't free info_ptr->palette,
-    * as recommended in versions 1.0.5m and earlier of this example; if
-    * libpng mallocs info_ptr->palette, libpng will free it).  If you
-    * allocated it with malloc() instead of png_malloc(), use free() instead
-    * of png_free().
+   /* If you png_malloced a palette, free it here.
+    * (Don't free info_ptr->palette, as shown in versions 1.0.5m and earlier of
+    * this example; if libpng mallocs info_ptr->palette, libpng will free it).
+    * If you allocated it with malloc() instead of png_malloc(), use free()
+    * instead of png_free().
     */
    png_free(png_ptr, palette);
    palette = NULL;
@@ -1042,19 +1020,20 @@ void write_png(char *file_name /* , ... other image information ... */)
     */
    png_free(png_ptr, trans);
    trans = NULL;
-   /* Whenever you use png_free() it is a good idea to set the pointer to
+
+   /* Whenever you use png_free(), it is a good idea to set the pointer to
     * NULL in case your application inadvertently tries to png_free() it
-    * again.  When png_free() sees a NULL it returns without action, thus
-    * avoiding the double-free security problem.
+    * again.  When png_free() sees a NULL it returns without action, avoiding
+    * the double-free problem.
     */
 
-   /* Clean up after the write, and free any memory allocated */
+   /* Clean up after the write, and free any allocated memory. */
    png_destroy_write_struct(&png_ptr, &info_ptr);
 
-   /* Close the file */
+   /* Close the file. */
    fclose(fp);
 
-   /* That's it */
+   /* That's it! */
    return (OK);
 }
 
index 0b0fdcb..8175c64 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2013-12-25.23; # UTC
+scriptversion=2018-03-11.20; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -271,15 +271,18 @@ do
     fi
     dst=$dst_arg
 
-    # If destination is a directory, append the input filename; won't work
-    # if double slashes aren't ignored.
+    # If destination is a directory, append the input filename.
     if test -d "$dst"; then
       if test "$is_target_a_directory" = never; then
         echo "$0: $dst_arg: Is a directory" >&2
         exit 1
       fi
       dstdir=$dst
-      dst=$dstdir/`basename "$src"`
+      dstbase=`basename "$src"`
+      case $dst in
+       */) dst=$dst$dstbase;;
+       *)  dst=$dst/$dstbase;;
+      esac
       dstdir_status=0
     else
       dstdir=`dirname "$dst"`
@@ -288,6 +291,11 @@ do
     fi
   fi
 
+  case $dstdir in
+    */) dstdirslash=$dstdir;;
+    *)  dstdirslash=$dstdir/;;
+  esac
+
   obsolete_mkdir_used=false
 
   if test $dstdir_status != 0; then
@@ -324,34 +332,43 @@ do
             # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
             ;;
           *)
+            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
+            # here however when possible just to lower collision chance.
             tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-            trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
 
+            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+            # Because "mkdir -p" follows existing symlinks and we likely work
+            # directly in world-writeable /tmp, make sure that the '$tmpdir'
+            # directory is successfully created first before we actually test
+            # 'mkdir -p' feature.
             if (umask $mkdir_umask &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+                $mkdirprog $mkdir_mode "$tmpdir" &&
+                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
             then
               if test -z "$dir_arg" || {
                    # Check for POSIX incompatibilities with -m.
                    # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
                    # other-writable bit of parent directory when it shouldn't.
                    # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+                   test_tmpdir="$tmpdir/a"
+                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
                    case $ls_ld_tmpdir in
                      d????-?r-*) different_mode=700;;
                      d????-?--*) different_mode=755;;
                      *) false;;
                    esac &&
-                   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
                      test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
                    }
                  }
               then posix_mkdir=:
               fi
-              rmdir "$tmpdir/d" "$tmpdir"
+              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
             else
               # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
             fi
             trap '' 0;;
         esac;;
@@ -427,8 +444,8 @@ do
   else
 
     # Make a couple of temp file names in the proper directory.
-    dsttmp=$dstdir/_inst.$$_
-    rmtmp=$dstdir/_rm.$$_
+    dsttmp=${dstdirslash}_inst.$$_
+    rmtmp=${dstdirslash}_rm.$$_
 
     # Trap to clean up those temp files at exit.
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@@ -493,9 +510,9 @@ do
 done
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/intel/filter_sse2_intrinsics.c b/intel/filter_sse2_intrinsics.c
new file mode 100644 (file)
index 0000000..f52aaa8
--- /dev/null
@@ -0,0 +1,391 @@
+
+/* filter_sse2_intrinsics.c - SSE2 optimized filter functions
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett
+ * Derived from arm/filter_neon_intrinsics.c
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+#if PNG_INTEL_SSE_IMPLEMENTATION > 0
+
+#include <immintrin.h>
+
+/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
+ * They're positioned like this:
+ *    prev:  c b
+ *    row:   a d
+ * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
+ * whichever of a, b, or c is closest to p=a+b-c.
+ */
+
+static __m128i load4(const void* p) {
+   int tmp;
+   memcpy(&tmp, p, sizeof(tmp));
+   return _mm_cvtsi32_si128(tmp);
+}
+
+static void store4(void* p, __m128i v) {
+   int tmp = _mm_cvtsi128_si32(v);
+   memcpy(p, &tmp, sizeof(int));
+}
+
+static __m128i load3(const void* p) {
+   png_uint_32 tmp = 0;
+   memcpy(&tmp, p, 3);
+   return _mm_cvtsi32_si128(tmp);
+}
+
+static void store3(void* p, __m128i v) {
+   int tmp = _mm_cvtsi128_si32(v);
+   memcpy(p, &tmp, 3);
+}
+
+void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev)
+{
+   /* The Sub filter predicts each pixel as the previous pixel, a.
+    * There is no pixel to the left of the first pixel.  It's encoded directly.
+    * That works with our main loop if we just say that left pixel was zero.
+    */
+   size_t rb;
+
+   __m128i a, d = _mm_setzero_si128();
+
+   png_debug(1, "in png_read_filter_row_sub3_sse2");
+
+   rb = row_info->rowbytes;
+   while (rb >= 4) {
+      a = d; d = load4(row);
+      d = _mm_add_epi8(d, a);
+      store3(row, d);
+
+      row += 3;
+      rb  -= 3;
+   }
+   if (rb > 0) {
+      a = d; d = load3(row);
+      d = _mm_add_epi8(d, a);
+      store3(row, d);
+
+      row += 3;
+      rb  -= 3;
+   }
+   PNG_UNUSED(prev)
+}
+
+void png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev)
+{
+   /* The Sub filter predicts each pixel as the previous pixel, a.
+    * There is no pixel to the left of the first pixel.  It's encoded directly.
+    * That works with our main loop if we just say that left pixel was zero.
+    */
+   size_t rb;
+
+   __m128i a, d = _mm_setzero_si128();
+
+   png_debug(1, "in png_read_filter_row_sub4_sse2");
+
+   rb = row_info->rowbytes+4;
+   while (rb > 4) {
+      a = d; d = load4(row);
+      d = _mm_add_epi8(d, a);
+      store4(row, d);
+
+      row += 4;
+      rb  -= 4;
+   }
+   PNG_UNUSED(prev)
+}
+
+void png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev)
+{
+   /* The Avg filter predicts each pixel as the (truncated) average of a and b.
+    * There's no pixel to the left of the first pixel.  Luckily, it's
+    * predicted to be half of the pixel above it.  So again, this works
+    * perfectly with our loop if we make sure a starts at zero.
+    */
+
+   size_t rb;
+
+   const __m128i zero = _mm_setzero_si128();
+
+   __m128i    b;
+   __m128i a, d = zero;
+
+   png_debug(1, "in png_read_filter_row_avg3_sse2");
+   rb = row_info->rowbytes;
+   while (rb >= 4) {
+      __m128i avg;
+             b = load4(prev);
+      a = d; d = load4(row );
+
+      /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+      avg = _mm_avg_epu8(a,b);
+      /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+      avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
+                                            _mm_set1_epi8(1)));
+      d = _mm_add_epi8(d, avg);
+      store3(row, d);
+
+      prev += 3;
+      row  += 3;
+      rb   -= 3;
+   }
+   if (rb > 0) {
+      __m128i avg;
+             b = load3(prev);
+      a = d; d = load3(row );
+
+      /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+      avg = _mm_avg_epu8(a,b);
+      /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+      avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
+                                            _mm_set1_epi8(1)));
+
+      d = _mm_add_epi8(d, avg);
+      store3(row, d);
+
+      prev += 3;
+      row  += 3;
+      rb   -= 3;
+   }
+}
+
+void png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev)
+{
+   /* The Avg filter predicts each pixel as the (truncated) average of a and b.
+    * There's no pixel to the left of the first pixel.  Luckily, it's
+    * predicted to be half of the pixel above it.  So again, this works
+    * perfectly with our loop if we make sure a starts at zero.
+    */
+   size_t rb;
+   const __m128i zero = _mm_setzero_si128();
+   __m128i    b;
+   __m128i a, d = zero;
+
+   png_debug(1, "in png_read_filter_row_avg4_sse2");
+
+   rb = row_info->rowbytes+4;
+   while (rb > 4) {
+      __m128i avg;
+             b = load4(prev);
+      a = d; d = load4(row );
+
+      /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+      avg = _mm_avg_epu8(a,b);
+      /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+      avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
+                                            _mm_set1_epi8(1)));
+
+      d = _mm_add_epi8(d, avg);
+      store4(row, d);
+
+      prev += 4;
+      row  += 4;
+      rb   -= 4;
+   }
+}
+
+/* Returns |x| for 16-bit lanes. */
+static __m128i abs_i16(__m128i x) {
+#if PNG_INTEL_SSE_IMPLEMENTATION >= 2
+   return _mm_abs_epi16(x);
+#else
+   /* Read this all as, return x<0 ? -x : x.
+   * To negate two's complement, you flip all the bits then add 1.
+    */
+   __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128());
+
+   /* Flip negative lanes. */
+   x = _mm_xor_si128(x, is_negative);
+
+   /* +1 to negative lanes, else +0. */
+   x = _mm_sub_epi16(x, is_negative);
+   return x;
+#endif
+}
+
+/* Bytewise c ? t : e. */
+static __m128i if_then_else(__m128i c, __m128i t, __m128i e) {
+#if PNG_INTEL_SSE_IMPLEMENTATION >= 3
+   return _mm_blendv_epi8(e,t,c);
+#else
+   return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e));
+#endif
+}
+
+void png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev)
+{
+   /* Paeth tries to predict pixel d using the pixel to the left of it, a,
+    * and two pixels from the previous row, b and c:
+    *   prev: c b
+    *   row:  a d
+    * The Paeth function predicts d to be whichever of a, b, or c is nearest to
+    * p=a+b-c.
+    *
+    * The first pixel has no left context, and so uses an Up filter, p = b.
+    * This works naturally with our main loop's p = a+b-c if we force a and c
+    * to zero.
+    * Here we zero b and d, which become c and a respectively at the start of
+    * the loop.
+    */
+   size_t rb;
+   const __m128i zero = _mm_setzero_si128();
+   __m128i c, b = zero,
+           a, d = zero;
+
+   png_debug(1, "in png_read_filter_row_paeth3_sse2");
+
+   rb = row_info->rowbytes;
+   while (rb >= 4) {
+      /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+       * intermediates.
+       */
+      __m128i pa,pb,pc,smallest,nearest;
+      c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
+      a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
+
+      /* (p-a) == (a+b-c - a) == (b-c) */
+   
+      pa = _mm_sub_epi16(b,c);
+
+      /* (p-b) == (a+b-c - b) == (a-c) */
+      pb = _mm_sub_epi16(a,c);
+
+      /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+      pc = _mm_add_epi16(pa,pb);
+
+      pa = abs_i16(pa);  /* |p-a| */
+      pb = abs_i16(pb);  /* |p-b| */
+      pc = abs_i16(pc);  /* |p-c| */
+
+      smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+      /* Paeth breaks ties favoring a over b over c. */
+      nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+                 if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+                                                             c));
+
+      /* Note `_epi8`: we need addition to wrap modulo 255. */
+      d = _mm_add_epi8(d, nearest);
+      store3(row, _mm_packus_epi16(d,d));
+
+      prev += 3;
+      row  += 3;
+      rb   -= 3;
+   }
+   if (rb > 0) {
+      /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+       * intermediates.
+       */
+      __m128i pa,pb,pc,smallest,nearest;
+      c = b; b = _mm_unpacklo_epi8(load3(prev), zero);
+      a = d; d = _mm_unpacklo_epi8(load3(row ), zero);
+
+      /* (p-a) == (a+b-c - a) == (b-c) */
+      pa = _mm_sub_epi16(b,c);
+
+      /* (p-b) == (a+b-c - b) == (a-c) */
+      pb = _mm_sub_epi16(a,c);
+
+      /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+      pc = _mm_add_epi16(pa,pb);
+
+      pa = abs_i16(pa);  /* |p-a| */
+      pb = abs_i16(pb);  /* |p-b| */
+      pc = abs_i16(pc);  /* |p-c| */
+
+      smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+      /* Paeth breaks ties favoring a over b over c. */
+      nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+                         if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+                                                                     c));
+
+      /* Note `_epi8`: we need addition to wrap modulo 255. */
+      d = _mm_add_epi8(d, nearest);
+      store3(row, _mm_packus_epi16(d,d));
+
+      prev += 3;
+      row  += 3;
+      rb   -= 3;
+   }
+}
+
+void png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev)
+{
+   /* Paeth tries to predict pixel d using the pixel to the left of it, a,
+    * and two pixels from the previous row, b and c:
+    *   prev: c b
+    *   row:  a d
+    * The Paeth function predicts d to be whichever of a, b, or c is nearest to
+    * p=a+b-c.
+    *
+    * The first pixel has no left context, and so uses an Up filter, p = b.
+    * This works naturally with our main loop's p = a+b-c if we force a and c
+    * to zero.
+    * Here we zero b and d, which become c and a respectively at the start of
+    * the loop.
+    */
+   size_t rb;
+   const __m128i zero = _mm_setzero_si128();
+   __m128i pa,pb,pc,smallest,nearest;
+   __m128i c, b = zero,
+           a, d = zero;
+
+   png_debug(1, "in png_read_filter_row_paeth4_sse2");
+
+   rb = row_info->rowbytes+4;
+   while (rb > 4) {
+      /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+       * intermediates.
+       */
+      c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
+      a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
+
+      /* (p-a) == (a+b-c - a) == (b-c) */
+      pa = _mm_sub_epi16(b,c);
+
+      /* (p-b) == (a+b-c - b) == (a-c) */
+      pb = _mm_sub_epi16(a,c);
+
+      /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+      pc = _mm_add_epi16(pa,pb);
+
+      pa = abs_i16(pa);  /* |p-a| */
+      pb = abs_i16(pb);  /* |p-b| */
+      pc = abs_i16(pc);  /* |p-c| */
+
+      smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+      /* Paeth breaks ties favoring a over b over c. */
+      nearest  = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+                         if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+                                                                     c));
+
+      /* Note `_epi8`: we need addition to wrap modulo 255. */
+      d = _mm_add_epi8(d, nearest);
+      store4(row, _mm_packus_epi16(d,d));
+
+      prev += 4;
+      row  += 4;
+      rb   -= 4;
+   }
+}
+
+#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */
+#endif /* READ */
diff --git a/intel/intel_init.c b/intel/intel_init.c
new file mode 100644 (file)
index 0000000..2f8168b
--- /dev/null
@@ -0,0 +1,52 @@
+
+/* intel_init.c - SSE2 optimized filter functions
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett, Google, Inc.
+ * Derived from arm/arm_init.c
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+#if PNG_INTEL_SSE_IMPLEMENTATION > 0
+
+void
+png_init_filter_functions_sse2(png_structp pp, unsigned int bpp)
+{
+   /* The techniques used to implement each of these filters in SSE operate on
+    * one pixel at a time.
+    * So they generally speed up 3bpp images about 3x, 4bpp images about 4x.
+    * They can scale up to 6 and 8 bpp images and down to 2 bpp images,
+    * but they'd not likely have any benefit for 1bpp images.
+    * Most of these can be implemented using only MMX and 64-bit registers,
+    * but they end up a bit slower than using the equally-ubiquitous SSE2.
+   */
+   png_debug(1, "in png_init_filter_functions_sse2");
+   if (bpp == 3)
+   {
+      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2;
+      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2;
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+         png_read_filter_row_paeth3_sse2;
+   }
+   else if (bpp == 4)
+   {
+      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2;
+      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2;
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+          png_read_filter_row_paeth4_sse2;
+   }
+
+   /* No need optimize PNG_FILTER_VALUE_UP.  The compiler should
+    * autovectorize.
+    */
+}
+
+#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */
+#endif /* PNG_READ_SUPPORTED */
index 1e838bd..19cfed2 100644 (file)
@@ -1,9 +1,7 @@
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.21 - January 15, 2016
- Updated and distributed by Glenn Randers-Pehrson
- <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 2018 Cosmin Truta
+ Copyright (c) 1998-2018 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
@@ -11,9 +9,13 @@ libpng-manual.txt - A description on how to use and modify libpng
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.21 - January 15, 2016
+ libpng version 1.6.36 - December 1, 2018
+ Updated and distributed by Cosmin Truta
+ Copyright (c) 2018 Cosmin Truta
+
+ libpng versions 0.97, January 1998, through 1.6.35 - July 15, 2018
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 1998-2018 Glenn Randers-Pehrson
 
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
@@ -45,7 +47,6 @@ libpng-manual.txt - A description on how to use and modify libpng
  XIII. Detecting libpng
   XIV. Source code repository
    XV. Coding style
-  XVI. Y2K Compliance in libpng
 
 I. Introduction
 
@@ -66,17 +67,17 @@ file format in application programs.
 
 The PNG specification (second edition), November 2003, is available as
 a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
-<http://www.w3.org/TR/2003/REC-PNG-20031110/
+<https://www.w3.org/TR/2003/REC-PNG-20031110/>.
 The W3C and ISO documents have identical technical content.
 
 The PNG-1.2 specification is available at
-<http://png-mng.sourceforge.net/pub/png/spec/1.2/>.
+<https://png-mng.sourceforge.io/pub/png/spec/1.2/>.
 It is technically equivalent
 to the PNG specification (second edition) but has some additional material.
 
-The PNG-1.0 specification is available as RFC 2083 
-<http://png-mng.sourceforge.net/pub/png/spec/1.0/> and as a
-W3C Recommendation <http://www.w3.org/TR/REC-png-961001>.
+The PNG-1.0 specification is available as RFC 2083 at
+<https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
+W3C Recommendation at <https://www.w3.org/TR/REC-png-961001>.
 
 Some additional chunks are described in the special-purpose public chunks
 documents at <http://www.libpng.org/pub/png/spec/register/>
@@ -101,7 +102,7 @@ majority of the needs of its users.
 
 Libpng uses zlib for its compression and decompression of PNG files.
 Further information about zlib, and the latest version of zlib, can
-be found at the zlib home page, <http://zlib.net/>.
+be found at the zlib home page, <https://zlib.net/>.
 The zlib compression utility is a general purpose utility that is
 useful for more than PNG files, and can be used without libpng.
 See the documentation delivered with zlib for more details.
@@ -348,18 +349,18 @@ Customizing libpng.
     FILE *fp = fopen(file_name, "rb");
     if (!fp)
     {
-       return (ERROR);
+       return ERROR;
     }
 
     if (fread(header, 1, number, fp) != number)
     {
-       return (ERROR);
+       return ERROR;
     }
 
     is_png = !png_sig_cmp(header, 0, number);
     if (!is_png)
     {
-       return (NOT_PNG);
+       return NOT_PNG;
     }
 
 Next, png_struct and png_info need to be allocated and initialized.  In
@@ -378,7 +379,7 @@ create the structure, so your application should check for that.
         user_error_fn, user_warning_fn);
 
     if (!png_ptr)
-       return (ERROR);
+       return ERROR;
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
 
@@ -386,7 +387,7 @@ create the structure, so your application should check for that.
     {
        png_destroy_read_struct(&png_ptr,
            (png_infopp)NULL, (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
 If you want to use your own memory allocation routines,
@@ -421,7 +422,7 @@ free any memory.
        png_destroy_read_struct(&png_ptr, &info_ptr,
            &end_info);
        fclose(fp);
-       return (ERROR);
+       return ERROR;
     }
 
 Pass (png_infopp)NULL instead of &end_info if you didn't create
@@ -467,8 +468,9 @@ the default, use
 
 The values for png_set_crc_action() say how libpng is to handle CRC errors in
 ancillary and critical chunks, and whether to use the data contained
-therein.  Note that it is impossible to "discard" data in a critical
-chunk.
+therein. Starting with libpng-1.6.26, this also governs how an ADLER32 error
+is handled while reading the IDAT chunk. Note that it is impossible to
+"discard" data in a critical chunk.
 
 Choices for (int) crit_action are
    PNG_CRC_DEFAULT      0  error/quit
@@ -485,6 +487,9 @@ Choices for (int) ancil_action are
    PNG_CRC_QUIET_USE    4  quiet/use data
    PNG_CRC_NO_CHANGE    5  use the current value
 
+When the setting for crit_action is PNG_CRC_QUIET_USE, the CRC and ADLER32
+checksums are not only ignored, but they are not evaluated.
+
 Setting up callback code
 
 You can set up a callback function to handle any unknown chunks in the
@@ -499,7 +504,7 @@ input stream. You must supply the function
 
            png_byte name[5];
            png_byte *data;
-           png_size_t size;
+           size_t size;
 
        /* Note that libpng has already taken care of
           the CRC handling */
@@ -508,9 +513,9 @@ input stream. You must supply the function
           unknown chunk structure, process it, and return one
           of the following: */
 
-       return (-n); /* chunk had an error */
-       return (0); /* did not recognize */
-       return (n); /* success */
+       return -n; /* chunk had an error */
+       return 0; /* did not recognize */
+       return n; /* success */
     }
 
 (You can give your function another name that you like instead of
@@ -559,7 +564,7 @@ non-interlaced case the row that was just handled is simply one less than the
 passed in row number, and pass will always be 0.  For the interlaced case the
 same applies unless the row value is 0, in which case the row just handled was
 the last one from one of the preceding passes.  Because interlacing may skip a
-pass you cannot be sure that the preceding pass is just 'pass-1', if you really
+pass you cannot be sure that the preceding pass is just 'pass-1'; if you really
 need to know what the last pass is record (row,pass) from the callback and use
 the last recorded value each time.
 
@@ -684,8 +689,9 @@ where 0x7fffffffL means unlimited.  You can retrieve this limit with
    chunk_cache_max = png_get_chunk_cache_max(png_ptr);
 
 Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of
-memory that a compressed chunk other than IDAT can occupy, when decompressed.
-You can change this limit with
+memory that any chunk other than IDAT can occupy, originally or when
+decompressed (prior to libpng-1.6.32 the limit was only applied to compressed
+chunks after decompression). You can change this limit with
 
    png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);
 
@@ -981,15 +987,24 @@ premultiplication.
 
     png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
 
-This is the default libpng handling of the alpha channel - it is not
-pre-multiplied into the color components.  In addition the call states
+Choices for the alpha_mode are
+
+    PNG_ALPHA_PNG           0 /* according to the PNG standard */
+    PNG_ALPHA_STANDARD      1 /* according to Porter/Duff */
+    PNG_ALPHA_ASSOCIATED    1 /* as above; this is the normal practice */
+    PNG_ALPHA_PREMULTIPLIED 1 /* as above */
+    PNG_ALPHA_OPTIMIZED     2 /* 'PNG' for opaque pixels, else 'STANDARD' */
+    PNG_ALPHA_BROKEN        3 /* the alpha channel is gamma encoded */
+
+PNG_ALPHA_PNG is the default libpng handling of the alpha channel. It is not
+pre-multiplied into the color components. In addition the call states
 that the output is for a sRGB system and causes all PNG files without gAMA
 chunks to be assumed to be encoded using sRGB.
 
     png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
 
 In this case the output is assumed to be something like an sRGB conformant
-display preceeded by a power-law lookup table of power 1.45.  This is how
+display preceded by a power-law lookup table of power 1.45.  This is how
 early Mac systems behaved.
 
     png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
@@ -997,7 +1012,7 @@ early Mac systems behaved.
 This is the classic Jim Blinn approach and will work in academic
 environments where everything is done by the book.  It has the shortcoming
 of assuming that input PNG data with no gamma information is linear - this
-is unlikely to be correct unless the PNG files where generated locally.
+is unlikely to be correct unless the PNG files were generated locally.
 Most of the time the output precision will be so low as to show
 significant banding in dark areas of the image.
 
@@ -1041,7 +1056,7 @@ faster.)
 
 When the default gamma of PNG files doesn't match the output gamma.
 If you have PNG files with no gamma information png_set_alpha_mode allows
-you to provide a default gamma, but it also sets the ouput gamma to the
+you to provide a default gamma, but it also sets the output gamma to the
 matching value.  If you know your PNG files have a gamma that doesn't
 match the output you can take advantage of the fact that
 png_set_alpha_mode always sets the output gamma but only sets the PNG
@@ -1186,7 +1201,20 @@ row_pointers prior to calling png_read_png() with
    png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 Alternatively you could allocate your image in one big block and define
-row_pointers[i] to point into the proper places in your block.
+row_pointers[i] to point into the proper places in your block, but first
+be sure that your platform is able to allocate such a large buffer:
+
+   /* Guard against integer overflow */
+   if (height > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
+   png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size);
+
+   for (int i=0; i<height, i++)
+      row_pointers[i]=buffer+i*width*pixel_size;
+
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 If you use png_set_rows(), the application is responsible for freeing
 row_pointers (and row_pointers[i], if they were separately allocated).
@@ -1313,6 +1341,11 @@ in until png_read_end() has read the chunk data following the image.
     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
     rowbytes       - number of bytes needed to hold a row
+                     This value, the bit_depth, color_type,
+                     and the number of channels can change
+                     if you use transforms such as
+                     png_set_expand(). See
+                     png_read_update_info(), below.
 
     signature = png_get_signature(png_ptr, info_ptr);
 
@@ -1431,6 +1464,11 @@ png_set_rgb_to_gray()).
                      the single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
 
+    png_get_eXIf_1(png_ptr, info_ptr, &num_exif, &exif);
+                     (PNG_INFO_eXIf)
+
+    exif           - Exif profile (array of png_byte)
+
     png_get_hIST(png_ptr, info_ptr, &hist);
                      (PNG_INFO_hIST)
 
@@ -2142,6 +2180,16 @@ are allocating one large chunk, you will need to build an
 array of pointers to each row, as it will be needed for some
 of the functions below.
 
+Be sure that your platform can allocate the buffer that you'll need.
+libpng internally checks for oversize width, but you'll need to
+do your own check for number_of_rows*width*pixel_size if you are using
+a multiple-row buffer:
+
+   /* Guard against integer overflow */
+   if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
 Remember: Before you call png_read_update_info(), the png_get_*()
 functions return the values corresponding to the original PNG image.
 After you call png_read_update_info the values refer to the image
@@ -2230,7 +2278,8 @@ is exactly the same.  If you are planning on displaying the image
 after each pass, the "rectangle" effect is generally considered the
 better looking one.
 
-If you only want the "sparkle" effect, just call png_read_rows() as
+If you only want the "sparkle" effect, just call png_read_row() or
+png_read_rows() as
 normal, with the third parameter NULL.  Make sure you make pass over
 the image number_of_passes times, and you don't change the data in the
 rows between calls.  You can change the locations of the data, just
@@ -2239,6 +2288,8 @@ pass, and assumes the data from previous passes is still valid.
 
     png_read_rows(png_ptr, row_pointers, NULL,
         number_of_rows);
+    or
+    png_read_row(png_ptr, row_pointers, NULL);
 
 If you only want the first effect (the rectangles), do the same as
 before except pass the row buffer in the third parameter, and leave
@@ -2246,6 +2297,8 @@ the second parameter NULL.
 
     png_read_rows(png_ptr, NULL, row_pointers,
         number_of_rows);
+    or
+    png_read_row(png_ptr, NULL, row_pointers);
 
 If you don't want libpng to handle the interlacing details, just call
 png_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images.
@@ -2357,7 +2410,7 @@ separate.
     {
        png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
    png_read_end(png_ptr, end_info);
@@ -2461,6 +2514,7 @@ your application instead of by libpng, you can use
              PNG_INFO_gAMA, PNG_INFO_sBIT,
              PNG_INFO_cHRM, PNG_INFO_PLTE,
              PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_eXIf,
              PNG_INFO_hIST, PNG_INFO_pHYs,
              PNG_INFO_oFFs, PNG_INFO_tIME,
              PNG_INFO_pCAL, PNG_INFO_sRGB,
@@ -2496,7 +2550,7 @@ png_infop info_ptr;
          user_error_fn, user_warning_fn);
 
     if (!png_ptr)
-        return (ERROR);
+        return ERROR;
 
     info_ptr = png_create_info_struct(png_ptr);
 
@@ -2504,14 +2558,14 @@ png_infop info_ptr;
     {
        png_destroy_read_struct(&png_ptr,
           (png_infopp)NULL, (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
     if (setjmp(png_jmpbuf(png_ptr)))
     {
        png_destroy_read_struct(&png_ptr, &info_ptr,
           (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
     /* This one's new.  You can provide functions
@@ -2545,7 +2599,7 @@ png_infop info_ptr;
     {
        png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
     /* This one's new also.  Simply give it a chunk
@@ -2689,7 +2743,7 @@ custom writing functions.  See the discussion under Customizing libpng.
     FILE *fp = fopen(file_name, "wb");
 
     if (!fp)
-       return (ERROR);
+       return ERROR;
 
 Next, png_struct and png_info need to be allocated and initialized.
 As these can be both relatively large, you may not want to store these
@@ -2704,14 +2758,14 @@ both "png_ptr"; you can call them anything you like, such as
         user_error_fn, user_warning_fn);
 
     if (!png_ptr)
-       return (ERROR);
+       return ERROR;
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
        png_destroy_write_struct(&png_ptr,
            (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
 If you want to use your own memory allocation routines,
@@ -2738,7 +2792,7 @@ section below for more information on the libpng error handling.
     {
     png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);
-       return (ERROR);
+       return ERROR;
     }
     ...
     return;
@@ -2842,7 +2896,7 @@ filter types.
        PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
        PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG  |
        PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
-       PNG_ALL_FILTERS);
+       PNG_ALL_FILTERS  | PNG_FAST_FILTERS);
 
 If an application wants to start and stop using particular filters during
 compression, it should start out with all of the filters (to ensure that
@@ -3060,6 +3114,11 @@ width, height, bit_depth, and color_type must be the same in each call.
                      single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
 
+    png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif);
+
+    exif           - Exif profile (array of
+                     png_byte) (PNG_INFO_eXIf)
+
     png_set_hIST(png_ptr, info_ptr, hist);
 
     hist           - histogram of palette (array of
@@ -3721,7 +3780,7 @@ in-memory bitmap formats or to be written from the same formats.  If these
 formats do not accommodate your needs then you can, and should, use the more
 sophisticated APIs above - these support a wide variety of in-memory formats
 and a wide variety of sophisticated transformations to those formats as well
-as a wide variety of APIs to manipulate ancilliary information.
+as a wide variety of APIs to manipulate ancillary information.
 
 To read a PNG file using the simplified API:
 
@@ -3815,7 +3874,7 @@ PNG_FORMAT_FLAG_LINEAR flag below.
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
-article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
 approximation used elsewhere in libpng.
 
 When an alpha channel is present it is expected to denote pixel coverage
@@ -3997,7 +4056,7 @@ Flags containing additional information about the image are held in
 the 'flags' field of png_image.
 
   PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01
-    This indicates the the RGB values of the in-memory bitmap do not
+    This indicates that the RGB values of the in-memory bitmap do not
     correspond to the red, green and blue end-points defined by sRGB.
 
   PNG_IMAGE_FLAG_FAST == 0x02
@@ -4044,7 +4103,7 @@ READ APIs
       The PNG header is read from the stdio FILE object.
 
    int png_image_begin_read_from_memory(png_imagep image,
-      png_const_voidp memory, png_size_t size)
+      png_const_voidp memory, size_t size)
 
       The PNG header is read from the given memory buffer.
 
@@ -4079,7 +4138,7 @@ READ APIs
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
-article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
 approximation used elsewhere in libpng.
 
 WRITE APIS
@@ -4103,6 +4162,13 @@ be written:
 
       Write the image to the named file.
 
+   int png_image_write_to_memory (png_imagep image, void *memory,
+      png_alloc_size_t * PNG_RESTRICT memory_bytes,
+      int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride,
+      const void *colormap));
+
+      Write the image to memory.
+
    int png_image_write_to_stdio(png_imagep image, FILE *file,
       int convert_to_8_bit, const void *buffer,
       png_int_32 row_stride, const void *colormap)
@@ -4190,10 +4256,10 @@ png_get_io_ptr().  For example:
 The replacement I/O functions must have prototypes as follows:
 
     void user_read_data(png_structp png_ptr,
-        png_bytep data, png_size_t length);
+        png_bytep data, size_t length);
 
     void user_write_data(png_structp png_ptr,
-        png_bytep data, png_size_t length);
+        png_bytep data, size_t length);
 
     void user_flush_data(png_structp png_ptr);
 
@@ -4230,8 +4296,6 @@ functions after png_create_*_struct() has been called by calling:
         png_voidp error_ptr, png_error_ptr error_fn,
         png_error_ptr warning_fn);
 
-    png_voidp error_ptr = png_get_error_ptr(png_ptr);
-
 If NULL is supplied for either error_fn or warning_fn, then the libpng
 default function will be used, calling fprintf() and/or longjmp() if a
 problem is encountered.  The replacement error functions should have
@@ -4243,6 +4307,11 @@ parameters as follows:
     void user_warning_fn(png_structp png_ptr,
         png_const_charp warning_msg);
 
+Then, within your user_error_fn or user_warning_fn, you can retrieve
+the error_ptr if you need it, by calling
+
+    png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
 The motivation behind using setjmp() and longjmp() is the C++ throw and
 catch exception handling methods.  This makes the code much easier to write,
 as there is no need to check every return code of every function call.
@@ -4250,7 +4319,7 @@ However, there are some uncertainties about the status of local variables
 after a longjmp, so the user may want to be careful about doing anything
 after setjmp returns non-zero besides returning itself.  Consult your
 compiler documentation for more details.  For an alternative approach, you
-may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net),
+may wish to use the "cexcept" facility (see https://cexcept.sourceforge.io/),
 which is illustrated in pngvalid.c and in contrib/visupng.
 
 Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
@@ -4380,8 +4449,9 @@ for any images with bit depths less than 8 bits/pixel.
 The 'method' parameter sets the main filtering method, which is
 currently only '0' in the PNG 1.2 specification.  The 'filters'
 parameter sets which filter(s), if any, should be used for each
-scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
-to turn filtering on and off, respectively.
+scanline.  Possible values are PNG_ALL_FILTERS, PNG_NO_FILTERS,
+or PNG_FAST_FILTERS to turn filtering on and off, or to turn on
+just the fast-decoding subset of filters, respectively.
 
 Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
 PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
@@ -4395,12 +4465,19 @@ means the first row must always be adaptively filtered, because libpng
 currently does not allocate the filter buffers until png_write_row()
 is called for the first time.)
 
-    filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+    filters = PNG_NO_FILTERS;
+    filters = PNG_ALL_FILTERS;
+    filters = PNG_FAST_FILTERS;
+
+    or
+
+    filters = PNG_FILTER_NONE | PNG_FILTER_SUB |
               PNG_FILTER_UP | PNG_FILTER_AVG |
-              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+              PNG_FILTER_PAETH;
 
     png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
        filters);
+
               The second parameter can also be
               PNG_INTRAPIXEL_DIFFERENCING if you are
               writing a PNG to be embedded in a MNG
@@ -4445,7 +4522,7 @@ When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
 having level = 0 will be printed.  There aren't any such statements in
 this version of libpng, but if you insert some they will be printed.
 
-VII.  MNG support
+VII. MNG support
 
 The MNG specification (available at http://www.libpng.org/pub/mng) allows
 certain extensions to PNG for PNG images that are embedded in MNG datastreams.
@@ -4470,9 +4547,9 @@ in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
 and the MHDR and MEND chunks.  Libpng does not provide support for these
 or any other MNG chunks; your application must provide its own support for
 them.  You may wish to consider using libmng (available at
-http://www.libmng.com) instead.
+https://www.libmng.com/) instead.
 
-VIII.  Changes to Libpng from version 0.88
+VIII. Changes to Libpng from version 0.88
 
 It should be noted that versions of libpng later than 0.96 are not
 distributed by the original libpng author, Guy Schalnat, nor by
@@ -4527,7 +4604,7 @@ application:
 
    png_uint_32 application_vn = PNG_LIBPNG_VER;
 
-IX.  Changes to Libpng from version 1.0.x to 1.2.x
+IX. Changes to Libpng from version 1.0.x to 1.2.x
 
 Support for user memory management was enabled by default.  To
 accomplish this, the functions png_create_read_struct_2(),
@@ -4624,7 +4701,7 @@ which also expands tRNS to alpha was replaced with
     png_set_expand_gray_1_2_4_to_8()
 which does not. It has been deprecated since libpng-1.0.18 and 1.2.9.
 
-X.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
+X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
 
 Private libpng prototypes and macro definitions were moved from
 png.h and pngconf.h into a new pngpriv.h header file.
@@ -4708,7 +4785,7 @@ behavior in case the application runs out of memory part-way through
 the process.
 
 We changed the prototypes of png_get_compression_buffer_size() and
-png_set_compression_buffer_size() to work with png_size_t instead of
+png_set_compression_buffer_size() to work with size_t instead of
 png_uint_32.
 
 Support for numbered error messages was removed by default, since we
@@ -4734,7 +4811,7 @@ was renamed to PNG_READ_QUANTIZE_SUPPORTED.
 
 We removed the trailing '.' from the warning and error messages.
 
-XI.  Changes to Libpng from version 1.4.x to 1.5.x
+XI. Changes to Libpng from version 1.4.x to 1.5.x
 
 From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
 function) incorrectly returned a value of type png_uint_32.
@@ -4775,7 +4852,8 @@ There are no substantial API changes between the non-deprecated parts of
 the 1.4.5 API and the 1.5.0 API; however, the ability to directly access
 members of the main libpng control structures, png_struct and png_info,
 deprecated in earlier versions of libpng, has been completely removed from
-libpng 1.5.
+libpng 1.5, and new private "pngstruct.h", "pnginfo.h", and "pngdebug.h"
+header files were created.
 
 We no longer include zlib.h in png.h.  The include statement has been moved
 to pngstruct.h, where it is not accessible by applications. Applications that
@@ -4796,7 +4874,7 @@ to png_bytepp, and in png_set_iCCP, from png_charp to png_const_bytep.
 There are changes of form in png.h, including new and changed macros to
 declare parts of the API.  Some API functions with arguments that are
 pointers to data not modified within the function have been corrected to
-declare these arguments with PNG_CONST.
+declare these arguments with const.
 
 Much of the internal use of C macros to control the library build has also
 changed and some of this is visible in the exported header files, in
@@ -4892,18 +4970,14 @@ PNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said
 that it could be used to override them.  Now this function will reduce or
 increase the limits.
 
-Starting in libpng-1.5.10, the user limits can be set en masse with the
-configuration option PNG_SAFE_LIMITS_SUPPORTED.  If this option is enabled,
-a set of "safe" limits is applied in pngpriv.h.  These can be overridden by
-application calls to png_set_user_limits(), png_set_user_chunk_cache_max(),
-and/or png_set_user_malloc_max() that increase or decrease the limits.  Also,
-in libpng-1.5.10 the default width and height limits were increased
-from 1,000,000 to 0x7fffffff (i.e., made unlimited).  Therefore, the
-limits are now
-                               default      safe
+Starting in libpng-1.5.22, default user limits were established. These
+can be overridden by application calls to png_set_user_limits(),
+png_set_user_chunk_cache_max(), and/or png_set_user_malloc_max().
+The limits are now
+                             max possible  default
    png_user_width_max        0x7fffffff    1,000,000
    png_user_height_max       0x7fffffff    1,000,000
-   png_user_chunk_cache_max  0 (unlimited)   128
+   png_user_chunk_cache_max  0 (unlimited) 1000
    png_user_chunk_malloc_max 0 (unlimited) 8,000,000
 
 The png_set_option() function (and the "options" member of the png struct) was
@@ -4995,7 +5069,7 @@ even though the default is to use the macros - this allows applications
 to choose at app buildtime whether or not to use macros (previously
 impossible because the functions weren't in the default build.)
 
-XII.  Changes to Libpng from version 1.5.x to 1.6.x
+XII. Changes to Libpng from version 1.5.x to 1.6.x
 
 A "simplified API" has been added (see documentation in png.h and a simple
 example in contrib/examples/pngtopng.c).  The new publicly visible API
@@ -5015,6 +5089,7 @@ includes the following:
      png_image_free()
    write functions
      png_image_write_to_file()
+     png_image_write_to_memory()
      png_image_write_to_stdio()
 
 Starting with libpng-1.6.0, you can configure libpng to prefix all exported
@@ -5152,7 +5227,12 @@ is an error. Previously this requirement of the PNG specification was not
 enforced, and the palette was always limited to 256 entries. An over-length
 PLTE chunk found in an input PNG is silently truncated.
 
-XIII.  Detecting libpng
+Starting with libpng-1.6.31, the eXIf chunk is supported. Libpng does not
+attempt to decode the Exif profile; it simply returns a byte array
+containing the profile to the calling application which must do its own
+decoding.
+
+XIII. Detecting libpng
 
 The png_get_io_ptr() function has been present since libpng-0.88, has never
 changed, and is unaffected by conditional compilation macros.  It is the
@@ -5168,27 +5248,32 @@ control.  The git repository was built from old libpng-x.y.z.tar.gz files
 going back to version 0.70.  You can access the git repository (read only)
 at
 
-    git://git.code.sf.net/p/libpng/code
+    https://github.com/glennrp/libpng or
+    https://git.code.sf.net/p/libpng/code.git
+
+or you can browse it with a web browser at
 
-or you can browse it with a web browser by selecting the "code" button at
+    https://github.com/glennrp/libpng or
+    https://sourceforge.net/p/libpng/code/ci/libpng16/tree/
 
-    https://sourceforge.net/projects/libpng
+Patches can be sent to png-mng-implement at lists.sourceforge.net or
+uploaded to the libpng bug tracker at
 
-Patches can be sent to glennrp at users.sourceforge.net or to
-png-mng-implement at lists.sourceforge.net or you can upload them to
-the libpng bug tracker at
+    https://libpng.sourceforge.io/
 
-    http://libpng.sourceforge.net
+or as a "pull request" to
+
+    https://github.com/glennrp/libpng/pulls
 
 We also accept patches built from the tar or zip distributions, and
-simple verbal discriptions of bug fixes, reported either to the
+simple verbal descriptions of bug fixes, reported either to the
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
-mailing list, or directly to glennrp.
+mailing list, as github issues.
 
 XV. Coding style
 
 Our coding style is similar to the "Allman" style
-(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly
+(See https://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly
 braces on separate lines:
 
     if (condition)
@@ -5204,7 +5289,7 @@ braces on separate lines:
 The braces can be omitted from simple one-line actions:
 
     if (condition)
-       return (0);
+       return 0;
 
 We use 3-space indentation, except for continued statements which
 are usually indented the same as the first line of the statement
@@ -5289,7 +5374,7 @@ Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as
 though it were a function.
 
 Control keywords if, for, while, and switch are always followed by a space
-to distinguish them from function calls, which have no trailing space. 
+to distinguish them from function calls, which have no trailing space.
 
 We put a space after each comma and after each semicolon
 in "for" statements, and we put spaces before and after each
@@ -5313,66 +5398,12 @@ with an even number of lower-case hex digits, and to make them unsigned
 We prefer to use underscores rather than camelCase in names, except
 for a few type names that we inherit from zlib.h.
 
-We prefer "if (something != 0)" and "if (something == 0)"
-over "if (something)" and if "(!something)", respectively.
+We prefer "if (something != 0)" and "if (something == 0)" over
+"if (something)" and if "(!something)", respectively, and for pointers
+we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)".
 
 We do not use the TAB character for indentation in the C sources.
 
 Lines do not exceed 80 characters.
 
 Other rules can be inferred by inspecting the libpng source.
-
-XVI. Y2K Compliance in libpng
-
-Since the PNG Development group is an ad-hoc body, we can't make
-an official declaration.
-
-This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.21 are Y2K compliant.  It is my belief that earlier
-versions were also Y2K compliant.
-
-Libpng only has two year fields.  One is a 2-byte unsigned integer
-that will hold years up to 65535.  The other, which is deprecated,
-holds the date in text format, and will hold years up to 9999.
-
-The integer is
-    "png_uint_16 year" in png_time_struct.
-
-The string is
-    "char time_buffer[29]" in png_struct.  This is no longer used
-in libpng-1.6.x and will be removed from libpng-1.7.0.
-
-There are seven time-related functions:
-
-    png_convert_to_rfc_1123_buffer() in png.c
-      (formerly png_convert_to_rfc_1152() in error, and
-      also formerly png_convert_to_rfc_1123())
-    png_convert_from_struct_tm() in pngwrite.c, called
-      in pngwrite.c
-    png_convert_from_time_t() in pngwrite.c
-    png_get_tIME() in pngget.c
-    png_handle_tIME() in pngrutil.c, called in pngread.c
-    png_set_tIME() in pngset.c
-    png_write_tIME() in pngwutil.c, called in pngwrite.c
-
-All appear to handle dates properly in a Y2K environment.  The
-png_convert_from_time_t() function calls gmtime() to convert from system
-clock time, which returns (year - 1900), which we properly convert to
-the full 4-digit year.  There is a possibility that applications using
-libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or that they are incorrectly passing only a 2-digit year
-instead of "year - 1900" into the png_convert_from_struct_tm() function,
-but this is not under our control.  The libpng documentation has always
-stated that it works with 4-digit years, and the APIs have been
-documented as such.
-
-The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
-integer to hold the year, and can hold years as large as 65535.
-
-zlib, upon which libpng depends, is also Y2K compliant.  It contains
-no date-related code.
-
-
-   Glenn Randers-Pehrson
-   libpng maintainer
-   PNG Development Group
index b1f0c93..9757deb 100644 (file)
--- a/libpng.3
+++ b/libpng.3
@@ -1,11 +1,11 @@
-.TH LIBPNG 3 "January 15, 2016"
+.TH LIBPNG 3 "December 1, 2018"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.36
+
 .SH SYNOPSIS
-\fB
-#include <png.h>\fP
+\fB#include <png.h>\fP
 
-\fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP
+\fBpng_uint_32 png_access_version_number (void);\fP
 
 \fBvoid png_benign_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
 
@@ -35,7 +35,7 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBpng_structp png_create_write_struct_2 (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
 
-\fBvoid png_data_freer (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIfreer\fP\fB, png_uint_32 \fImask)\fP\fB);\fP
+\fBvoid png_data_freer (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIfreer\fP\fB, png_uint_32 \fImask\fP\fB);\fP
 
 \fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
 
@@ -97,6 +97,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBpng_byte png_get_header_version (png_const_structp \fIpng_ptr\fP\fB);\fP
 
+\fBpng_uint_32 png_get_eXIf (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fI*exif\fP\fB);\fP
+
+\fBpng_uint_32 png_get_eXIf_1 (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_unit_32 \fP\fI*num_exif\fP\fB, png_bytep \fI*exif\fP\fB);\fP
+
 \fBpng_uint_32 png_get_hIST (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP
 
 \fBpng_uint_32 png_get_iCCP (png_const_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_bytepp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP
@@ -221,7 +225,7 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBint png_image_begin_read_from_stdio (png_imagep \fP\fIimage\fP\fB, FILE* \fIfile\fP\fB);\fP
 
-\fBint, png_image_begin_read_from_memory (png_imagep \fP\fIimage\fP\fB, png_const_voidp \fP\fImemory\fP\fB, png_size_t \fIsize\fP\fB);\fP
+\fBint, png_image_begin_read_from_memory (png_imagep \fP\fIimage\fP\fB, png_const_voidp \fP\fImemory\fP\fB, size_t \fIsize\fP\fB);\fP
 
 \fBint png_image_finish_read (png_imagep \fP\fIimage\fP\fB, png_colorp \fP\fIbackground\fP\fB, void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap\fP\fB);\fP
 
@@ -229,9 +233,11 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBint png_image_write_to_file (png_imagep \fP\fIimage\fP\fB, const char \fP\fI*file\fP\fB, int \fP\fIconvert_to_8bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap\fP\fB);\fP
 
-\fBint png_image_write_to_stdio (png_imagep \fP\fIimage\fP\fB, FILE \fP\fI*file\fP\fB, int \fP\fIconvert_to_8_bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap)\fP\fB);\fP
+\fBint png_image_write_to_memory (png_imagep \fP\fIimage\fP\fB, void \fP\fI*memory\fP\fB, png_alloc_size_t * PNG_RESTRICT \fP\fImemory_bytes\fP\fB, int \fP\fIconvert_to_8_bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, const void \fI*colormap\fP\fB);\fP
 
-\fBvoid png_info_init_3 (png_infopp \fP\fIinfo_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP
+\fBint png_image_write_to_stdio (png_imagep \fP\fIimage\fP\fB, FILE \fP\fI*file\fP\fB, int \fP\fIconvert_to_8_bit\fP\fB, const void \fP\fI*buffer\fP\fB, png_int_32 \fP\fIrow_stride\fP\fB, void \fI*colormap\fP\fB);\fP
+
+\fBvoid png_info_init_3 (png_infopp \fP\fIinfo_ptr\fP\fB, size_t \fIpng_info_struct_size\fP\fB);\fP
 
 \fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
 
@@ -245,11 +251,11 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBpng_uint_32 png_permit_mng_features (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fImng_features_permitted\fP\fB);\fP
 
-\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP
+\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, size_t \fIbuffer_size\fP\fB);\fP
 
-\fBpng_size_t png_process_data_pause \fP\fI(png_structp\fP\fB, int \fIsave\fP\fB);\fP
+\fBsize_t png_process_data_pause (png_structp \fP\fIpng_ptr\fP\fB, int \fIsave\fP\fB);\fP
 
-\fBpng_uint_32 png_process_data_skip \fI(png_structp\fP\fB);\fP
+\fBpng_uint_32 png_process_data_skip (png_structp \fP\fIpng_ptr\fP\fB);\fP
 
 \fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP
 
@@ -291,7 +297,7 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP
 
-\fBvoid png_set_check_for_invalid_index(png_structrp \fP\fIpng_ptr\fP\fB, int \fIallowed\fP\fB);\fP
+\fBvoid png_set_check_for_invalid_index (png_structrp \fP\fIpng_ptr\fP\fB, int \fIallowed\fP\fB);\fP
 
 \fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
 
@@ -345,6 +351,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
 
+\fBvoid png_set_eXIf (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fIexif\fP\fB);\fP
+
+\fBvoid png_set_eXIf_1 (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fInum_exif\fP\fB, png_bytep \fIexif\fP\fB);\fP
+
 \fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP
 
 \fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_const_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_const_bytep \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP
@@ -443,7 +453,7 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBvoid png_set_text_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
 
-\fBvoid \fP\fIpng_set_text_compression_method\fP\fB, (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod)\fP\fB);\fP
+\fBvoid png_set_text_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP
 
 \fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
 
@@ -465,15 +475,15 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
 
 \fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP
 
-\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP
+\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, size_t \fP\fIstart\fP\fB, size_t \fInum_to_check\fP\fB);\fP
 
 \fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP
 
 \fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
 
-\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, size_t \fIlength\fP\fB);\fP
 
-\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, size_t \fIlength\fP\fB);\fP
 
 \fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP
 
@@ -505,13 +515,12 @@ the Portable Network Graphics (PNG) format image files.  It uses the
 .IR zlib(3)
 compression library.
 Following is a copy of the libpng-manual.txt file that accompanies libpng.
+
 .SH LIBPNG.TXT
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.21 - January 15, 2016
- Updated and distributed by Glenn Randers-Pehrson
- <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 2018 Cosmin Truta
+ Copyright (c) 1998-2018 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
@@ -519,9 +528,13 @@ libpng-manual.txt - A description on how to use and modify libpng
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.21 - January 15, 2016
+ libpng version 1.6.36 - December 1, 2018
+ Updated and distributed by Cosmin Truta
+ Copyright (c) 2018 Cosmin Truta
+
+ libpng versions 0.97, January 1998, through 1.6.35 - July 15, 2018
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 1998-2018 Glenn Randers-Pehrson
 
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
@@ -553,7 +566,6 @@ libpng-manual.txt - A description on how to use and modify libpng
  XIII. Detecting libpng
   XIV. Source code repository
    XV. Coding style
-  XVI. Y2K Compliance in libpng
 
 .SH I. Introduction
 
@@ -574,17 +586,17 @@ file format in application programs.
 
 The PNG specification (second edition), November 2003, is available as
 a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
-<http://www.w3.org/TR/2003/REC-PNG-20031110/
+<https://www.w3.org/TR/2003/REC-PNG-20031110/>.
 The W3C and ISO documents have identical technical content.
 
 The PNG-1.2 specification is available at
-<http://png-mng.sourceforge.net/pub/png/spec/1.2/>.
+<https://png-mng.sourceforge.io/pub/png/spec/1.2/>.
 It is technically equivalent
 to the PNG specification (second edition) but has some additional material.
 
-The PNG-1.0 specification is available as RFC 2083 
-<http://png-mng.sourceforge.net/pub/png/spec/1.0/> and as a
-W3C Recommendation <http://www.w3.org/TR/REC-png-961001>.
+The PNG-1.0 specification is available as RFC 2083 at
+<https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
+W3C Recommendation at <https://www.w3.org/TR/REC-png-961001>.
 
 Some additional chunks are described in the special-purpose public chunks
 documents at <http://www.libpng.org/pub/png/spec/register/>
@@ -609,7 +621,7 @@ majority of the needs of its users.
 
 Libpng uses zlib for its compression and decompression of PNG files.
 Further information about zlib, and the latest version of zlib, can
-be found at the zlib home page, <http://zlib.net/>.
+be found at the zlib home page, <https://zlib.net/>.
 The zlib compression utility is a general purpose utility that is
 useful for more than PNG files, and can be used without libpng.
 See the documentation delivered with zlib for more details.
@@ -856,18 +868,18 @@ Customizing libpng.
     FILE *fp = fopen(file_name, "rb");
     if (!fp)
     {
-       return (ERROR);
+       return ERROR;
     }
 
     if (fread(header, 1, number, fp) != number)
     {
-       return (ERROR);
+       return ERROR;
     }
 
     is_png = !png_sig_cmp(header, 0, number);
     if (!is_png)
     {
-       return (NOT_PNG);
+       return NOT_PNG;
     }
 
 Next, png_struct and png_info need to be allocated and initialized.  In
@@ -886,7 +898,7 @@ create the structure, so your application should check for that.
         user_error_fn, user_warning_fn);
 
     if (!png_ptr)
-       return (ERROR);
+       return ERROR;
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
 
@@ -894,7 +906,7 @@ create the structure, so your application should check for that.
     {
        png_destroy_read_struct(&png_ptr,
            (png_infopp)NULL, (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
 If you want to use your own memory allocation routines,
@@ -929,7 +941,7 @@ free any memory.
        png_destroy_read_struct(&png_ptr, &info_ptr,
            &end_info);
        fclose(fp);
-       return (ERROR);
+       return ERROR;
     }
 
 Pass (png_infopp)NULL instead of &end_info if you didn't create
@@ -975,8 +987,9 @@ the default, use
 
 The values for png_set_crc_action() say how libpng is to handle CRC errors in
 ancillary and critical chunks, and whether to use the data contained
-therein.  Note that it is impossible to "discard" data in a critical
-chunk.
+therein. Starting with libpng-1.6.26, this also governs how an ADLER32 error
+is handled while reading the IDAT chunk. Note that it is impossible to
+"discard" data in a critical chunk.
 
 Choices for (int) crit_action are
    PNG_CRC_DEFAULT      0  error/quit
@@ -993,6 +1006,9 @@ Choices for (int) ancil_action are
    PNG_CRC_QUIET_USE    4  quiet/use data
    PNG_CRC_NO_CHANGE    5  use the current value
 
+When the setting for crit_action is PNG_CRC_QUIET_USE, the CRC and ADLER32
+checksums are not only ignored, but they are not evaluated.
+
 .SS Setting up callback code
 
 You can set up a callback function to handle any unknown chunks in the
@@ -1007,7 +1023,7 @@ input stream. You must supply the function
 
            png_byte name[5];
            png_byte *data;
-           png_size_t size;
+           size_t size;
 
        /* Note that libpng has already taken care of
           the CRC handling */
@@ -1016,9 +1032,9 @@ input stream. You must supply the function
           unknown chunk structure, process it, and return one
           of the following: */
 
-       return (\-n); /* chunk had an error */
-       return (0); /* did not recognize */
-       return (n); /* success */
+       return \-n; /* chunk had an error */
+       return 0; /* did not recognize */
+       return n; /* success */
     }
 
 (You can give your function another name that you like instead of
@@ -1067,7 +1083,7 @@ non-interlaced case the row that was just handled is simply one less than the
 passed in row number, and pass will always be 0.  For the interlaced case the
 same applies unless the row value is 0, in which case the row just handled was
 the last one from one of the preceding passes.  Because interlacing may skip a
-pass you cannot be sure that the preceding pass is just 'pass\-1', if you really
+pass you cannot be sure that the preceding pass is just 'pass\-1'; if you really
 need to know what the last pass is record (row,pass) from the callback and use
 the last recorded value each time.
 
@@ -1192,8 +1208,9 @@ where 0x7fffffffL means unlimited.  You can retrieve this limit with
    chunk_cache_max = png_get_chunk_cache_max(png_ptr);
 
 Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of
-memory that a compressed chunk other than IDAT can occupy, when decompressed.
-You can change this limit with
+memory that any chunk other than IDAT can occupy, originally or when
+decompressed (prior to libpng-1.6.32 the limit was only applied to compressed
+chunks after decompression). You can change this limit with
 
    png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);
 
@@ -1489,15 +1506,24 @@ premultiplication.
 
     png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
 
-This is the default libpng handling of the alpha channel - it is not
-pre-multiplied into the color components.  In addition the call states
+Choices for the alpha_mode are
+
+    PNG_ALPHA_PNG           0 /* according to the PNG standard */
+    PNG_ALPHA_STANDARD      1 /* according to Porter/Duff */
+    PNG_ALPHA_ASSOCIATED    1 /* as above; this is the normal practice */
+    PNG_ALPHA_PREMULTIPLIED 1 /* as above */
+    PNG_ALPHA_OPTIMIZED     2 /* 'PNG' for opaque pixels, else 'STANDARD' */
+    PNG_ALPHA_BROKEN        3 /* the alpha channel is gamma encoded */
+
+PNG_ALPHA_PNG is the default libpng handling of the alpha channel. It is not
+pre-multiplied into the color components. In addition the call states
 that the output is for a sRGB system and causes all PNG files without gAMA
 chunks to be assumed to be encoded using sRGB.
 
     png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
 
 In this case the output is assumed to be something like an sRGB conformant
-display preceeded by a power-law lookup table of power 1.45.  This is how
+display preceded by a power-law lookup table of power 1.45.  This is how
 early Mac systems behaved.
 
     png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
@@ -1505,7 +1531,7 @@ early Mac systems behaved.
 This is the classic Jim Blinn approach and will work in academic
 environments where everything is done by the book.  It has the shortcoming
 of assuming that input PNG data with no gamma information is linear - this
-is unlikely to be correct unless the PNG files where generated locally.
+is unlikely to be correct unless the PNG files were generated locally.
 Most of the time the output precision will be so low as to show
 significant banding in dark areas of the image.
 
@@ -1549,7 +1575,7 @@ faster.)
 
 When the default gamma of PNG files doesn't match the output gamma.
 If you have PNG files with no gamma information png_set_alpha_mode allows
-you to provide a default gamma, but it also sets the ouput gamma to the
+you to provide a default gamma, but it also sets the output gamma to the
 matching value.  If you know your PNG files have a gamma that doesn't
 match the output you can take advantage of the fact that
 png_set_alpha_mode always sets the output gamma but only sets the PNG
@@ -1694,7 +1720,20 @@ row_pointers prior to calling png_read_png() with
    png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 Alternatively you could allocate your image in one big block and define
-row_pointers[i] to point into the proper places in your block.
+row_pointers[i] to point into the proper places in your block, but first
+be sure that your platform is able to allocate such a large buffer:
+
+   /* Guard against integer overflow */
+   if (height > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
+   png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size);
+
+   for (int i=0; i<height, i++)
+      row_pointers[i]=buffer+i*width*pixel_size;
+
+   png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 If you use png_set_rows(), the application is responsible for freeing
 row_pointers (and row_pointers[i], if they were separately allocated).
@@ -1821,6 +1860,11 @@ in until png_read_end() has read the chunk data following the image.
     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
     rowbytes       - number of bytes needed to hold a row
+                     This value, the bit_depth, color_type,
+                     and the number of channels can change
+                     if you use transforms such as
+                     png_set_expand(). See
+                     png_read_update_info(), below.
 
     signature = png_get_signature(png_ptr, info_ptr);
 
@@ -1939,6 +1983,11 @@ png_set_rgb_to_gray()).
                      the single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
 
+    png_get_eXIf_1(png_ptr, info_ptr, &num_exif, &exif);
+                     (PNG_INFO_eXIf)
+
+    exif           - Exif profile (array of png_byte)
+
     png_get_hIST(png_ptr, info_ptr, &hist);
                      (PNG_INFO_hIST)
 
@@ -2650,6 +2699,16 @@ are allocating one large chunk, you will need to build an
 array of pointers to each row, as it will be needed for some
 of the functions below.
 
+Be sure that your platform can allocate the buffer that you'll need.
+libpng internally checks for oversize width, but you'll need to
+do your own check for number_of_rows*width*pixel_size if you are using
+a multiple-row buffer:
+
+   /* Guard against integer overflow */
+   if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) {
+        png_error(png_ptr,"image_data buffer would be too large");
+   }
+
 Remember: Before you call png_read_update_info(), the png_get_*()
 functions return the values corresponding to the original PNG image.
 After you call png_read_update_info the values refer to the image
@@ -2738,7 +2797,8 @@ is exactly the same.  If you are planning on displaying the image
 after each pass, the "rectangle" effect is generally considered the
 better looking one.
 
-If you only want the "sparkle" effect, just call png_read_rows() as
+If you only want the "sparkle" effect, just call png_read_row() or
+png_read_rows() as
 normal, with the third parameter NULL.  Make sure you make pass over
 the image number_of_passes times, and you don't change the data in the
 rows between calls.  You can change the locations of the data, just
@@ -2747,6 +2807,8 @@ pass, and assumes the data from previous passes is still valid.
 
     png_read_rows(png_ptr, row_pointers, NULL,
         number_of_rows);
+    or
+    png_read_row(png_ptr, row_pointers, NULL);
 
 If you only want the first effect (the rectangles), do the same as
 before except pass the row buffer in the third parameter, and leave
@@ -2754,6 +2816,8 @@ the second parameter NULL.
 
     png_read_rows(png_ptr, NULL, row_pointers,
         number_of_rows);
+    or
+    png_read_row(png_ptr, NULL, row_pointers);
 
 If you don't want libpng to handle the interlacing details, just call
 png_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images.
@@ -2865,7 +2929,7 @@ separate.
     {
        png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
    png_read_end(png_ptr, end_info);
@@ -2969,6 +3033,7 @@ your application instead of by libpng, you can use
              PNG_INFO_gAMA, PNG_INFO_sBIT,
              PNG_INFO_cHRM, PNG_INFO_PLTE,
              PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_eXIf,
              PNG_INFO_hIST, PNG_INFO_pHYs,
              PNG_INFO_oFFs, PNG_INFO_tIME,
              PNG_INFO_pCAL, PNG_INFO_sRGB,
@@ -3004,7 +3069,7 @@ png_infop info_ptr;
          user_error_fn, user_warning_fn);
 
     if (!png_ptr)
-        return (ERROR);
+        return ERROR;
 
     info_ptr = png_create_info_struct(png_ptr);
 
@@ -3012,14 +3077,14 @@ png_infop info_ptr;
     {
        png_destroy_read_struct(&png_ptr,
           (png_infopp)NULL, (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
     if (setjmp(png_jmpbuf(png_ptr)))
     {
        png_destroy_read_struct(&png_ptr, &info_ptr,
           (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
     /* This one's new.  You can provide functions
@@ -3053,7 +3118,7 @@ png_infop info_ptr;
     {
        png_destroy_read_struct(&png_ptr, &info_ptr,
            (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
     /* This one's new also.  Simply give it a chunk
@@ -3197,7 +3262,7 @@ custom writing functions.  See the discussion under Customizing libpng.
     FILE *fp = fopen(file_name, "wb");
 
     if (!fp)
-       return (ERROR);
+       return ERROR;
 
 Next, png_struct and png_info need to be allocated and initialized.
 As these can be both relatively large, you may not want to store these
@@ -3212,14 +3277,14 @@ both "png_ptr"; you can call them anything you like, such as
         user_error_fn, user_warning_fn);
 
     if (!png_ptr)
-       return (ERROR);
+       return ERROR;
 
     png_infop info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr)
     {
        png_destroy_write_struct(&png_ptr,
            (png_infopp)NULL);
-       return (ERROR);
+       return ERROR;
     }
 
 If you want to use your own memory allocation routines,
@@ -3246,7 +3311,7 @@ section below for more information on the libpng error handling.
     {
     png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);
-       return (ERROR);
+       return ERROR;
     }
     ...
     return;
@@ -3350,7 +3415,7 @@ filter types.
        PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
        PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG  |
        PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
-       PNG_ALL_FILTERS);
+       PNG_ALL_FILTERS  | PNG_FAST_FILTERS);
 
 If an application wants to start and stop using particular filters during
 compression, it should start out with all of the filters (to ensure that
@@ -3568,6 +3633,11 @@ width, height, bit_depth, and color_type must be the same in each call.
                      single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
 
+    png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif);
+
+    exif           - Exif profile (array of
+                     png_byte) (PNG_INFO_eXIf)
+
     png_set_hIST(png_ptr, info_ptr, hist);
 
     hist           - histogram of palette (array of
@@ -4229,7 +4299,7 @@ in-memory bitmap formats or to be written from the same formats.  If these
 formats do not accommodate your needs then you can, and should, use the more
 sophisticated APIs above - these support a wide variety of in-memory formats
 and a wide variety of sophisticated transformations to those formats as well
-as a wide variety of APIs to manipulate ancilliary information.
+as a wide variety of APIs to manipulate ancillary information.
 
 To read a PNG file using the simplified API:
 
@@ -4323,7 +4393,7 @@ PNG_FORMAT_FLAG_LINEAR flag below.
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
-article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
 approximation used elsewhere in libpng.
 
 When an alpha channel is present it is expected to denote pixel coverage
@@ -4505,7 +4575,7 @@ Flags containing additional information about the image are held in
 the 'flags' field of png_image.
 
   PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01
-    This indicates the the RGB values of the in-memory bitmap do not
+    This indicates that the RGB values of the in-memory bitmap do not
     correspond to the red, green and blue end-points defined by sRGB.
 
   PNG_IMAGE_FLAG_FAST == 0x02
@@ -4552,7 +4622,7 @@ READ APIs
       The PNG header is read from the stdio FILE object.
 
    int png_image_begin_read_from_memory(png_imagep image,
-      png_const_voidp memory, png_size_t size)
+      png_const_voidp memory, size_t size)
 
       The PNG header is read from the given memory buffer.
 
@@ -4587,7 +4657,7 @@ READ APIs
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
-article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
 approximation used elsewhere in libpng.
 
 WRITE APIS
@@ -4611,6 +4681,13 @@ be written:
 
       Write the image to the named file.
 
+   int png_image_write_to_memory (png_imagep image, void *memory,
+      png_alloc_size_t * PNG_RESTRICT memory_bytes,
+      int convert_to_8_bit, const void *buffer, ptrdiff_t row_stride,
+      const void *colormap));
+
+      Write the image to memory.
+
    int png_image_write_to_stdio(png_imagep image, FILE *file,
       int convert_to_8_bit, const void *buffer,
       png_int_32 row_stride, const void *colormap)
@@ -4698,10 +4775,10 @@ png_get_io_ptr().  For example:
 The replacement I/O functions must have prototypes as follows:
 
     void user_read_data(png_structp png_ptr,
-        png_bytep data, png_size_t length);
+        png_bytep data, size_t length);
 
     void user_write_data(png_structp png_ptr,
-        png_bytep data, png_size_t length);
+        png_bytep data, size_t length);
 
     void user_flush_data(png_structp png_ptr);
 
@@ -4738,8 +4815,6 @@ functions after png_create_*_struct() has been called by calling:
         png_voidp error_ptr, png_error_ptr error_fn,
         png_error_ptr warning_fn);
 
-    png_voidp error_ptr = png_get_error_ptr(png_ptr);
-
 If NULL is supplied for either error_fn or warning_fn, then the libpng
 default function will be used, calling fprintf() and/or longjmp() if a
 problem is encountered.  The replacement error functions should have
@@ -4751,6 +4826,11 @@ parameters as follows:
     void user_warning_fn(png_structp png_ptr,
         png_const_charp warning_msg);
 
+Then, within your user_error_fn or user_warning_fn, you can retrieve
+the error_ptr if you need it, by calling
+
+    png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
 The motivation behind using setjmp() and longjmp() is the C++ throw and
 catch exception handling methods.  This makes the code much easier to write,
 as there is no need to check every return code of every function call.
@@ -4758,7 +4838,7 @@ However, there are some uncertainties about the status of local variables
 after a longjmp, so the user may want to be careful about doing anything
 after setjmp returns non-zero besides returning itself.  Consult your
 compiler documentation for more details.  For an alternative approach, you
-may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net),
+may wish to use the "cexcept" facility (see https://cexcept.sourceforge.io/),
 which is illustrated in pngvalid.c and in contrib/visupng.
 
 Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
@@ -4888,8 +4968,9 @@ for any images with bit depths less than 8 bits/pixel.
 The 'method' parameter sets the main filtering method, which is
 currently only '0' in the PNG 1.2 specification.  The 'filters'
 parameter sets which filter(s), if any, should be used for each
-scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
-to turn filtering on and off, respectively.
+scanline.  Possible values are PNG_ALL_FILTERS, PNG_NO_FILTERS,
+or PNG_FAST_FILTERS to turn filtering on and off, or to turn on
+just the fast-decoding subset of filters, respectively.
 
 Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
 PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
@@ -4903,12 +4984,19 @@ means the first row must always be adaptively filtered, because libpng
 currently does not allocate the filter buffers until png_write_row()
 is called for the first time.)
 
-    filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+    filters = PNG_NO_FILTERS;
+    filters = PNG_ALL_FILTERS;
+    filters = PNG_FAST_FILTERS;
+
+    or
+
+    filters = PNG_FILTER_NONE | PNG_FILTER_SUB |
               PNG_FILTER_UP | PNG_FILTER_AVG |
-              PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+              PNG_FILTER_PAETH;
 
     png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
        filters);
+
               The second parameter can also be
               PNG_INTRAPIXEL_DIFFERENCING if you are
               writing a PNG to be embedded in a MNG
@@ -4953,7 +5041,7 @@ When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
 having level = 0 will be printed.  There aren't any such statements in
 this version of libpng, but if you insert some they will be printed.
 
-.SH VII.  MNG support
+.SH VII. MNG support
 
 The MNG specification (available at http://www.libpng.org/pub/mng) allows
 certain extensions to PNG for PNG images that are embedded in MNG datastreams.
@@ -4978,9 +5066,9 @@ in a MNG datastream.  As a minimum, it must have the MNG 8-byte signature
 and the MHDR and MEND chunks.  Libpng does not provide support for these
 or any other MNG chunks; your application must provide its own support for
 them.  You may wish to consider using libmng (available at
-http://www.libmng.com) instead.
+https://www.libmng.com/) instead.
 
-.SH VIII.  Changes to Libpng from version 0.88
+.SH VIII. Changes to Libpng from version 0.88
 
 It should be noted that versions of libpng later than 0.96 are not
 distributed by the original libpng author, Guy Schalnat, nor by
@@ -5035,7 +5123,7 @@ application:
 
    png_uint_32 application_vn = PNG_LIBPNG_VER;
 
-.SH IX.  Changes to Libpng from version 1.0.x to 1.2.x
+.SH IX. Changes to Libpng from version 1.0.x to 1.2.x
 
 Support for user memory management was enabled by default.  To
 accomplish this, the functions png_create_read_struct_2(),
@@ -5132,7 +5220,7 @@ which also expands tRNS to alpha was replaced with
     png_set_expand_gray_1_2_4_to_8()
 which does not. It has been deprecated since libpng-1.0.18 and 1.2.9.
 
-.SH X.  Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
+.SH X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
 
 Private libpng prototypes and macro definitions were moved from
 png.h and pngconf.h into a new pngpriv.h header file.
@@ -5216,7 +5304,7 @@ behavior in case the application runs out of memory part-way through
 the process.
 
 We changed the prototypes of png_get_compression_buffer_size() and
-png_set_compression_buffer_size() to work with png_size_t instead of
+png_set_compression_buffer_size() to work with size_t instead of
 png_uint_32.
 
 Support for numbered error messages was removed by default, since we
@@ -5242,7 +5330,7 @@ was renamed to PNG_READ_QUANTIZE_SUPPORTED.
 
 We removed the trailing '.' from the warning and error messages.
 
-.SH XI.  Changes to Libpng from version 1.4.x to 1.5.x
+.SH XI. Changes to Libpng from version 1.4.x to 1.5.x
 
 From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
 function) incorrectly returned a value of type png_uint_32.
@@ -5283,7 +5371,8 @@ There are no substantial API changes between the non-deprecated parts of
 the 1.4.5 API and the 1.5.0 API; however, the ability to directly access
 members of the main libpng control structures, png_struct and png_info,
 deprecated in earlier versions of libpng, has been completely removed from
-libpng 1.5.
+libpng 1.5, and new private "pngstruct.h", "pnginfo.h", and "pngdebug.h"
+header files were created.
 
 We no longer include zlib.h in png.h.  The include statement has been moved
 to pngstruct.h, where it is not accessible by applications. Applications that
@@ -5304,7 +5393,7 @@ to png_bytepp, and in png_set_iCCP, from png_charp to png_const_bytep.
 There are changes of form in png.h, including new and changed macros to
 declare parts of the API.  Some API functions with arguments that are
 pointers to data not modified within the function have been corrected to
-declare these arguments with PNG_CONST.
+declare these arguments with const.
 
 Much of the internal use of C macros to control the library build has also
 changed and some of this is visible in the exported header files, in
@@ -5400,18 +5489,14 @@ PNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said
 that it could be used to override them.  Now this function will reduce or
 increase the limits.
 
-Starting in libpng-1.5.10, the user limits can be set en masse with the
-configuration option PNG_SAFE_LIMITS_SUPPORTED.  If this option is enabled,
-a set of "safe" limits is applied in pngpriv.h.  These can be overridden by
-application calls to png_set_user_limits(), png_set_user_chunk_cache_max(),
-and/or png_set_user_malloc_max() that increase or decrease the limits.  Also,
-in libpng-1.5.10 the default width and height limits were increased
-from 1,000,000 to 0x7fffffff (i.e., made unlimited).  Therefore, the
-limits are now
-                               default      safe
+Starting in libpng-1.5.22, default user limits were established. These
+can be overridden by application calls to png_set_user_limits(),
+png_set_user_chunk_cache_max(), and/or png_set_user_malloc_max().
+The limits are now
+                             max possible  default
    png_user_width_max        0x7fffffff    1,000,000
    png_user_height_max       0x7fffffff    1,000,000
-   png_user_chunk_cache_max  0 (unlimited)   128
+   png_user_chunk_cache_max  0 (unlimited) 1000
    png_user_chunk_malloc_max 0 (unlimited) 8,000,000
 
 The png_set_option() function (and the "options" member of the png struct) was
@@ -5503,7 +5588,7 @@ even though the default is to use the macros - this allows applications
 to choose at app buildtime whether or not to use macros (previously
 impossible because the functions weren't in the default build.)
 
-.SH XII.  Changes to Libpng from version 1.5.x to 1.6.x
+.SH XII. Changes to Libpng from version 1.5.x to 1.6.x
 
 A "simplified API" has been added (see documentation in png.h and a simple
 example in contrib/examples/pngtopng.c).  The new publicly visible API
@@ -5523,6 +5608,7 @@ includes the following:
      png_image_free()
    write functions
      png_image_write_to_file()
+     png_image_write_to_memory()
      png_image_write_to_stdio()
 
 Starting with libpng-1.6.0, you can configure libpng to prefix all exported
@@ -5660,7 +5746,12 @@ is an error. Previously this requirement of the PNG specification was not
 enforced, and the palette was always limited to 256 entries. An over-length
 PLTE chunk found in an input PNG is silently truncated.
 
-.SH XIII.  Detecting libpng
+Starting with libpng-1.6.31, the eXIf chunk is supported. Libpng does not
+attempt to decode the Exif profile; it simply returns a byte array
+containing the profile to the calling application which must do its own
+decoding.
+
+.SH XIII. Detecting libpng
 
 The png_get_io_ptr() function has been present since libpng-0.88, has never
 changed, and is unaffected by conditional compilation macros.  It is the
@@ -5676,27 +5767,32 @@ control.  The git repository was built from old libpng-x.y.z.tar.gz files
 going back to version 0.70.  You can access the git repository (read only)
 at
 
-    git://git.code.sf.net/p/libpng/code
+    https://github.com/glennrp/libpng or
+    https://git.code.sf.net/p/libpng/code.git
+
+or you can browse it with a web browser at
+
+    https://github.com/glennrp/libpng or
+    https://sourceforge.net/p/libpng/code/ci/libpng16/tree/
 
-or you can browse it with a web browser by selecting the "code" button at
+Patches can be sent to png-mng-implement at lists.sourceforge.net or
+uploaded to the libpng bug tracker at
 
-    https://sourceforge.net/projects/libpng
+    https://libpng.sourceforge.io/
 
-Patches can be sent to glennrp at users.sourceforge.net or to
-png-mng-implement at lists.sourceforge.net or you can upload them to
-the libpng bug tracker at
+or as a "pull request" to
 
-    http://libpng.sourceforge.net
+    https://github.com/glennrp/libpng/pulls
 
 We also accept patches built from the tar or zip distributions, and
-simple verbal discriptions of bug fixes, reported either to the
+simple verbal descriptions of bug fixes, reported either to the
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
-mailing list, or directly to glennrp.
+mailing list, as github issues.
 
 .SH XV. Coding style
 
 Our coding style is similar to the "Allman" style
-(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly
+(See https://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly
 braces on separate lines:
 
     if (condition)
@@ -5712,7 +5808,7 @@ braces on separate lines:
 The braces can be omitted from simple one-line actions:
 
     if (condition)
-       return (0);
+       return 0;
 
 We use 3-space indentation, except for continued statements which
 are usually indented the same as the first line of the statement
@@ -5797,7 +5893,7 @@ Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as
 though it were a function.
 
 Control keywords if, for, while, and switch are always followed by a space
-to distinguish them from function calls, which have no trailing space. 
+to distinguish them from function calls, which have no trailing space.
 
 We put a space after each comma and after each semicolon
 in "for" statements, and we put spaces before and after each
@@ -5821,8 +5917,9 @@ with an even number of lower-case hex digits, and to make them unsigned
 We prefer to use underscores rather than camelCase in names, except
 for a few type names that we inherit from zlib.h.
 
-We prefer "if (something != 0)" and "if (something == 0)"
-over "if (something)" and if "(!something)", respectively.
+We prefer "if (something != 0)" and "if (something == 0)" over
+"if (something)" and if "(!something)", respectively, and for pointers
+we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)".
 
 We do not use the TAB character for indentation in the C sources.
 
@@ -5830,61 +5927,6 @@ Lines do not exceed 80 characters.
 
 Other rules can be inferred by inspecting the libpng source.
 
-.SH XVI. Y2K Compliance in libpng
-
-Since the PNG Development group is an ad-hoc body, we can't make
-an official declaration.
-
-This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.21 are Y2K compliant.  It is my belief that earlier
-versions were also Y2K compliant.
-
-Libpng only has two year fields.  One is a 2-byte unsigned integer
-that will hold years up to 65535.  The other, which is deprecated,
-holds the date in text format, and will hold years up to 9999.
-
-The integer is
-    "png_uint_16 year" in png_time_struct.
-
-The string is
-    "char time_buffer[29]" in png_struct.  This is no longer used
-in libpng-1.6.x and will be removed from libpng-1.7.0.
-
-There are seven time-related functions:
-
-    png_convert_to_rfc_1123_buffer() in png.c
-      (formerly png_convert_to_rfc_1152() in error, and
-      also formerly png_convert_to_rfc_1123())
-    png_convert_from_struct_tm() in pngwrite.c, called
-      in pngwrite.c
-    png_convert_from_time_t() in pngwrite.c
-    png_get_tIME() in pngget.c
-    png_handle_tIME() in pngrutil.c, called in pngread.c
-    png_set_tIME() in pngset.c
-    png_write_tIME() in pngwutil.c, called in pngwrite.c
-
-All appear to handle dates properly in a Y2K environment.  The
-png_convert_from_time_t() function calls gmtime() to convert from system
-clock time, which returns (year - 1900), which we properly convert to
-the full 4-digit year.  There is a possibility that applications using
-libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or that they are incorrectly passing only a 2-digit year
-instead of "year - 1900" into the png_convert_from_struct_tm() function,
-but this is not under our control.  The libpng documentation has always
-stated that it works with 4-digit years, and the APIs have been
-documented as such.
-
-The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
-integer to hold the year, and can hold years as large as 65535.
-
-zlib, upon which libpng depends, is also Y2K compliant.  It contains
-no date-related code.
-
-
-   Glenn Randers-Pehrson
-   libpng maintainer
-   PNG Development Group
-
 .SH NOTE
 
 Note about libpng version numbers:
@@ -5895,9 +5937,9 @@ on the library has not always been consistent and straightforward.
 The following table summarizes matters since version 0.89c, which was
 the first widely used release:
 
- source             png.h  png.h  shared-lib
- version            string   int  version
- -------            ------  ----- ----------
+ source               png.h    png.h  shared-lib
+ version              string   int    version
+ -------              ------   -----  ----------
  0.89c "1.0 beta 3"     0.89      89  1.0.89
  0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
  0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
@@ -5932,30 +5974,32 @@ the first widely used release:
  1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
  1.0.7                    1    10007  (still compatible)
  ...
- 1.0.19                  10    10019  10.so.0.19[.0]
+ 1.0.69                  10    10069  10.so.0.69[.0]
+ ...
+ 1.2.59                  13    10259  12.so.0.59[.0]
  ...
- 1.2.53                  13    10253  12.so.0.53[.0]
+ 1.4.20                  14    10420  14.so.0.20[.0]
  ...
- 1.5.23                  15    10523  15.so.15.23[.0]
+ 1.5.30                  15    10530  15.so.15.30[.0]
  ...
- 1.6.21                  16    10621  16.so.16.21[.0]
-
-Henceforth the source version will match the shared-library minor
-and patch numbers; the shared-library major version number will be
-used for changes in backward compatibility, as it is intended.  The
-PNG_PNGLIB_VER macro, which is not used within libpng but is available
-for applications, is an unsigned integer of the form xyyzz corresponding
-to the source version x.y.z (leading zeros in y and z).  Beta versions
-were given the previous public release number plus a letter, until
-version 1.0.6j; from then on they were given the upcoming public
-release number plus "betaNN" or "rcNN".
+ 1.6.35                  16    10635  16.so.16.35[.0]
+
+Henceforth the source version will match the shared-library minor and
+patch numbers; the shared-library major version number will be used for
+changes in backward compatibility, as it is intended.
+The PNG_PNGLIB_VER macro, which is not used within libpng but is
+available for applications, is an unsigned integer of the form XYYZZ
+corresponding to the source version X.Y.Z (leading zeros in Y and Z).
+Beta versions were given the previous public release number plus a
+letter, until version 1.0.6j; from then on they were given the upcoming
+public release number plus "betaNN" or "rcNN".
 
 .SH "SEE ALSO"
 .IR libpngpf(3) ", " png(5)
 .LP
 .IR libpng :
 .IP
-http://libpng.sourceforge.net (follow the [DOWNLOAD] link)
+https://libpng.sourceforge.io/ (follow the [DOWNLOAD] link)
 http://www.libpng.org/pub/png
 
 .LP
@@ -5965,7 +6009,7 @@ http://www.libpng.org/pub/png
 .I libpng
 or at
 .br
-ftp://ftp.info-zip.org/pub/infozip/zlib
+https://zlib.net/
 
 .LP
 .IR PNG specification: RFC 2083
@@ -5974,19 +6018,20 @@ ftp://ftp.info-zip.org/pub/infozip/zlib
 .I libpng
 or at
 .br
-ftp://ftp.rfc-editor.org:/in-notes/rfc2083.txt
+https://www.ietf.org/rfc/rfc2083.txt
 .br
 or (as a W3C Recommendation) at
 .br
-http://www.w3.org/TR/REC-png.html
+https://www.w3.org/TR/REC-png.html
 
 .LP
 In the case of any inconsistency between the PNG specification
 and this library, the specification takes precedence.
 
 .SH AUTHORS
-This man page: Glenn Randers-Pehrson
-<glennrp at users.sourceforge.net>
+This man page:
+Initially created by Glenn Randers-Pehrson.
+Maintained by Cosmin Truta.
 
 The contributing authors would like to thank all those who helped
 with testing, bug fixes, and patience.  This wouldn't have been
@@ -5994,9 +6039,9 @@ possible without all of you.
 
 Thanks to Frank J. T. Wojcik for helping with the documentation.
 
-Libpng version 1.6.21 - January 15, 2016:
+Libpng:
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
-Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
+Maintained by Cosmin Truta.
 
 Supported by the PNG development group
 .br
@@ -6006,119 +6051,4 @@ png-mng-implement at lists.sourceforge.net (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
 to subscribe).
 
-.SH NOTICES:
-
-This copy of the libpng notices is provided for your convenience.  In case of
-any discrepancy between this copy and the notices in the file png.h that is
-included in the libpng distribution, the latter shall prevail.
-
-COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
-
-If you modify libpng you may insert additional notices immediately following
-this sentence.
-
-This code is released under the libpng license.
-
-libpng versions 1.0.7, July 1, 2000, through 1.6.21, January 15, 2016, are
-Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
-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
-added to the list of Contributing Authors:
-
-   Simon-Pierre Cadieux
-   Eric S. Raymond
-   Mans Rullgard
-   Cosmin Truta
-   Gilles Vollant
-   James Yu
-
-and with the following additions to the disclaimer:
-
-   There is no warranty against interference with your enjoyment of the
-   library or against infringement.  There is no warranty that our
-   efforts or the library will fulfill any of your particular purposes
-   or needs.  This library is provided with all faults, and the entire
-   risk of satisfactory quality, performance, accuracy, and effort is with
-   the user.
-
-libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
-Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
-libpng-0.96, and are distributed according to the same disclaimer and
-license as libpng-0.96, with the following individuals added to the list
-of Contributing Authors:
-
-   Tom Lane
-   Glenn Randers-Pehrson
-   Willem van Schaik
-
-libpng versions 0.89, June 1996, through 0.96, May 1997, are
-Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
-and are distributed according to the same disclaimer and license as
-libpng-0.88, with the following individuals added to the list of
-Contributing Authors:
-
-   John Bowler
-   Kevin Bracey
-   Sam Bushell
-   Magnus Holmgren
-   Greg Roelofs
-   Tom Tanner
-
-libpng versions 0.5, May 1995, through 0.88, January 1996, are
-Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
-
-For the purposes of this copyright and license, "Contributing Authors"
-is defined as the following set of individuals:
-
-   Andreas Dilger
-   Dave Martindale
-   Guy Eric Schalnat
-   Paul Schmidt
-   Tim Wegner
-
-The PNG Reference Library is supplied "AS IS".  The Contributing Authors
-and Group 42, Inc. disclaim all warranties, expressed or implied,
-including, without limitation, the warranties of merchantability and of
-fitness for any purpose.  The Contributing Authors and Group 42, Inc.
-assume no liability for direct, indirect, incidental, special, exemplary,
-or consequential damages, which may result from the use of the PNG
-Reference Library, even if advised of the possibility of such damage.
-
-Permission is hereby granted to use, copy, modify, and distribute this
-source code, or portions hereof, for any purpose, without fee, subject
-to the following restrictions:
-
-  1. The origin of this source code must not be misrepresented.
-
-  2. Altered versions must be plainly marked as such and must not
-     be misrepresented as being the original source.
-
-  3. This Copyright notice may not be removed or altered from any
-     source or altered source distribution.
-
-The Contributing Authors and Group 42, Inc. specifically permit, without
-fee, and encourage the use of this source code as a component to
-supporting the PNG file format in commercial products.  If you use this
-source code in a product, acknowledgment is not required but would be
-appreciated.
-
-END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
-
-A "png_get_copyright" function is available, for convenient use in "about"
-boxes and the like:
-
-   printf("%s", png_get_copyright(NULL));
-
-Also, the PNG logo (in PNG format, of course) is supplied in the
-files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
-
-Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is
-a certification mark of the Open Source Initiative. OSI has not addressed
-the additional disclaimers inserted at version 1.0.7.
-
-Glenn Randers-Pehrson
-glennrp at users.sourceforge.net
-January 15, 2016
-
 .\" end of man page
-
index 3e7e2c5..9708e9a 100644 (file)
@@ -6,6 +6,7 @@ includedir=@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
 Name: libpng
 Description: Loads and saves PNG files
 Version: @PNGLIB_VERSION@
+Requires: zlib
 Libs: -L${libdir} -lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
 Libs.private: @LIBS@
 Cflags: -I${includedir}
index a76a0c5..b736d82 100644 (file)
@@ -1,18 +1,24 @@
-.TH LIBPNGPF 3 "January 15, 2016"
+.TH LIBPNGPF 3 "December 1, 2018"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.21
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.36
 (private functions)
+
 .SH SYNOPSIS
 \fB#include \fI"pngpriv.h"
 
-\fBAs of libpng version \fP\fI1.5.1\fP\fB, this section is no longer \fP\fImaintained\fP\fB, now that the private function prototypes are hidden in pngpriv.h and not accessible to applications. Look in pngpriv.h for the prototypes and a short description of each \fIfunction.
+\fBAs of libpng version \fP\fI1.5.1\fP\fB, this section is no longer
+\fP\fImaintained\fP\fB, now that the private function prototypes are hidden in
+\fP\fIpngpriv.h\fP\fB and not accessible to applications. Look in
+\fP\fIpngpriv.h\fP\fB for the prototypes and a short description of each
+function.
 
 .SH DESCRIPTION
 The functions previously listed here are used privately by libpng and are not
 available for use by applications.  They are not "exported" to applications
 using shared libraries.
 
-.SH SEE ALSO
+.SH "SEE ALSO"
 .BR "png"(5), " libpng"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5)
-.SH AUTHOR
-Glenn Randers-Pehrson
+
+.SH AUTHORS
+Cosmin Truta, Glenn Randers-Pehrson
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/mips/filter_msa_intrinsics.c b/mips/filter_msa_intrinsics.c
new file mode 100644 (file)
index 0000000..a579179
--- /dev/null
@@ -0,0 +1,808 @@
+
+/* filter_msa_intrinsics.c - MSA optimised filter functions
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2016 Glenn Randers-Pehrson
+ * Written by Mandar Sahastrabuddhe, August 2016.
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* This code requires -mfpu=msa on the command line: */
+#if PNG_MIPS_MSA_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
+
+#include <msa.h>
+
+/* libpng row pointers are not necessarily aligned to any particular boundary,
+ * however this code will only work with appropriate alignment. mips/mips_init.c
+ * checks for this (and will not compile unless it is done). This code uses
+ * variants of png_aligncast to avoid compiler warnings.
+ */
+#define png_ptr(type,pointer) png_aligncast(type *,pointer)
+#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
+
+/* The following relies on a variable 'temp_pointer' being declared with type
+ * 'type'.  This is written this way just to hide the GCC strict aliasing
+ * warning; note that the code is safe because there never is an alias between
+ * the input and output pointers.
+ */
+#define png_ldr(type,pointer)\
+   (temp_pointer = png_ptr(type,pointer), *temp_pointer)
+
+#if PNG_MIPS_MSA_OPT > 0
+
+#ifdef CLANG_BUILD
+   #define MSA_SRLI_B(a, b)   __msa_srli_b((v16i8) a, b)
+
+   #define LW(psrc)                              \
+   ( {                                           \
+       uint8_t *psrc_lw_m = (uint8_t *) (psrc);  \
+       uint32_t val_m;                           \
+                                                 \
+       asm volatile (                            \
+           "lw  %[val_m],  %[psrc_lw_m]  \n\t"   \
+                                                 \
+           : [val_m] "=r" (val_m)                \
+           : [psrc_lw_m] "m" (*psrc_lw_m)        \
+       );                                        \
+                                                 \
+       val_m;                                    \
+   } )
+
+   #define SH(val, pdst)                         \
+   {                                             \
+       uint8_t *pdst_sh_m = (uint8_t *) (pdst);  \
+       uint16_t val_m = (val);                   \
+                                                 \
+       asm volatile (                            \
+           "sh  %[val_m],  %[pdst_sh_m]  \n\t"   \
+                                                 \
+           : [pdst_sh_m] "=m" (*pdst_sh_m)       \
+           : [val_m] "r" (val_m)                 \
+       );                                        \
+   }
+
+   #define SW(val, pdst)                         \
+   {                                             \
+       uint8_t *pdst_sw_m = (uint8_t *) (pdst);  \
+       uint32_t val_m = (val);                   \
+                                                 \
+       asm volatile (                            \
+           "sw  %[val_m],  %[pdst_sw_m]  \n\t"   \
+                                                 \
+           : [pdst_sw_m] "=m" (*pdst_sw_m)       \
+           : [val_m] "r" (val_m)                 \
+       );                                        \
+   }
+
+       #if (__mips == 64)
+        #define SD(val, pdst)                         \
+        {                                             \
+            uint8_t *pdst_sd_m = (uint8_t *) (pdst);  \
+            uint64_t val_m = (val);                   \
+                                                      \
+            asm volatile (                            \
+                "sd  %[val_m],  %[pdst_sd_m]  \n\t"   \
+                                                      \
+                : [pdst_sd_m] "=m" (*pdst_sd_m)       \
+                : [val_m] "r" (val_m)                 \
+            );                                        \
+        }
+    #else
+        #define SD(val, pdst)                                          \
+        {                                                              \
+            uint8_t *pdst_sd_m = (uint8_t *) (pdst);                   \
+            uint32_t val0_m, val1_m;                                   \
+                                                                       \
+            val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF);          \
+            val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF);  \
+                                                                       \
+            SW(val0_m, pdst_sd_m);                                     \
+            SW(val1_m, pdst_sd_m + 4);                                 \
+        }
+    #endif
+#else
+   #define MSA_SRLI_B(a, b)   (a >> b)
+
+#if (__mips_isa_rev >= 6)
+   #define LW(psrc)                              \
+   ( {                                           \
+       uint8_t *psrc_lw_m = (uint8_t *) (psrc);  \
+       uint32_t val_m;                           \
+                                                 \
+       asm volatile (                            \
+           "lw  %[val_m],  %[psrc_lw_m]  \n\t"   \
+                                                 \
+           : [val_m] "=r" (val_m)                \
+           : [psrc_lw_m] "m" (*psrc_lw_m)        \
+       );                                        \
+                                                 \
+       val_m;                                    \
+   } )
+
+   #define SH(val, pdst)                         \
+   {                                             \
+       uint8_t *pdst_sh_m = (uint8_t *) (pdst);  \
+       uint16_t val_m = (val);                   \
+                                                 \
+       asm volatile (                            \
+           "sh  %[val_m],  %[pdst_sh_m]  \n\t"   \
+                                                 \
+           : [pdst_sh_m] "=m" (*pdst_sh_m)       \
+           : [val_m] "r" (val_m)                 \
+       );                                        \
+   }
+
+   #define SW(val, pdst)                         \
+   {                                             \
+       uint8_t *pdst_sw_m = (uint8_t *) (pdst);  \
+       uint32_t val_m = (val);                   \
+                                                 \
+       asm volatile (                            \
+           "sw  %[val_m],  %[pdst_sw_m]  \n\t"   \
+                                                 \
+           : [pdst_sw_m] "=m" (*pdst_sw_m)       \
+           : [val_m] "r" (val_m)                 \
+       );                                        \
+   }
+
+   #if (__mips == 64)
+        #define SD(val, pdst)                         \
+        {                                             \
+            uint8_t *pdst_sd_m = (uint8_t *) (pdst);  \
+            uint64_t val_m = (val);                   \
+                                                      \
+            asm volatile (                            \
+                "sd  %[val_m],  %[pdst_sd_m]  \n\t"   \
+                                                      \
+                : [pdst_sd_m] "=m" (*pdst_sd_m)       \
+                : [val_m] "r" (val_m)                 \
+            );                                        \
+        }
+    #else
+        #define SD(val, pdst)                                          \
+        {                                                              \
+            uint8_t *pdst_sd_m = (uint8_t *) (pdst);                   \
+            uint32_t val0_m, val1_m;                                   \
+                                                                       \
+            val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF);          \
+            val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF);  \
+                                                                       \
+            SW(val0_m, pdst_sd_m);                                     \
+            SW(val1_m, pdst_sd_m + 4);                                 \
+        }
+    #endif
+#else  // !(__mips_isa_rev >= 6)
+   #define LW(psrc)                              \
+   ( {                                           \
+       uint8_t *psrc_lw_m = (uint8_t *) (psrc);  \
+       uint32_t val_m;                           \
+                                                 \
+       asm volatile (                            \
+           "ulw  %[val_m],  %[psrc_lw_m]  \n\t"  \
+                                                 \
+           : [val_m] "=r" (val_m)                \
+           : [psrc_lw_m] "m" (*psrc_lw_m)        \
+       );                                        \
+                                                 \
+       val_m;                                    \
+   } )
+
+   #define SH(val, pdst)                         \
+   {                                             \
+       uint8_t *pdst_sh_m = (uint8_t *) (pdst);  \
+       uint16_t val_m = (val);                   \
+                                                 \
+       asm volatile (                            \
+           "ush  %[val_m],  %[pdst_sh_m]  \n\t"  \
+                                                 \
+           : [pdst_sh_m] "=m" (*pdst_sh_m)       \
+           : [val_m] "r" (val_m)                 \
+       );                                        \
+   }
+
+   #define SW(val, pdst)                         \
+   {                                             \
+       uint8_t *pdst_sw_m = (uint8_t *) (pdst);  \
+       uint32_t val_m = (val);                   \
+                                                 \
+       asm volatile (                            \
+           "usw  %[val_m],  %[pdst_sw_m]  \n\t"  \
+                                                 \
+           : [pdst_sw_m] "=m" (*pdst_sw_m)       \
+           : [val_m] "r" (val_m)                 \
+       );                                        \
+   }
+
+   #define SD(val, pdst)                                          \
+    {                                                              \
+        uint8_t *pdst_sd_m = (uint8_t *) (pdst);                   \
+        uint32_t val0_m, val1_m;                                   \
+                                                                   \
+        val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF);          \
+        val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF);  \
+                                                                   \
+        SW(val0_m, pdst_sd_m);                                     \
+        SW(val1_m, pdst_sd_m + 4);                                 \
+    }
+
+    #define SW_ZERO(pdst)                      \
+    {                                          \
+        uint8_t *pdst_m = (uint8_t *) (pdst);  \
+                                               \
+        asm volatile (                         \
+            "usw  $0,  %[pdst_m]  \n\t"        \
+                                               \
+            : [pdst_m] "=m" (*pdst_m)          \
+            :                                  \
+        );                                     \
+    }
+#endif  // (__mips_isa_rev >= 6)
+#endif
+
+#define LD_B(RTYPE, psrc) *((RTYPE *) (psrc))
+#define LD_UB(...) LD_B(v16u8, __VA_ARGS__)
+#define LD_B2(RTYPE, psrc, stride, out0, out1)  \
+{                                               \
+    out0 = LD_B(RTYPE, (psrc));                 \
+    out1 = LD_B(RTYPE, (psrc) + stride);        \
+}
+#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__)
+#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3)   \
+{                                                            \
+    LD_B2(RTYPE, (psrc), stride, out0, out1);                \
+    LD_B2(RTYPE, (psrc) + 2 * stride , stride, out2, out3);  \
+}
+#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__)
+
+#define ST_B(RTYPE, in, pdst) *((RTYPE *) (pdst)) = (in)
+#define ST_UB(...) ST_B(v16u8, __VA_ARGS__)
+#define ST_B2(RTYPE, in0, in1, pdst, stride)  \
+{                                             \
+    ST_B(RTYPE, in0, (pdst));                 \
+    ST_B(RTYPE, in1, (pdst) + stride);        \
+}
+#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__)
+#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride)    \
+{                                                         \
+    ST_B2(RTYPE, in0, in1, (pdst), stride);               \
+    ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride);  \
+}
+#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__)
+
+#define ADD2(in0, in1, in2, in3, out0, out1)  \
+{                                             \
+    out0 = in0 + in1;                         \
+    out1 = in2 + in3;                         \
+}
+#define ADD3(in0, in1, in2, in3, in4, in5,  \
+             out0, out1, out2)              \
+{                                           \
+    ADD2(in0, in1, in2, in3, out0, out1);   \
+    out2 = in4 + in5;                       \
+}
+#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7,  \
+             out0, out1, out2, out3)                  \
+{                                                     \
+    ADD2(in0, in1, in2, in3, out0, out1);             \
+    ADD2(in4, in5, in6, in7, out2, out3);             \
+}
+
+#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1)      \
+{                                                           \
+    out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1);  \
+    out1 = (RTYPE) __msa_ilvr_b((v16i8) in2, (v16i8) in3);  \
+}
+#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__)
+
+#define HSUB_UB2(RTYPE, in0, in1, out0, out1)                 \
+{                                                             \
+    out0 = (RTYPE) __msa_hsub_u_h((v16u8) in0, (v16u8) in0);  \
+    out1 = (RTYPE) __msa_hsub_u_h((v16u8) in1, (v16u8) in1);  \
+}
+#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__)
+
+#define SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val)                 \
+{                                                                         \
+    v16i8 zero_m = { 0 };                                                 \
+    out0 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in0, slide_val);  \
+    out1 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in1, slide_val);  \
+}
+#define SLDI_B2_0_UB(...) SLDI_B2_0(v16u8, __VA_ARGS__)
+
+#define SLDI_B3_0(RTYPE, in0, in1, in2, out0, out1, out2,  slide_val)     \
+{                                                                         \
+    v16i8 zero_m = { 0 };                                                 \
+    SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val);                    \
+    out2 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in2, slide_val);  \
+}
+#define SLDI_B3_0_UB(...) SLDI_B3_0(v16u8, __VA_ARGS__)
+
+#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1)      \
+{                                                            \
+    out0 = (RTYPE) __msa_ilvev_w((v4i32) in1, (v4i32) in0);  \
+    out1 = (RTYPE) __msa_ilvev_w((v4i32) in3, (v4i32) in2);  \
+}
+#define ILVEV_W2_UB(...) ILVEV_W2(v16u8, __VA_ARGS__)
+
+#define ADD_ABS_H3(RTYPE, in0, in1, in2, out0, out1, out2)  \
+{                                                           \
+    RTYPE zero = {0};                                       \
+                                                            \
+    out0 = __msa_add_a_h((v8i16) zero, in0);                \
+    out1 = __msa_add_a_h((v8i16) zero, in1);                \
+    out2 = __msa_add_a_h((v8i16) zero, in2);                \
+}
+#define ADD_ABS_H3_SH(...) ADD_ABS_H3(v8i16, __VA_ARGS__)
+
+#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1)       \
+{                                                                          \
+    out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0);  \
+    out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2);  \
+}
+#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
+
+#define CMP_AND_SELECT(inp0, inp1, inp2, inp3, inp4, inp5, out0)              \
+{                                                                             \
+   v8i16 _sel_h0, _sel_h1;                                                    \
+   v16u8 _sel_b0, _sel_b1;                                                    \
+   _sel_h0 = (v8i16) __msa_clt_u_h((v8u16) inp1, (v8u16) inp0);               \
+   _sel_b0 = (v16u8) __msa_pckev_b((v16i8) _sel_h0, (v16i8) _sel_h0);         \
+   inp0 = (v8i16) __msa_bmnz_v((v16u8) inp0, (v16u8) inp1, (v16u8) _sel_h0);  \
+   inp4 = (v16u8) __msa_bmnz_v(inp3, inp4, _sel_b0);                          \
+   _sel_h1 = (v8i16) __msa_clt_u_h((v8u16) inp2, (v8u16) inp0);               \
+   _sel_b1 = (v16u8) __msa_pckev_b((v16i8) _sel_h1, (v16i8) _sel_h1);         \
+   inp4 = (v16u8) __msa_bmnz_v(inp4, inp5, _sel_b1);                          \
+   out0 += inp4;                                                              \
+}
+
+void png_read_filter_row_up_msa(png_row_infop row_info, png_bytep row,
+                                png_const_bytep prev_row)
+{
+   size_t i, cnt, cnt16, cnt32;
+   size_t istop = row_info->rowbytes;
+   png_bytep rp = row;
+   png_const_bytep pp = prev_row;
+   v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
+
+   for (i = 0; i < (istop >> 6); i++)
+   {
+      LD_UB4(rp, 16, src0, src1, src2, src3);
+      LD_UB4(pp, 16, src4, src5, src6, src7);
+      pp += 64;
+
+         ADD4(src0, src4, src1, src5, src2, src6, src3, src7,
+              src0, src1, src2, src3);
+
+      ST_UB4(src0, src1, src2, src3, rp, 16);
+      rp += 64;
+   }
+
+   if (istop & 0x3F)
+   {
+      cnt32 = istop & 0x20;
+      cnt16 = istop & 0x10;
+      cnt = istop & 0xF;
+
+      if(cnt32)
+      {
+         if (cnt16 && cnt)
+         {
+            LD_UB4(rp, 16, src0, src1, src2, src3);
+            LD_UB4(pp, 16, src4, src5, src6, src7);
+
+            ADD4(src0, src4, src1, src5, src2, src6, src3, src7,
+                    src0, src1, src2, src3);
+
+            ST_UB4(src0, src1, src2, src3, rp, 16);
+            rp += 64;
+         }
+         else if (cnt16 || cnt)
+         {
+            LD_UB2(rp, 16, src0, src1);
+            LD_UB2(pp, 16, src4, src5);
+            pp += 32;
+            src2 = LD_UB(rp + 32);
+            src6 = LD_UB(pp);
+
+            ADD3(src0, src4, src1, src5, src2, src6, src0, src1, src2);
+
+            ST_UB2(src0, src1, rp, 16);
+            rp += 32;
+            ST_UB(src2, rp);
+            rp += 16;
+         }
+         else
+         {
+            LD_UB2(rp, 16, src0, src1);
+            LD_UB2(pp, 16, src4, src5);
+
+                       ADD2(src0, src4, src1, src5, src0, src1);
+
+            ST_UB2(src0, src1, rp, 16);
+            rp += 32;
+         }
+      }
+      else if (cnt16 && cnt)
+      {
+         LD_UB2(rp, 16, src0, src1);
+         LD_UB2(pp, 16, src4, src5);
+
+         ADD2(src0, src4, src1, src5, src0, src1);
+
+         ST_UB2(src0, src1, rp, 16);
+         rp += 32;
+      }
+      else if (cnt16 || cnt)
+      {
+         src0 = LD_UB(rp);
+         src4 = LD_UB(pp);
+         pp += 16;
+
+         src0 += src4;
+
+         ST_UB(src0, rp);
+         rp += 16;
+      }
+   }
+}
+
+void png_read_filter_row_sub4_msa(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+   size_t count;
+   size_t istop = row_info->rowbytes;
+   png_bytep src = row;
+   png_bytep nxt = row + 4;
+   int32_t inp0;
+   v16u8 src0, src1, src2, src3, src4;
+   v16u8 dst0, dst1;
+   v16u8 zero = { 0 };
+
+   istop -= 4;
+
+   inp0 = LW(src);
+   src += 4;
+   src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+
+   for (count = 0; count < istop; count += 16)
+   {
+      src1 = LD_UB(src);
+      src += 16;
+
+      src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 4);
+      src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 8);
+      src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 12);
+      src1 += src0;
+      src2 += src1;
+      src3 += src2;
+      src4 += src3;
+      src0 = src4;
+      ILVEV_W2_UB(src1, src2, src3, src4, dst0, dst1);
+      dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
+
+      ST_UB(dst0, nxt);
+      nxt += 16;
+   }
+}
+
+void png_read_filter_row_sub3_msa(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+   size_t count;
+   size_t istop = row_info->rowbytes;
+   png_bytep src = row;
+   png_bytep nxt = row + 3;
+   int64_t out0;
+   int32_t inp0, out1;
+   v16u8 src0, src1, src2, src3, src4, dst0, dst1;
+   v16u8 zero = { 0 };
+   v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+   v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
+
+   istop -= 3;
+
+   inp0 = LW(src);
+   src += 3;
+   src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+
+   for (count = 0; count < istop; count += 12)
+   {
+      src1 = LD_UB(src);
+      src += 12;
+
+      src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 3);
+      src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 6);
+      src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 9);
+      src1 += src0;
+      src2 += src1;
+      src3 += src2;
+      src4 += src3;
+      src0 = src4;
+      VSHF_B2_UB(src1, src2, src3, src4, mask0, mask0, dst0, dst1);
+      dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
+      out0 = __msa_copy_s_d((v2i64) dst0, 0);
+      out1 = __msa_copy_s_w((v4i32) dst0, 2);
+
+      SD(out0, nxt);
+      nxt += 8;
+      SW(out1, nxt);
+      nxt += 4;
+   }
+}
+
+void png_read_filter_row_avg4_msa(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+   size_t i;
+   png_bytep src = row;
+   png_bytep nxt = row;
+   png_const_bytep pp = prev_row;
+   size_t istop = row_info->rowbytes - 4;
+   int32_t inp0, inp1, out0;
+   v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
+   v16u8 zero = { 0 };
+
+   inp0 = LW(pp);
+   pp += 4;
+   inp1 = LW(src);
+   src += 4;
+   src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+   src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+   src0 = (v16u8) MSA_SRLI_B(src0, 1);
+   src1 += src0;
+   out0 = __msa_copy_s_w((v4i32) src1, 0);
+   SW(out0, nxt);
+   nxt += 4;
+
+   for (i = 0; i < istop; i += 16)
+   {
+      src2 = LD_UB(pp);
+      pp += 16;
+      src6 = LD_UB(src);
+      src += 16;
+
+      SLDI_B2_0_UB(src2, src6, src3, src7, 4);
+      SLDI_B2_0_UB(src2, src6, src4, src8, 8);
+      SLDI_B2_0_UB(src2, src6, src5, src9, 12);
+      src2 = __msa_ave_u_b(src2, src1);
+      src6 += src2;
+      src3 = __msa_ave_u_b(src3, src6);
+      src7 += src3;
+      src4 = __msa_ave_u_b(src4, src7);
+      src8 += src4;
+      src5 = __msa_ave_u_b(src5, src8);
+      src9 += src5;
+      src1 = src9;
+      ILVEV_W2_UB(src6, src7, src8, src9, dst0, dst1);
+      dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
+
+      ST_UB(dst0, nxt);
+      nxt += 16;
+   }
+}
+
+void png_read_filter_row_avg3_msa(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+   size_t i;
+   png_bytep src = row;
+   png_bytep nxt = row;
+   png_const_bytep pp = prev_row;
+   size_t istop = row_info->rowbytes - 3;
+   int64_t out0;
+   int32_t inp0, inp1, out1;
+   int16_t out2;
+   v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
+   v16u8 zero = { 0 };
+   v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+   v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
+
+   inp0 = LW(pp);
+   pp += 3;
+   inp1 = LW(src);
+   src += 3;
+   src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+   src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+   src0 = (v16u8) MSA_SRLI_B(src0, 1);
+   src1 += src0;
+   out2 = __msa_copy_s_h((v8i16) src1, 0);
+   SH(out2, nxt);
+   nxt += 2;
+   nxt[0] = src1[2];
+   nxt++;
+
+   for (i = 0; i < istop; i += 12)
+   {
+      src2 = LD_UB(pp);
+      pp += 12;
+      src6 = LD_UB(src);
+      src += 12;
+
+      SLDI_B2_0_UB(src2, src6, src3, src7, 3);
+      SLDI_B2_0_UB(src2, src6, src4, src8, 6);
+      SLDI_B2_0_UB(src2, src6, src5, src9, 9);
+      src2 = __msa_ave_u_b(src2, src1);
+      src6 += src2;
+      src3 = __msa_ave_u_b(src3, src6);
+      src7 += src3;
+      src4 = __msa_ave_u_b(src4, src7);
+      src8 += src4;
+      src5 = __msa_ave_u_b(src5, src8);
+      src9 += src5;
+      src1 = src9;
+      VSHF_B2_UB(src6, src7, src8, src9, mask0, mask0, dst0, dst1);
+      dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
+      out0 = __msa_copy_s_d((v2i64) dst0, 0);
+      out1 = __msa_copy_s_w((v4i32) dst0, 2);
+
+      SD(out0, nxt);
+      nxt += 8;
+      SW(out1, nxt);
+      nxt += 4;
+   }
+}
+
+void png_read_filter_row_paeth4_msa(png_row_infop row_info,
+                                    png_bytep row,
+                                    png_const_bytep prev_row)
+{
+   int32_t count, rp_end;
+   png_bytep nxt;
+   png_const_bytep prev_nxt;
+   int32_t inp0, inp1, res0;
+   v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9;
+   v16u8 src10, src11, src12, src13, dst0, dst1;
+   v8i16 vec0, vec1, vec2;
+   v16u8 zero = { 0 };
+
+   nxt = row;
+   prev_nxt = prev_row;
+
+   inp0 = LW(nxt);
+   inp1 = LW(prev_nxt);
+   prev_nxt += 4;
+   src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+   src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+
+   src1 += src0;
+   res0 = __msa_copy_s_w((v4i32) src1, 0);
+
+   SW(res0, nxt);
+   nxt += 4;
+
+   /* Remainder */
+   rp_end = row_info->rowbytes - 4;
+
+   for (count = 0; count < rp_end; count += 16)
+   {
+      src2 = LD_UB(prev_nxt);
+      prev_nxt += 16;
+      src6 = LD_UB(prev_row);
+      prev_row += 16;
+      src10 = LD_UB(nxt);
+
+      SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 4);
+      SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 8);
+      SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 12);
+      ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10);
+      ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11);
+      ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12);
+      ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13);
+      src1 = src13;
+      ILVEV_W2_UB(src10, src11, src12, src1, dst0, dst1);
+      dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
+
+      ST_UB(dst0, nxt);
+      nxt += 16;
+   }
+}
+
+void png_read_filter_row_paeth3_msa(png_row_infop row_info,
+                                    png_bytep row,
+                                    png_const_bytep prev_row)
+{
+   int32_t count, rp_end;
+   png_bytep nxt;
+   png_const_bytep prev_nxt;
+   int64_t out0;
+   int32_t inp0, inp1, out1;
+   int16_t out2;
+   v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
+   v16u8 src10, src11, src12, src13;
+   v8i16 vec0, vec1, vec2;
+   v16u8 zero = { 0 };
+   v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+   v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
+
+   nxt = row;
+   prev_nxt = prev_row;
+
+   inp0 = LW(nxt);
+   inp1 = LW(prev_nxt);
+   prev_nxt += 3;
+   src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+   src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+
+   src1 += src0;
+   out2 = __msa_copy_s_h((v8i16) src1, 0);
+
+   SH(out2, nxt);
+   nxt += 2;
+   nxt[0] = src1[2];
+   nxt++;
+
+   /* Remainder */
+   rp_end = row_info->rowbytes - 3;
+
+   for (count = 0; count < rp_end; count += 12)
+   {
+      src2 = LD_UB(prev_nxt);
+      prev_nxt += 12;
+      src6 = LD_UB(prev_row);
+      prev_row += 12;
+      src10 = LD_UB(nxt);
+
+      SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 3);
+      SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 6);
+      SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 9);
+      ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10);
+      ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11);
+      ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12);
+      ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1);
+      HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+      vec2 = vec0 + vec1;
+      ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+      CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13);
+      src1 = src13;
+      VSHF_B2_UB(src10, src11, src12, src13, mask0, mask0, dst0, dst1);
+      dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
+      out0 = __msa_copy_s_d((v2i64) dst0, 0);
+      out1 = __msa_copy_s_w((v4i32) dst0, 2);
+
+      SD(out0, nxt);
+      nxt += 8;
+      SW(out1, nxt);
+      nxt += 4;
+   }
+}
+
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+#endif /* PNG_MIPS_MSA_IMPLEMENTATION == 1 (intrinsics) */
+#endif /* READ */
diff --git a/mips/mips_init.c b/mips/mips_init.c
new file mode 100644 (file)
index 0000000..8dd283d
--- /dev/null
@@ -0,0 +1,130 @@
+
+/* mips_init.c - MSA optimised filter functions
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2016 Glenn Randers-Pehrson
+ * Written by Mandar Sahastrabuddhe, 2016.
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
+ * called.
+ */
+#define _POSIX_SOURCE 1
+
+#include <stdio.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+#if PNG_MIPS_MSA_OPT > 0
+#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED /* Do run-time checks */
+/* WARNING: it is strongly recommended that you do not build libpng with
+ * run-time checks for CPU features if at all possible.  In the case of the MIPS
+ * MSA instructions there is no processor-specific way of detecting the
+ * presence of the required support, therefore run-time detection is extremely
+ * OS specific.
+ *
+ * You may set the macro PNG_MIPS_MSA_FILE to the file name of file containing
+ * a fragment of C source code which defines the png_have_msa function.  There
+ * are a number of implementations in contrib/mips-msa, but the only one that
+ * has partial support is contrib/mips-msa/linux.c - a generic Linux
+ * implementation which reads /proc/cpufino.
+ */
+#ifndef PNG_MIPS_MSA_FILE
+#  ifdef __linux__
+#     define PNG_MIPS_MSA_FILE "contrib/mips-msa/linux.c"
+#  endif
+#endif
+
+#ifdef PNG_MIPS_MSA_FILE
+
+#include <signal.h> /* for sig_atomic_t */
+static int png_have_msa(png_structp png_ptr);
+#include PNG_MIPS_MSA_FILE
+
+#else  /* PNG_MIPS_MSA_FILE */
+#  error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks"
+#endif /* PNG_MIPS_MSA_FILE */
+#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
+
+#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
+#  error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
+#endif
+
+void
+png_init_filter_functions_msa(png_structp pp, unsigned int bpp)
+{
+   /* The switch statement is compiled in for MIPS_MSA_API, the call to
+    * png_have_msa is compiled in for MIPS_MSA_CHECK. If both are defined
+    * the check is only performed if the API has not set the MSA option on
+    * or off explicitly. In this case the check controls what happens.
+    */
+
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+   switch ((pp->options >> PNG_MIPS_MSA) & 3)
+   {
+      case PNG_OPTION_UNSET:
+         /* Allow the run-time check to execute if it has been enabled -
+          * thus both API and CHECK can be turned on.  If it isn't supported
+          * this case will fall through to the 'default' below, which just
+          * returns.
+          */
+#endif /* PNG_MIPS_MSA_API_SUPPORTED */
+#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
+         {
+            static volatile sig_atomic_t no_msa = -1; /* not checked */
+
+            if (no_msa < 0)
+               no_msa = !png_have_msa(pp);
+
+            if (no_msa)
+               return;
+         }
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+         break;
+#endif
+#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
+
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+      default: /* OFF or INVALID */
+         return;
+
+      case PNG_OPTION_ON:
+         /* Option turned on */
+         break;
+   }
+#endif
+
+   /* IMPORTANT: any new external functions used here must be declared using
+    * PNG_INTERNAL_FUNCTION in ../pngpriv.h.  This is required so that the
+    * 'prefix' option to configure works:
+    *
+    *    ./configure --with-libpng-prefix=foobar_
+    *
+    * Verify you have got this right by running the above command, doing a build
+    * and examining pngprefix.h; it must contain a #define for every external
+    * function you add.  (Notice that this happens automatically for the
+    * initialization function.)
+    */
+   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_msa;
+
+   if (bpp == 3)
+   {
+      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_msa;
+      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_msa;
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_msa;
+   }
+
+   else if (bpp == 4)
+   {
+      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_msa;
+      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_msa;
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_msa;
+   }
+}
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+#endif /* READ */
diff --git a/missing b/missing
index f62bbae..625aeb1 100755 (executable)
--- a/missing
+++ b/missing
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2013-10-28.13; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC
 # GNU General Public License for more details.
 
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -101,9 +101,9 @@ else
   exit $st
 fi
 
-perl_URL=http://www.perl.org/
-flex_URL=http://flex.sourceforge.net/
-gnu_software_URL=http://www.gnu.org/software
+perl_URL=https://www.perl.org/
+flex_URL=https://github.com/westes/flex
+gnu_software_URL=https://www.gnu.org/software
 
 program_details ()
 {
@@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
 exit $st
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
diff --git a/png.5 b/png.5
index 5a44ea6..2077d1f 100644 (file)
--- a/png.5
+++ b/png.5
@@ -1,47 +1,49 @@
-.TH PNG 5 "January 15, 2016"
+.TH PNG 5 "December 1, 2018"
 .SH NAME
 png \- Portable Network Graphics (PNG) format
+
 .SH DESCRIPTION
 PNG (Portable Network Graphics) is an extensible file format for the
-lossless, portable, well-compressed storage of raster images. PNG provides
-a patent-free replacement for GIF and can also replace many
+lossless, portable, well-compressed storage of raster images.  PNG
+provides a patent-free replacement for GIF, and can also replace many
 common uses of TIFF. Indexed-color, grayscale, and truecolor images are
-supported, plus an optional alpha channel. Sample depths range from
+supported, plus an optional alpha channel.  Sample depths range from
 1 to 16 bits.
 .br
-
-PNG is designed to work well in online viewing applications, such as the
-World Wide Web, so it is fully streamable with a progressive display
-option. PNG is robust, providing both full file integrity checking and
-fast, simple detection of common transmission errors. Also, PNG can store
-gamma and chromaticity data for improved color matching on heterogeneous
-platforms.
+PNG is designed to work well in online viewing applications, such
+as the World Wide Web, so it is fully streamable with a progressive
+display option.  PNG is robust, providing both full file integrity
+checking and fast, simple detection of common transmission errors.
+Also, PNG can store gamma and chromaticity data for improved color
+matching on heterogeneous platforms.
 
 .SH "SEE ALSO"
 .BR "libpng"(3), " libpngpf"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5)
 .LP
-PNG specification (second edition), November 2003:
+PNG Specification (Second Edition), November 2003:
 .IP
 .br
-  <http://www.w3.org/TR/2003/REC-PNG-20031110/
-PNG 1.2 specification, July 1999:
+https://www.w3.org/TR/2003/REC-PNG-20031110/
+.LP
+PNG 1.2 Specification, July 1999:
 .IP
 .br
-http://png-mng.sourceforge.net/pub/png/spec/1.2/
+https://png-mng.sourceforge.io/pub/png/spec/1.2/
 .LP
-PNG 1.0 specification, October 1996:
+PNG 1.0 Specification, October 1996:
 .IP
 .br
 RFC 2083
-.IP
 .br
-ftp://ds.internic.net/rfc/rfc2083.txt
+https://www.ietf.org/rfc/rfc2083.txt
+.IP
 .br
-or (as a W3C Recommendation) at
+or W3C Recommendation
 .br
-http://www.w3.org/TR/REC-png-961001
+https://www.w3.org/TR/REC-png-961001
+
 .SH AUTHORS
-This man page: Glenn Randers-Pehrson
+This man page: Cosmin Truta, Glenn Randers-Pehrson
 .LP
 Portable Network Graphics (PNG) Specification (Second Edition)
 Information technology - Computer graphics and image processing -
@@ -53,22 +55,30 @@ Glenn Randers-Pehrson and others (png-list).
 .LP
 Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
 Thomas Boutell and others (png-list).
-.LP
-
 
-.SH COPYRIGHT NOTICE
+.SH COPYRIGHT
 .LP
-This man page is Copyright (c) 1998-2006 Glenn Randers-Pehrson.  See png.h
-for conditions of use and distribution.
+This man page is
+.br
+Copyright (c) 2018 Cosmin Truta.
+.br
+Copyright (c) 1998-2006 Glenn Randers-Pehrson.
+.br
+See png.h for conditions of use and distribution.
 .LP
 The PNG Specification (Second Edition) is
+.br
 Copyright (c) 2003 W3C. (MIT, ERCIM, Keio), All Rights Reserved.
 .LP
-The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson.
+The PNG-1.2 Specification is
+.br
+Copyright (c) 1999 Glenn Randers-Pehrson.
+.br
 See the specification for conditions of use and distribution.
 .LP
-The PNG-1.0 specification is copyright (c) 1996 Massachusetts Institute of
-Technology.  See the specification for conditions of use and distribution.
-.LP
+The PNG-1.0 Specification is
+.br
+Copyright (c) 1996 Massachusetts Institute of Technology.
+.br
+See the specification for conditions of use and distribution.
 .\" end of man page
-
diff --git a/png.c b/png.c
index 1d1bde5..3dce191 100644 (file)
--- a/png.c
+++ b/png.c
@@ -1,10 +1,10 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_21 Your_png_h_is_not_version_1_6_21;
+typedef png_libpng_version_1_6_36 Your_png_h_is_not_version_1_6_36;
+
+#ifdef __GNUC__
+/* The version tests may need to be added to, but the problem warning has
+ * consistently been fixed in GCC versions which obtain wide-spread release.
+ * The problem is that many versions of GCC rearrange comparison expressions in
+ * the optimizer in such a way that the results of the comparison will change
+ * if signed integer overflow occurs.  Such comparisons are not permitted in
+ * ANSI C90, however GCC isn't clever enough to work out that that do not occur
+ * below in png_ascii_from_fp and png_muldiv, so it produces a warning with
+ * -Wextra.  Unfortunately this is highly dependent on the optimizer and the
+ * machine architecture so the warning comes and goes unpredictably and is
+ * impossible to "fix", even were that a good idea.
+ */
+#if __GNUC__ == 7 && __GNUC_MINOR__ == 1
+#define GCC_STRICT_OVERFLOW 1
+#endif /* GNU 7.1.x */
+#endif /* GNU */
+#ifndef GCC_STRICT_OVERFLOW
+#define GCC_STRICT_OVERFLOW 0
+#endif
 
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
@@ -51,7 +71,7 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
  * PNG signature (this is the same behavior as strcmp, memcmp, etc).
  */
 int PNGAPI
-png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
+png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check)
 {
    png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
 
@@ -85,7 +105,7 @@ png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
    if (items >= (~(png_alloc_size_t)0)/size)
    {
       png_warning (png_voidcast(png_structrp, png_ptr),
-         "Potential overflow in png_zalloc()");
+          "Potential overflow in png_zalloc()");
       return NULL;
    }
 
@@ -116,7 +136,7 @@ png_reset_crc(png_structrp png_ptr)
  * trouble of calculating it.
  */
 void /* PRIVATE */
-png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
+png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length)
 {
    int need_crc = 1;
 
@@ -172,10 +192,10 @@ png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
 int
 png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
 {
-     /* Libpng versions 1.0.0 and later are binary compatible if the version
-      * string matches through the second '.'; we must recompile any
-      * applications that use any older library version.
-      */
+   /* Libpng versions 1.0.0 and later are binary compatible if the version
+    * string matches through the second '.'; we must recompile any
+    * applications that use any older library version.
+    */
 
    if (user_png_ver != NULL)
    {
@@ -297,7 +317,7 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
          if (png_user_version_check(&create_struct, user_png_ver) != 0)
          {
             png_structrp png_ptr = png_voidcast(png_structrp,
-               png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+                png_malloc_warn(&create_struct, (sizeof *png_ptr)));
 
             if (png_ptr != NULL)
             {
@@ -346,7 +366,7 @@ png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
     * has always been done in 'example.c'.
     */
    info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
-      (sizeof *info_ptr)));
+       (sizeof *info_ptr)));
 
    if (info_ptr != NULL)
       memset(info_ptr, 0, (sizeof *info_ptr));
@@ -401,8 +421,8 @@ png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
  * those cases where it does anything other than a memset.
  */
 PNG_FUNCTION(void,PNGAPI
-png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
-   PNG_DEPRECATED)
+png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
+    PNG_DEPRECATED)
 {
    png_inforp info_ptr = *ptr_ptr;
 
@@ -417,7 +437,7 @@ png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
       /* The following line is why this API should not be used: */
       free(info_ptr);
       info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
-         (sizeof *info_ptr)));
+          (sizeof *info_ptr)));
       if (info_ptr == NULL)
          return;
       *ptr_ptr = info_ptr;
@@ -430,7 +450,7 @@ png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
 /* The following API is not called internally */
 void PNGAPI
 png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
-   int freer, png_uint_32 mask)
+    int freer, png_uint_32 mask)
 {
    png_debug(1, "in png_data_freer");
 
@@ -449,7 +469,7 @@ png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
 
 void PNGAPI
 png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
-   int num)
+    int num)
 {
    png_debug(1, "in png_free_data");
 
@@ -458,7 +478,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
 
 #ifdef PNG_TEXT_SUPPORTED
    /* Free text item num or (if num == -1) all text items */
-   if (info_ptr->text != 0 &&
+   if (info_ptr->text != NULL &&
        ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -477,6 +497,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
          png_free(png_ptr, info_ptr->text);
          info_ptr->text = NULL;
          info_ptr->num_text = 0;
+         info_ptr->max_text = 0;
       }
    }
 #endif
@@ -541,7 +562,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
 
 #ifdef PNG_sPLT_SUPPORTED
    /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
-   if (info_ptr->splt_palettes != 0 &&
+   if (info_ptr->splt_palettes != NULL &&
        ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -571,7 +592,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
 #endif
 
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-   if (info_ptr->unknown_chunks != 0 &&
+   if (info_ptr->unknown_chunks != NULL &&
        ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
    {
       if (num != -1)
@@ -594,6 +615,26 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
    }
 #endif
 
+#ifdef PNG_eXIf_SUPPORTED
+   /* Free any eXIf entry */
+   if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0)
+   {
+# ifdef PNG_READ_eXIf_SUPPORTED
+      if (info_ptr->eXIf_buf)
+      {
+         png_free(png_ptr, info_ptr->eXIf_buf);
+         info_ptr->eXIf_buf = NULL;
+      }
+# endif
+      if (info_ptr->exif)
+      {
+         png_free(png_ptr, info_ptr->exif);
+         info_ptr->exif = NULL;
+      }
+      info_ptr->valid &= ~PNG_INFO_eXIf;
+   }
+#endif
+
 #ifdef PNG_hIST_SUPPORTED
    /* Free any hIST entry */
    if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
@@ -617,7 +658,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
    /* Free any image bits attached to the info structure */
    if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
    {
-      if (info_ptr->row_pointers != 0)
+      if (info_ptr->row_pointers != NULL)
       {
          png_uint_32 row;
          for (row = 0; row < info_ptr->height; row++)
@@ -684,7 +725,7 @@ png_init_io(png_structrp png_ptr, png_FILE_p fp)
 void PNGAPI
 png_save_int_32(png_bytep buf, png_int_32 i)
 {
-   png_save_uint_32(buf, i);
+   png_save_uint_32(buf, (png_uint_32)i);
 }
 #  endif
 
@@ -695,7 +736,7 @@ png_save_int_32(png_bytep buf, png_int_32 i)
 int PNGAPI
 png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
 {
-   static PNG_CONST char short_months[12][4] =
+   static const char short_months[12][4] =
         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
 
@@ -773,20 +814,14 @@ png_get_copyright(png_const_structrp png_ptr)
 #ifdef PNG_STRING_COPYRIGHT
    return PNG_STRING_COPYRIGHT
 #else
-#  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-      "libpng version 1.6.21 - January 15, 2016" PNG_STRING_NEWLINE \
-      "Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson" \
+      "libpng version 1.6.36" PNG_STRING_NEWLINE \
+      "Copyright (c) 2018 Cosmin Truta" PNG_STRING_NEWLINE \
+      "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
       PNG_STRING_NEWLINE \
       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
       "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
       PNG_STRING_NEWLINE;
-#  else
-   return "libpng version 1.6.21 - January 15, 2016\
-      Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\
-      Copyright (c) 1996-1997 Andreas Dilger\
-      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
-#  endif
 #endif
 }
 
@@ -901,7 +936,7 @@ png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
 
    /* The code is the fifth byte after each four byte string.  Historically this
     * code was always searched from the end of the list, this is no longer
-    * necessary because the 'set' routine handles duplicate entries correcty.
+    * necessary because the 'set' routine handles duplicate entries correctly.
     */
    do /* num_chunk_list > 0, so at least one */
    {
@@ -1033,7 +1068,7 @@ png_zstream_error(png_structrp png_ptr, int ret)
 #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
 static int
 png_colorspace_check_gamma(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+    png_colorspacerp colorspace, png_fixed_point gAMA, int from)
    /* This is called to check a new gamma value against an existing one.  The
     * routine returns false if the new gamma value should not be written.
     *
@@ -1047,7 +1082,7 @@ png_colorspace_check_gamma(png_const_structrp png_ptr,
    png_fixed_point gtest;
 
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-      (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
+       (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
       png_gamma_significant(gtest) != 0))
    {
       /* Either this is an sRGB image, in which case the calculated gamma
@@ -1059,7 +1094,7 @@ png_colorspace_check_gamma(png_const_structrp png_ptr,
       if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
       {
          png_chunk_report(png_ptr, "gamma value does not match sRGB",
-            PNG_CHUNK_ERROR);
+             PNG_CHUNK_ERROR);
          /* Do not overwrite an sRGB value */
          return from == 2;
       }
@@ -1067,7 +1102,7 @@ png_colorspace_check_gamma(png_const_structrp png_ptr,
       else /* sRGB tag not involved */
       {
          png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
-            PNG_CHUNK_WARNING);
+             PNG_CHUNK_WARNING);
          return from == 1;
       }
    }
@@ -1077,10 +1112,10 @@ png_colorspace_check_gamma(png_const_structrp png_ptr,
 
 void /* PRIVATE */
 png_colorspace_set_gamma(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_fixed_point gAMA)
+    png_colorspacerp colorspace, png_fixed_point gAMA)
 {
    /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
-    * occur.  Since the fixed point representation is asymetrical it is
+    * occur.  Since the fixed point representation is asymmetrical it is
     * possible for 1/gamma to overflow the limit of 21474 and this means the
     * gamma value must be at least 5/100000 and hence at most 20000.0.  For
     * safety the limits here are a little narrower.  The values are 0.00016 to
@@ -1635,8 +1670,8 @@ static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
 
 static int
 png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
-   int preferred)
+    png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+    int preferred)
 {
    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
       return 0;
@@ -1683,7 +1718,7 @@ png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
 
 int /* PRIVATE */
 png_colorspace_set_chromaticities(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_xy *xy, int preferred)
+    png_colorspacerp colorspace, const png_xy *xy, int preferred)
 {
    /* We must check the end points to ensure they are reasonable - in the past
     * color management systems have crashed as a result of getting bogus
@@ -1697,7 +1732,7 @@ png_colorspace_set_chromaticities(png_const_structrp png_ptr,
    {
       case 0: /* success */
          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
-            preferred);
+             preferred);
 
       case 1:
          /* We can't invert the chromaticities so we can't produce value XYZ
@@ -1720,7 +1755,7 @@ png_colorspace_set_chromaticities(png_const_structrp png_ptr,
 
 int /* PRIVATE */
 png_colorspace_set_endpoints(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+    png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
 {
    png_XYZ XYZ = *XYZ_in;
    png_xy xy;
@@ -1729,7 +1764,7 @@ png_colorspace_set_endpoints(png_const_structrp png_ptr,
    {
       case 0:
          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
-            preferred);
+             preferred);
 
       case 1:
          /* End points are invalid. */
@@ -1786,7 +1821,7 @@ is_ICC_signature(png_alloc_size_t it)
 
 static int
 png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+    png_const_charp name, png_alloc_size_t value, png_const_charp reason)
 {
    size_t pos;
    char message[196]; /* see below for calculation */
@@ -1811,8 +1846,8 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
          char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
 
          pos = png_safecat(message, (sizeof message), pos,
-            png_format_number(number, number+(sizeof number),
-               PNG_NUMBER_FORMAT_x, value));
+             png_format_number(number, number+(sizeof number),
+             PNG_NUMBER_FORMAT_x, value));
          pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
       }
 #  endif
@@ -1826,7 +1861,7 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
     * application errors the PNG won't be written.)
     */
    png_chunk_report(png_ptr, message,
-      (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+       (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
 
    return 0;
 }
@@ -1835,7 +1870,7 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
 #ifdef PNG_sRGB_SUPPORTED
 int /* PRIVATE */
 png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   int intent)
+    int intent)
 {
    /* sRGB sets known gamma, end points and (from the chunk) intent. */
    /* IMPORTANT: these are not necessarily the values found in an ICC profile
@@ -1872,12 +1907,12 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
     */
    if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
-         (unsigned)intent, "invalid sRGB rendering intent");
+          (png_alloc_size_t)intent, "invalid sRGB rendering intent");
 
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
-      colorspace->rendering_intent != intent)
+       colorspace->rendering_intent != intent)
       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
-         (unsigned)intent, "inconsistent rendering intents");
+         (png_alloc_size_t)intent, "inconsistent rendering intents");
 
    if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
    {
@@ -1889,8 +1924,8 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
     * warn but overwrite the value with the correct one.
     */
    if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
-      !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
-         100))
+       !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+       100))
       png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
          PNG_CHUNK_ERROR);
 
@@ -1898,7 +1933,7 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
     * returns true when the 'from' argument corresponds to sRGB (2).
     */
    (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
-      2/*from sRGB*/);
+       2/*from sRGB*/);
 
    /* intent: bugs in GCC force 'int' to be used as the parameter type. */
    colorspace->rendering_intent = (png_uint_16)intent;
@@ -1931,21 +1966,54 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
 static const png_byte D50_nCIEXYZ[12] =
    { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
 
-int /* PRIVATE */
-png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length)
+static int /* bool */
+icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    png_const_charp name, png_uint_32 profile_length)
 {
    if (profile_length < 132)
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-         "too short");
+          "too short");
+   return 1;
+}
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+int /* PRIVATE */
+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    png_const_charp name, png_uint_32 profile_length)
+{
+   if (!icc_check_length(png_ptr, colorspace, name, profile_length))
+      return 0;
+
+   /* This needs to be here because the 'normal' check is in
+    * png_decompress_chunk, yet this happens after the attempt to
+    * png_malloc_base the required data.  We only need this on read; on write
+    * the caller supplies the profile buffer so libpng doesn't allocate it.  See
+    * the call to icc_check_length below (the write case).
+    */
+#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
+      else if (png_ptr->user_chunk_malloc_max > 0 &&
+               png_ptr->user_chunk_malloc_max < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds application limits");
+#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
+      else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds libpng limits");
+#  else /* !SET_USER_LIMITS */
+      /* This will get compiled out on all 32-bit and better systems. */
+      else if (PNG_SIZE_MAX < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds system limits");
+#  endif /* !SET_USER_LIMITS */
 
    return 1;
 }
+#endif /* READ_iCCP */
 
 int /* PRIVATE */
 png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length,
-   png_const_bytep profile/* first 132 bytes only */, int color_type)
+    png_const_charp name, png_uint_32 profile_length,
+    png_const_bytep profile/* first 132 bytes only */, int color_type)
 {
    png_uint_32 temp;
 
@@ -1957,18 +2025,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
    temp = png_get_uint_32(profile);
    if (temp != profile_length)
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "length does not match profile");
+          "length does not match profile");
 
    temp = (png_uint_32) (*(profile+8));
    if (temp > 3 && (profile_length & 3))
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
-         "invalid length");
+          "invalid length");
 
    temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
    if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
       profile_length < 132+12*temp) /* truncated tag table */
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "tag count too large");
+          "tag count too large");
 
    /* The 'intent' must be valid or we can't store it, ICC limits the intent to
     * 16 bits.
@@ -1976,14 +2044,14 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
    temp = png_get_uint_32(profile+64);
    if (temp >= 0xffff) /* The ICC limit */
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "invalid rendering intent");
+          "invalid rendering intent");
 
    /* This is just a warning because the profile may be valid in future
     * versions.
     */
    if (temp >= PNG_sRGB_INTENT_LAST)
       (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-         "intent outside defined range");
+          "intent outside defined range");
 
    /* At this point the tag table can't be checked because it hasn't necessarily
     * been loaded; however, various header fields can be checked.  These checks
@@ -1993,14 +2061,14 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
     */
 
    /* Data checks (could be skipped).  These checks must be independent of the
-    * version number; however, the version number doesn't accomodate changes in
+    * version number; however, the version number doesn't accommodate changes in
     * the header fields (just the known tags and the interpretation of the
     * data.)
     */
    temp = png_get_uint_32(profile+36); /* signature 'ascp' */
    if (temp != 0x61637370)
       return png_icc_profile_error(png_ptr, colorspace, name, temp,
-         "invalid signature");
+          "invalid signature");
 
    /* Currently the PCS illuminant/adopted white point (the computational
     * white point) are required to be D50,
@@ -2011,7 +2079,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
     */
    if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
       (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
-         "PCS illuminant is not D50");
+          "PCS illuminant is not D50");
 
    /* The PNG spec requires this:
     * "If the iCCP chunk is present, the image samples conform to the colour
@@ -2039,18 +2107,18 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
       case 0x52474220: /* 'RGB ' */
          if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
             return png_icc_profile_error(png_ptr, colorspace, name, temp,
-               "RGB color space not permitted on grayscale PNG");
+                "RGB color space not permitted on grayscale PNG");
          break;
 
       case 0x47524159: /* 'GRAY' */
          if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
             return png_icc_profile_error(png_ptr, colorspace, name, temp,
-               "Gray color space not permitted on RGB PNG");
+                "Gray color space not permitted on RGB PNG");
          break;
 
       default:
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "invalid ICC profile color space");
+             "invalid ICC profile color space");
    }
 
    /* It is up to the application to check that the profile class matches the
@@ -2075,7 +2143,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
       case 0x61627374: /* 'abst' */
          /* May not be embedded in an image */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "invalid embedded Abstract ICC profile");
+             "invalid embedded Abstract ICC profile");
 
       case 0x6c696e6b: /* 'link' */
          /* DeviceLink profiles cannot be interpreted in a non-device specific
@@ -2085,7 +2153,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
           * PNG.
           */
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "unexpected DeviceLink ICC profile class");
+             "unexpected DeviceLink ICC profile class");
 
       case 0x6e6d636c: /* 'nmcl' */
          /* A NamedColor profile is also device specific, however it doesn't
@@ -2093,7 +2161,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
           * certainly it will fail the tests below.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-            "unexpected NamedColor ICC profile class");
+             "unexpected NamedColor ICC profile class");
          break;
 
       default:
@@ -2103,7 +2171,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
           * understood profiles.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
-            "unrecognized ICC profile class");
+             "unrecognized ICC profile class");
          break;
    }
 
@@ -2119,7 +2187,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
 
       default:
          return png_icc_profile_error(png_ptr, colorspace, name, temp,
-            "unexpected ICC PCS encoding");
+             "unexpected ICC PCS encoding");
    }
 
    return 1;
@@ -2127,8 +2195,8 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
 
 int /* PRIVATE */
 png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length,
-   png_const_bytep profile /* header plus whole tag table */)
+    png_const_charp name, png_uint_32 profile_length,
+    png_const_bytep profile /* header plus whole tag table */)
 {
    png_uint_32 tag_count = png_get_uint_32(profile+128);
    png_uint_32 itag;
@@ -2149,22 +2217,23 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
        * being in range.  All defined tag types have an 8 byte header - a 4 byte
        * type signature then 0.
        */
+
+      /* This is a hard error; potentially it can cause read outside the
+       * profile.
+       */
+      if (tag_start > profile_length || tag_length > profile_length - tag_start)
+         return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
+             "ICC profile tag outside profile");
+
       if ((tag_start & 3) != 0)
       {
-         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
+         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is
           * only a warning here because libpng does not care about the
           * alignment.
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
-            "ICC profile tag start not a multiple of 4");
+             "ICC profile tag start not a multiple of 4");
       }
-
-      /* This is a hard error; potentially it can cause read outside the
-       * profile.
-       */
-      if (tag_start > profile_length || tag_length > profile_length - tag_start)
-         return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
-            "ICC profile tag outside profile");
    }
 
    return 1; /* success, maybe with warnings */
@@ -2192,22 +2261,22 @@ static const struct
     */
    /* adler32, crc32, MD5[4], intent, date, length, file-name */
    PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
-      PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
-      "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+       PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+       "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
 
    /* ICC sRGB v2 perceptual no black-compensation: */
    PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
-      PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
-      "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+       PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+       "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
 
    PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
-      PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
-      "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+       PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+       "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
 
    /* ICC sRGB v4 perceptual */
    PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
-      PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
-      "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+       PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+       "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
 
    /* The following profiles have no known MD5 checksum. If there is a match
     * on the (empty) MD5 the other fields are used to attempt a match and
@@ -2215,8 +2284,8 @@ static const struct
     * which suggests that they were also made by Hewlett Packard.
     */
    PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
-      "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+       "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
 
    /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
     * match the D50 PCS illuminant in the header (it is in fact the D65 values,
@@ -2226,17 +2295,17 @@ static const struct
     * chromaticAdaptationTag.
     */
    PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
-      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
 
    PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
-      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
-      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+       PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+       "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
 };
 
 static int
 png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
-   png_const_bytep profile, uLong adler)
+    png_const_bytep profile, uLong adler)
 {
    /* The quick check is to verify just the MD5 signature and trust the
     * rest of the data.  Because the profile has already been verified for
@@ -2320,7 +2389,7 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
                       * which is made irrelevant by this error.
                       */
                      png_chunk_report(png_ptr, "known incorrect sRGB profile",
-                        PNG_CHUNK_ERROR);
+                         PNG_CHUNK_ERROR);
                   }
 
                   /* Warn that this being done; this isn't even an error since
@@ -2330,8 +2399,8 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
                   else if (png_sRGB_checks[i].have_md5 == 0)
                   {
                      png_chunk_report(png_ptr,
-                        "out-of-date sRGB profile with no signature",
-                        PNG_CHUNK_WARNING);
+                         "out-of-date sRGB profile with no signature",
+                         PNG_CHUNK_WARNING);
                   }
 
                   return 1+png_sRGB_checks[i].is_broken;
@@ -2354,38 +2423,36 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
 
    return 0; /* no match */
 }
-#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 
 void /* PRIVATE */
 png_icc_set_sRGB(png_const_structrp png_ptr,
-   png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+    png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
 {
    /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
     * the sRGB information.
     */
-#if PNG_sRGB_PROFILE_CHECKS >= 0
    if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
-#endif
       (void)png_colorspace_set_sRGB(png_ptr, colorspace,
          (int)/*already checked*/png_get_uint_32(profile+64));
 }
+#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 #endif /* sRGB */
 
 int /* PRIVATE */
 png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
-   png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
-   int color_type)
+    png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+    int color_type)
 {
    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
       return 0;
 
-   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
+   if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
        png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
-          color_type) != 0 &&
+           color_type) != 0 &&
        png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
-          profile) != 0)
+           profile) != 0)
    {
-#     ifdef PNG_sRGB_SUPPORTED
+#     if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
          /* If no sRGB support, don't try storing sRGB information */
          png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
 #     endif
@@ -2444,7 +2511,7 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
          /* Check for an internal error. */
          if (r+g+b != 32768)
             png_error(png_ptr,
-               "internal error handling cHRM coefficients");
+                "internal error handling cHRM coefficients");
 
          else
          {
@@ -2470,7 +2537,7 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
 static int /* PRIVATE */
 png_gt(size_t a, size_t b)
 {
-    return a > b;
+   return a > b;
 }
 #else
 #   define png_gt(a,b) ((a) > (b))
@@ -2478,9 +2545,9 @@ png_gt(size_t a, size_t b)
 
 void /* PRIVATE */
 png_check_IHDR(png_const_structrp png_ptr,
-   png_uint_32 width, png_uint_32 height, int bit_depth,
-   int color_type, int interlace_type, int compression_type,
-   int filter_type)
+    png_uint_32 width, png_uint_32 height, int bit_depth,
+    int color_type, int interlace_type, int compression_type,
+    int filter_type)
 {
    int error = 0;
 
@@ -2497,7 +2564,7 @@ png_check_IHDR(png_const_structrp png_ptr,
       error = 1;
    }
 
-   if (png_gt(((width + 7) & (~7)),
+   if (png_gt(((width + 7) & (~7U)),
        ((PNG_SIZE_MAX
            - 48        /* big_row_buf hack */
            - 1)        /* filter byte */
@@ -2634,7 +2701,7 @@ png_check_IHDR(png_const_structrp png_ptr,
 
 #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
 /* ASCII to fp functions */
-/* Check an ASCII formated floating point value, see the more detailed
+/* Check an ASCII formatted floating point value, see the more detailed
  * comments in pngpriv.h
  */
 /* The following is used internally to preserve the sticky flags */
@@ -2642,11 +2709,11 @@ png_check_IHDR(png_const_structrp png_ptr,
 #define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
 
 int /* PRIVATE */
-png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
-   png_size_tp whereami)
+png_check_fp_number(png_const_charp string, size_t size, int *statep,
+    png_size_tp whereami)
 {
    int state = *statep;
-   png_size_t i = *whereami;
+   size_t i = *whereami;
 
    while (i < size)
    {
@@ -2769,10 +2836,10 @@ PNG_FP_End:
 
 /* The same but for a complete string. */
 int
-png_check_fp_string(png_const_charp string, png_size_t size)
+png_check_fp_string(png_const_charp string, size_t size)
 {
    int        state=0;
-   png_size_t char_index=0;
+   size_t char_index=0;
 
    if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
       (char_index == size || string[char_index] == 0))
@@ -2799,7 +2866,7 @@ png_pow10(int power)
    if (power < 0)
    {
       if (power < DBL_MIN_10_EXP) return 0;
-      recip = 1, power = -power;
+      recip = 1; power = -power;
    }
 
    if (power > 0)
@@ -2824,8 +2891,16 @@ png_pow10(int power)
 /* Function to format a floating point value in ASCII with a given
  * precision.
  */
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic push
+/* The problem arises below with exp_b10, which can never overflow because it
+ * comes, originally, from frexp and is therefore limited to a range which is
+ * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)).
+ */
+#pragma GCC diagnostic warning "-Wstrict-overflow=2"
+#endif /* GCC_STRICT_OVERFLOW */
 void /* PRIVATE */
-png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
+png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
     double fp, unsigned int precision)
 {
    /* We use standard functions from math.h, but not printf because
@@ -2877,7 +2952,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
             double test = png_pow10(exp_b10+1);
 
             if (test <= DBL_MAX)
-               ++exp_b10, base = test;
+            {
+               ++exp_b10; base = test;
+            }
 
             else
                break;
@@ -2891,7 +2968,10 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
           * test on DBL_MAX above.
           */
          fp /= base;
-         while (fp >= 1) fp /= 10, ++exp_b10;
+         while (fp >= 1)
+         {
+            fp /= 10; ++exp_b10;
+         }
 
          /* Because of the code above fp may, at this point, be
           * less than .1, this is ok because the code below can
@@ -2908,7 +2988,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
              */
             if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
             {
-               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
+               czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */
                exp_b10 = 0;      /* Dot added below before first output. */
             }
             else
@@ -2942,7 +3022,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
                      /* Rounding up to 10, handle that here. */
                      if (czero > 0)
                      {
-                        --czero, d = 1;
+                        --czero; d = 1;
                         if (cdigits == 0) --clead;
                      }
                      else
@@ -2956,7 +3036,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
 
                            else if (ch == 46)
                            {
-                              ch = *--ascii, ++size;
+                              ch = *--ascii; ++size;
                               /* Advance exp_b10 to '1', so that the
                                * decimal point happens after the
                                * previous digit.
@@ -2983,7 +3063,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
                               int ch = *--ascii;
 
                               if (ch == 46)
-                                 ++size, exp_b10 = 1;
+                              {
+                                 ++size; exp_b10 = 1;
+                              }
 
                               /* Else lost a leading zero, so 'exp_b10' is
                                * still ok at (-1)
@@ -3019,21 +3101,26 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
                       */
                      if (exp_b10 != (-1))
                      {
-                        if (exp_b10 == 0) *ascii++ = 46, --size;
+                        if (exp_b10 == 0)
+                        {
+                           *ascii++ = 46; --size;
+                        }
                         /* PLUS 1: TOTAL 4 */
                         --exp_b10;
                      }
-                     *ascii++ = 48, --czero;
+                     *ascii++ = 48; --czero;
                   }
 
                   if (exp_b10 != (-1))
                   {
                      if (exp_b10 == 0)
-                        *ascii++ = 46, --size; /* counted above */
+                     {
+                        *ascii++ = 46; --size; /* counted above */
+                     }
 
                      --exp_b10;
                   }
-                  *ascii++ = (char)(48 + (int)d), ++cdigits;
+                  *ascii++ = (char)(48 + (int)d); ++cdigits;
                }
             }
             while (cdigits+czero < precision+clead && fp > DBL_MIN);
@@ -3041,11 +3128,11 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
             /* The total output count (max) is now 4+precision */
 
             /* Check for an exponent, if we don't need one we are
-             * done and just need to terminate the string.  At
-             * this point exp_b10==(-1) is effectively if flag - it got
-             * to '-1' because of the decrement after outputting
-             * the decimal point above (the exponent required is
-             * *not* -1!)
+             * done and just need to terminate the string.  At this
+             * point, exp_b10==(-1) is effectively a flag: it got
+             * to '-1' because of the decrement, after outputting
+             * the decimal point above. (The exponent required is
+             * *not* -1.)
              */
             if (exp_b10 >= (-1) && exp_b10 <= 2)
             {
@@ -3056,7 +3143,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
                 * zeros were *not* output, so this doesn't increase
                 * the output count.
                 */
-               while (--exp_b10 >= 0) *ascii++ = 48;
+               while (exp_b10-- > 0) *ascii++ = 48;
 
                *ascii = 0;
 
@@ -3074,7 +3161,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
              */
             size -= cdigits;
 
-            *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */
+            *ascii++ = 69; --size;    /* 'E': PLUS 1 TOTAL 2+precision */
 
             /* The following use of an unsigned temporary avoids ambiguities in
              * the signed arithmetic on exp_b10 and permits GCC at least to do
@@ -3085,12 +3172,12 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
 
                if (exp_b10 < 0)
                {
-                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
-                  uexp_b10 = -exp_b10;
+                  *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
+                  uexp_b10 = 0U-exp_b10;
                }
 
                else
-                  uexp_b10 = exp_b10;
+                  uexp_b10 = 0U+exp_b10;
 
                cdigits = 0;
 
@@ -3133,6 +3220,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
    /* Here on buffer too small. */
    png_error(png_ptr, "ASCII conversion buffer too small");
 }
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic pop
+#endif /* GCC_STRICT_OVERFLOW */
 
 #  endif /* FLOATING_POINT */
 
@@ -3141,7 +3231,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
  */
 void /* PRIVATE */
 png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
-    png_size_t size, png_fixed_point fp)
+    size_t size, png_fixed_point fp)
 {
    /* Require space for 10 decimal digits, a decimal point, a minus sign and a
     * trailing \0, 13 characters:
@@ -3152,9 +3242,11 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
 
       /* Avoid overflow here on the minimum integer. */
       if (fp < 0)
-         *ascii++ = 45, num = -fp;
+      {
+         *ascii++ = 45; num = (png_uint_32)(-fp);
+      }
       else
-         num = fp;
+         num = (png_uint_32)fp;
 
       if (num <= 0x80000000) /* else overflowed */
       {
@@ -3190,7 +3282,10 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
                 * then ndigits digits to first:
                 */
                i = 5;
-               while (ndigits < i) *ascii++ = 48, --i;
+               while (ndigits < i)
+               {
+                  *ascii++ = 48; --i;
+               }
                while (ndigits >= first) *ascii++ = digits[--ndigits];
                /* Don't output the trailing zeros! */
             }
@@ -3241,6 +3336,15 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
  * the nearest .00001).  Overflow and divide by zero are signalled in
  * the result, a boolean - true on success, false on overflow.
  */
+#if GCC_STRICT_OVERFLOW /* from above */
+/* It is not obvious which comparison below gets optimized in such a way that
+ * signed overflow would change the result; looking through the code does not
+ * reveal any tests which have the form GCC complains about, so presumably the
+ * optimizer is moving an add or subtract into the 'if' somewhere.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wstrict-overflow=2"
+#endif /* GCC_STRICT_OVERFLOW */
 int
 png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
     png_int_32 divisor)
@@ -3355,6 +3459,9 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
 
    return 0;
 }
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic pop
+#endif /* GCC_STRICT_OVERFLOW */
 #endif /* READ_GAMMA || INCH_CONVERSIONS */
 
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
@@ -3648,7 +3755,7 @@ png_log16bit(png_uint_32 x)
  * of getting this accuracy in practice.
  *
  * To deal with this the following exp() function works out the exponent of the
- * frational part of the logarithm by using an accurate 32-bit value from the
+ * fractional part of the logarithm by using an accurate 32-bit value from the
  * top four fractional bits then multiplying in the remaining bits.
  */
 static const png_uint_32
@@ -3806,25 +3913,25 @@ png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
 {
    if (value > 0 && value < 65535)
    {
-#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-         /* The same (unsigned int)->(double) constraints apply here as above,
-          * however in this case the (unsigned int) to (int) conversion can
-          * overflow on an ANSI-C90 compliant system so the cast needs to ensure
-          * that this is not possible.
-          */
-         double r = floor(65535*pow((png_int_32)value/65535.,
-                     gamma_val*.00001)+.5);
-         return (png_uint_16)r;
-#     else
-         png_int_32 lg2 = png_log16bit(value);
-         png_fixed_point res;
-
-         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
-            return png_exp16bit(res);
-
-         /* Overflow. */
-         value = 0;
-#     endif
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+      /* The same (unsigned int)->(double) constraints apply here as above,
+       * however in this case the (unsigned int) to (int) conversion can
+       * overflow on an ANSI-C90 compliant system so the cast needs to ensure
+       * that this is not possible.
+       */
+      double r = floor(65535*pow((png_int_32)value/65535.,
+          gamma_val*.00001)+.5);
+      return (png_uint_16)r;
+# else
+      png_int_32 lg2 = png_log16bit(value);
+      png_fixed_point res;
+
+      if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+         return png_exp16bit(res);
+
+      /* Overflow. */
+      value = 0;
+# endif
    }
 
    return (png_uint_16)value;
@@ -3863,18 +3970,18 @@ png_gamma_correct(png_structrp png_ptr, unsigned int value,
  */
 static void
 png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+    unsigned int shift, png_fixed_point gamma_val)
 {
    /* Various values derived from 'shift': */
-   PNG_CONST unsigned int num = 1U << (8U - shift);
+   unsigned int num = 1U << (8U - shift);
 #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    /* CSE the division and work round wacky GCC warnings (see the comments
     * in png_gamma_8bit_correct for where these come from.)
     */
-   PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1);
+   double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1);
 #endif
-   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
-   PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
+   unsigned int max = (1U << (16U - shift)) - 1U;
+   unsigned int max_by_2 = 1U << (15U - shift);
    unsigned int i;
 
    png_uint_16pp table = *ptable =
@@ -3940,10 +4047,10 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
  */
 static void
 png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
-   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+    unsigned int shift, png_fixed_point gamma_val)
 {
-   PNG_CONST unsigned int num = 1U << (8U - shift);
-   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+   unsigned int num = 1U << (8U - shift);
+   unsigned int max = (1U << (16U - shift))-1U;
    unsigned int i;
    png_uint_32 last;
 
@@ -4008,7 +4115,7 @@ png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
  */
 static void
 png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
-   PNG_CONST png_fixed_point gamma_val)
+    png_fixed_point gamma_val)
 {
    unsigned int i;
    png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
@@ -4088,131 +4195,133 @@ png_destroy_gamma_table(png_structrp png_ptr)
 void /* PRIVATE */
 png_build_gamma_table(png_structrp png_ptr, int bit_depth)
 {
-  png_debug(1, "in png_build_gamma_table");
-
-  /* Remove any existing table; this copes with multiple calls to
-   * png_read_update_info.  The warning is because building the gamma tables
-   * multiple times is a performance hit - it's harmless but the ability to call
-   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
-   * to warn if the app introduces such a hit.
-   */
-  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
-  {
-    png_warning(png_ptr, "gamma table being rebuilt");
-    png_destroy_gamma_table(png_ptr);
-  }
-
-  if (bit_depth <= 8)
-  {
-     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
-         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
+   png_debug(1, "in png_build_gamma_table");
+
+   /* Remove any existing table; this copes with multiple calls to
+    * png_read_update_info. The warning is because building the gamma tables
+    * multiple times is a performance hit - it's harmless but the ability to
+    * call png_read_update_info() multiple times is new in 1.5.6 so it seems
+    * sensible to warn if the app introduces such a hit.
+    */
+   if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+   {
+      png_warning(png_ptr, "gamma table being rebuilt");
+      png_destroy_gamma_table(png_ptr);
+   }
+
+   if (bit_depth <= 8)
+   {
+      png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+          png_ptr->screen_gamma > 0 ?
+          png_reciprocal2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
-     {
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
-            png_reciprocal(png_ptr->colorspace.gamma));
-
-        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
-            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
-     }
+      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+      {
+         png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+             png_reciprocal(png_ptr->colorspace.gamma));
+
+         png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+             png_ptr->screen_gamma > 0 ?
+             png_reciprocal(png_ptr->screen_gamma) :
+             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
+   }
 #ifdef PNG_16BIT_SUPPORTED
-  else
-  {
-     png_byte shift, sig_bit;
-
-     if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
-     {
-        sig_bit = png_ptr->sig_bit.red;
-
-        if (png_ptr->sig_bit.green > sig_bit)
-           sig_bit = png_ptr->sig_bit.green;
-
-        if (png_ptr->sig_bit.blue > sig_bit)
-           sig_bit = png_ptr->sig_bit.blue;
-     }
-     else
-        sig_bit = png_ptr->sig_bit.gray;
-
-     /* 16-bit gamma code uses this equation:
-      *
-      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
-      *
-      * Where 'iv' is the input color value and 'ov' is the output value -
-      * pow(iv, gamma).
-      *
-      * Thus the gamma table consists of up to 256 256-entry tables.  The table
-      * is selected by the (8-gamma_shift) most significant of the low 8 bits of
-      * the color value then indexed by the upper 8 bits:
-      *
-      *   table[low bits][high 8 bits]
-      *
-      * So the table 'n' corresponds to all those 'iv' of:
-      *
-      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
-      *
-      */
-     if (sig_bit > 0 && sig_bit < 16U)
-        /* shift == insignificant bits */
-        shift = (png_byte)((16U - sig_bit) & 0xff);
-
-     else
-        shift = 0; /* keep all 16 bits */
-
-     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
-     {
-        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
-         * the significant bits in the *input* when the output will
-         * eventually be 8 bits.  By default it is 11.
-         */
-        if (shift < (16U - PNG_MAX_GAMMA_8))
-           shift = (16U - PNG_MAX_GAMMA_8);
-     }
-
-     if (shift > 8U)
-        shift = 8U; /* Guarantees at least one table! */
-
-     png_ptr->gamma_shift = shift;
-
-     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
-      * PNG_COMPOSE).  This effectively smashed the background calculation for
-      * 16-bit output because the 8-bit table assumes the result will be reduced
-      * to 8 bits.
-      */
-     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
-         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
-
-     else
-         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
-         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
-         png_ptr->screen_gamma) : PNG_FP_1);
+   else
+   {
+      png_byte shift, sig_bit;
+
+      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+      {
+         sig_bit = png_ptr->sig_bit.red;
+
+         if (png_ptr->sig_bit.green > sig_bit)
+            sig_bit = png_ptr->sig_bit.green;
+
+         if (png_ptr->sig_bit.blue > sig_bit)
+            sig_bit = png_ptr->sig_bit.blue;
+      }
+      else
+         sig_bit = png_ptr->sig_bit.gray;
+
+      /* 16-bit gamma code uses this equation:
+       *
+       *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+       *
+       * Where 'iv' is the input color value and 'ov' is the output value -
+       * pow(iv, gamma).
+       *
+       * Thus the gamma table consists of up to 256 256-entry tables.  The table
+       * is selected by the (8-gamma_shift) most significant of the low 8 bits
+       * of the color value then indexed by the upper 8 bits:
+       *
+       *   table[low bits][high 8 bits]
+       *
+       * So the table 'n' corresponds to all those 'iv' of:
+       *
+       *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
+       *
+       */
+      if (sig_bit > 0 && sig_bit < 16U)
+         /* shift == insignificant bits */
+         shift = (png_byte)((16U - sig_bit) & 0xff);
+
+      else
+         shift = 0; /* keep all 16 bits */
+
+      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+      {
+         /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+          * the significant bits in the *input* when the output will
+          * eventually be 8 bits.  By default it is 11.
+          */
+         if (shift < (16U - PNG_MAX_GAMMA_8))
+            shift = (16U - PNG_MAX_GAMMA_8);
+      }
+
+      if (shift > 8U)
+         shift = 8U; /* Guarantees at least one table! */
+
+      png_ptr->gamma_shift = shift;
+
+      /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+       * PNG_COMPOSE).  This effectively smashed the background calculation for
+       * 16-bit output because the 8-bit table assumes the result will be
+       * reduced to 8 bits.
+       */
+      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+          png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+          png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
+
+      else
+          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+          png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+          png_ptr->screen_gamma) : PNG_FP_1);
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
-     {
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
-            png_reciprocal(png_ptr->colorspace.gamma));
-
-        /* Notice that the '16 from 1' table should be full precision, however
-         * the lookup on this table still uses gamma_shift, so it can't be.
-         * TODO: fix this.
-         */
-        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
-            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
-            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
-     }
+      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+      {
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+             png_reciprocal(png_ptr->colorspace.gamma));
+
+         /* Notice that the '16 from 1' table should be full precision, however
+          * the lookup on this table still uses gamma_shift, so it can't be.
+          * TODO: fix this.
+          */
+         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+             png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-  }
+   }
 #endif /* 16BIT */
 }
 #endif /* READ_GAMMA */
@@ -4225,13 +4334,13 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
    if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
       (option & 1) == 0)
    {
-      int mask = 3 << option;
-      int setting = (2 + (onoff != 0)) << option;
-      int current = png_ptr->options;
+      png_uint_32 mask = 3U << option;
+      png_uint_32 setting = (2U + (onoff != 0)) << option;
+      png_uint_32 current = png_ptr->options;
 
-      png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff);
+      png_ptr->options = (png_uint_32)((current & ~mask) | setting);
 
-      return (current & mask) >> option;
+      return (int)(current & mask) >> option;
    }
 
    return PNG_OPTION_INVALID;
@@ -4243,7 +4352,7 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
 /* sRGB conversion tables; these are machine generated with the code in
  * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
- * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
+ * specification (see the article at https://en.wikipedia.org/wiki/SRGB)
  * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
  * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
  * The inverse (linear to sRGB) table has accuracies as follows:
diff --git a/png.h b/png.h
index 123201d..8e272a0 100644 (file)
--- a/png.h
+++ b/png.h
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.6.21, January 15, 2016
+ * libpng version 1.6.36 - December 1, 2018
  *
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
- * This code is released under the libpng license (See LICENSE, below)
+ * This code is released under the libpng license. (See LICENSE, below.)
  *
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.6.21, January 15, 2016:
+ *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
  *     Glenn Randers-Pehrson.
+ *   libpng version 1.6.36, December 1, 2018: Cosmin Truta
  *   See also "Contributing Authors", below.
  */
 
 /*
- * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
+ * =========================================
+ *
+ * PNG Reference Library License version 2
+ * ---------------------------------------
+ *
+ *  * Copyright (c) 1995-2018 The PNG Reference Library Authors.
+ *  * Copyright (c) 2018 Cosmin Truta.
+ *  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
+ *  * Copyright (c) 1996-1997 Andreas Dilger.
+ *  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * The software is supplied "as is", without warranty of any kind,
+ * express or implied, including, without limitation, the warranties
+ * of merchantability, fitness for a particular purpose, title, and
+ * non-infringement.  In no even shall the Copyright owners, or
+ * anyone distributing the software, be liable for any damages or
+ * other liability, whether in contract, tort or otherwise, arising
+ * from, out of, or in connection with the software, or the use or
+ * other dealings in the software, even if advised of the possibility
+ * of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute
+ * this software, or portions hereof, for any purpose, without fee,
+ * subject to the following restrictions:
+ *
+ *  1. The origin of this software must not be misrepresented; you
+ *     must not claim that you wrote the original software.  If you
+ *     use this software in a product, an acknowledgment in the product
+ *     documentation would be appreciated, but is not required.
+ *
+ *  2. Altered source versions must be plainly marked as such, and must
+ *     not be misrepresented as being the original software.
+ *
+ *  3. This Copyright notice may not be removed or altered from any
+ *     source or altered source distribution.
  *
- * If you modify libpng you may insert additional notices immediately following
- * this sentence.
  *
- * This code is released under the libpng license.
+ * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
+ * -----------------------------------------------------------------------
  *
- * libpng versions 1.0.7, July 1, 2000, through 1.6.21, January 15, 2016, are
- * Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are
+ * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
  * 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
  * added to the list of Contributing Authors:
  *
- *    Simon-Pierre Cadieux
- *    Eric S. Raymond
- *    Mans Rullgard
- *    Cosmin Truta
- *    Gilles Vollant
- *    James Yu
+ *     Simon-Pierre Cadieux
+ *     Eric S. Raymond
+ *     Mans Rullgard
+ *     Cosmin Truta
+ *     Gilles Vollant
+ *     James Yu
+ *     Mandar Sahastrabuddhe
+ *     Google Inc.
+ *     Vadim Barkov
  *
  * and with the following additions to the disclaimer:
  *
- *    There is no warranty against interference with your enjoyment of the
- *    library or against infringement.  There is no warranty that our
- *    efforts or the library will fulfill any of your particular purposes
- *    or needs.  This library is provided with all faults, and the entire
- *    risk of satisfactory quality, performance, accuracy, and effort is with
- *    the user.
+ *     There is no warranty against interference with your enjoyment of
+ *     the library or against infringement.  There is no warranty that our
+ *     efforts or the library will fulfill any of your particular purposes
+ *     or needs.  This library is provided with all faults, and the entire
+ *     risk of satisfactory quality, performance, accuracy, and effort is
+ *     with the user.
+ *
+ * Some files in the "contrib" directory and some configure-generated
+ * files that are distributed with libpng have other copyright owners, and
+ * are released under other open source licenses.
  *
  * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
  * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
  * libpng-0.96, and are distributed according to the same disclaimer and
- * license as libpng-0.96, with the following individuals added to the list
- * of Contributing Authors:
+ * license as libpng-0.96, with the following individuals added to the
+ * list of Contributing Authors:
  *
- *    Tom Lane
- *    Glenn Randers-Pehrson
- *    Willem van Schaik
+ *     Tom Lane
+ *     Glenn Randers-Pehrson
+ *     Willem van Schaik
  *
  * libpng versions 0.89, June 1996, through 0.96, May 1997, are
  * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
  * libpng-0.88, with the following individuals added to the list of
  * Contributing Authors:
  *
- *    John Bowler
- *    Kevin Bracey
- *    Sam Bushell
- *    Magnus Holmgren
- *    Greg Roelofs
- *    Tom Tanner
+ *     John Bowler
+ *     Kevin Bracey
+ *     Sam Bushell
+ *     Magnus Holmgren
+ *     Greg Roelofs
+ *     Tom Tanner
+ *
+ * Some files in the "scripts" directory have other copyright owners,
+ * but are released under this license.
  *
  * libpng versions 0.5, May 1995, through 0.88, January 1996, are
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  * For the purposes of this copyright and license, "Contributing Authors"
  * is defined as the following set of individuals:
  *
- *    Andreas Dilger
- *    Dave Martindale
- *    Guy Eric Schalnat
- *    Paul Schmidt
- *    Tim Wegner
- *
- * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
- * and Group 42, Inc. disclaim all warranties, expressed or implied,
- * including, without limitation, the warranties of merchantability and of
- * fitness for any purpose.  The Contributing Authors and Group 42, Inc.
- * assume no liability for direct, indirect, incidental, special, exemplary,
- * or consequential damages, which may result from the use of the PNG
- * Reference Library, even if advised of the possibility of such damage.
+ *     Andreas Dilger
+ *     Dave Martindale
+ *     Guy Eric Schalnat
+ *     Paul Schmidt
+ *     Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS".  The Contributing
+ * Authors and Group 42, Inc. disclaim all warranties, expressed or
+ * implied, including, without limitation, the warranties of
+ * merchantability and of fitness for any purpose.  The Contributing
+ * Authors and Group 42, Inc. assume no liability for direct, indirect,
+ * incidental, special, exemplary, or consequential damages, which may
+ * result from the use of the PNG Reference Library, even if advised of
+ * the possibility of such damage.
  *
  * Permission is hereby granted to use, copy, modify, and distribute this
  * source code, or portions hereof, for any purpose, without fee, subject
  * to the following restrictions:
  *
- *   1. The origin of this source code must not be misrepresented.
+ *  1. The origin of this source code must not be misrepresented.
  *
- *   2. Altered versions must be plainly marked as such and must not
- *      be misrepresented as being the original source.
+ *  2. Altered versions must be plainly marked as such and must not
+ *     be misrepresented as being the original source.
  *
- *   3. This Copyright notice may not be removed or altered from any
- *      source or altered source distribution.
+ *  3. This Copyright notice may not be removed or altered from any
+ *     source or altered source distribution.
  *
- * The Contributing Authors and Group 42, Inc. specifically permit, without
- * fee, and encourage the use of this source code as a component to
- * supporting the PNG file format in commercial products.  If you use this
- * source code in a product, acknowledgment is not required but would be
- * appreciated.
+ * The Contributing Authors and Group 42, Inc. specifically permit,
+ * without fee, and encourage the use of this source code as a component
+ * to supporting the PNG file format in commercial products.  If you use
+ * this source code in a product, acknowledgment is not required but would
+ * be appreciated.
  *
  * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
+ *
+ * TRADEMARK
+ * =========
+ *
+ * The name "libpng" has not been registered by the Copyright owners
+ * as a trademark in any jurisdiction.  However, because libpng has
+ * been distributed and maintained world-wide, continually since 1995,
+ * the Copyright owners claim "common-law trademark protection" in any
+ * jurisdiction where common-law trademark is recognized.
  */
 
 /*
  */
 
 /*
- * Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is
- * a certification mark of the Open Source Initiative. OSI has not addressed
- * the additional disclaimers inserted at version 1.0.7.
- */
-
-/*
  * The contributing authors would like to thank all those who helped
  * with testing, bug fixes, and patience.  This wouldn't have been
  * possible without all of you.
  *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
  *    1.0.7                    1    10007  (still compatible)
  *    ...
- *    1.0.19                  10    10019  10.so.0.19[.0]
+ *    1.0.69                  10    10069  10.so.0.69[.0]
+ *    ...
+ *    1.2.59                  13    10259  12.so.0.59[.0]
  *    ...
- *    1.2.53                  13    10253  12.so.0.53[.0]
+ *    1.4.20                  14    10420  14.so.0.20[.0]
  *    ...
- *    1.5.23                  15    10523  15.so.15.23[.0]
+ *    1.5.30                  15    10530  15.so.15.30[.0]
  *    ...
- *    1.6.21                  16    10621  16.so.16.21[.0]
- *
- *    Henceforth the source version will match the shared-library major
- *    and minor numbers; the shared-library major version number will be
- *    used for changes in backward compatibility, as it is intended.  The
- *    PNG_LIBPNG_VER macro, which is not used within libpng but is available
- *    for applications, is an unsigned integer of the form xyyzz corresponding
- *    to the source version x.y.z (leading zeros in y and z).  Beta versions
- *    were given the previous public release number plus a letter, until
- *    version 1.0.6j; from then on they were given the upcoming public
- *    release number plus "betaNN" or "rcNN".
+ *    1.6.36                  16    10636  16.so.16.36[.0]
+ *
+ *    Henceforth the source version will match the shared-library major and
+ *    minor numbers; the shared-library major version number will be used for
+ *    changes in backward compatibility, as it is intended.
+ *    The PNG_LIBPNG_VER macro, which is not used within libpng but is
+ *    available for applications, is an unsigned integer of the form XYYZZ
+ *    corresponding to the source version X.Y.Z (leading zeros in Y and Z).
+ *    Beta versions were given the previous public release number plus a
+ *    letter, until version 1.0.6j; from then on they were given the upcoming
+ *    public release number plus "betaNN" or "rcNN".
  *
  *    Binary incompatibility exists only when applications make direct access
  *    to the info_ptr or png_ptr members through png.h, and the compiled
  *    in binary compatibility (e.g., when a new feature is added).
  *
  * See libpng.txt or libpng.3 for more information.  The PNG specification
- * is available as a W3C Recommendation and as an ISO Specification,
- * <http://www.w3.org/TR/2003/REC-PNG-20031110/
- */
-
-/*
- * Y2K compliance in libpng:
- * =========================
- *
- *    January 15, 2016
- *
- *    Since the PNG Development group is an ad-hoc body, we can't make
- *    an official declaration.
- *
- *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.6.21 are Y2K compliant.  It is my belief that
- *    earlier versions were also Y2K compliant.
- *
- *    Libpng only has two year fields.  One is a 2-byte unsigned integer
- *    that will hold years up to 65535.  The other, which is deprecated,
- *    holds the date in text format, and will hold years up to 9999.
- *
- *    The integer is
- *        "png_uint_16 year" in png_time_struct.
- *
- *    The string is
- *        "char time_buffer[29]" in png_struct.  This is no longer used
- *    in libpng-1.6.x and will be removed from libpng-1.7.0.
- *
- *    There are seven time-related functions:
- *        png.c: png_convert_to_rfc_1123_buffer() in png.c
- *          (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and
- *          png_convert_to_rfc_1152() in error prior to libpng-0.98)
- *        png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
- *        png_convert_from_time_t() in pngwrite.c
- *        png_get_tIME() in pngget.c
- *        png_handle_tIME() in pngrutil.c, called in pngread.c
- *        png_set_tIME() in pngset.c
- *        png_write_tIME() in pngwutil.c, called in pngwrite.c
- *
- *    All handle dates properly in a Y2K environment.  The
- *    png_convert_from_time_t() function calls gmtime() to convert from system
- *    clock time, which returns (year - 1900), which we properly convert to
- *    the full 4-digit year.  There is a possibility that libpng applications
- *    are not passing 4-digit years into the png_convert_to_rfc_1123_buffer()
- *    function, or that they are incorrectly passing only a 2-digit year
- *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
- *    but this is not under our control.  The libpng documentation has always
- *    stated that it works with 4-digit years, and the APIs have been
- *    documented as such.
- *
- *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
- *    integer to hold the year, and can hold years as large as 65535.
- *
- *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
- *    no date-related code.
- *
- *       Glenn Randers-Pehrson
- *       libpng maintainer
- *       PNG Development Group
+ * is available as a W3C Recommendation and as an ISO/IEC Standard; see
+ * <https://www.w3.org/TR/2003/REC-PNG-20031110/>
  */
 
 #ifndef PNG_H
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.21"
-#define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.6.21 - January 15, 2016\n"
+#define PNG_LIBPNG_VER_STRING "1.6.36"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.36 - December 1, 2018\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 21
+#define PNG_LIBPNG_VER_RELEASE 36
 
 /* This should match the numeric part of the final component of
  * PNG_LIBPNG_VER_STRING, omitting any leading zero:
 
 #define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
 
-/* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
- * We must not include leading zeros.
- * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
- * version 1.0.0 was mis-numbered 100 instead of 10000).  From
- * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
+/* Careful here.  At one time, Guy wanted to use 082, but that
+ * would be octal.  We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here
+ * (only version 1.0.0 was mis-numbered 100 instead of 10000).
+ * From version 1.0.1 it is:
+ * XXYYZZ, where XX=major, YY=minor, ZZ=release
  */
-#define PNG_LIBPNG_VER 10621 /* 1.6.21 */
+#define PNG_LIBPNG_VER 10636 /* 1.6.36 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
  */
 #ifndef PNGLCONF_H
-    /* If pnglibconf.h is missing, you can
    * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
    */
+/* If pnglibconf.h is missing, you can
+ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+ */
 #   include "pnglibconf.h"
 #endif
 
 #ifndef PNG_VERSION_INFO_ONLY
-   /* Machine specific configuration. */
+/* Machine specific configuration. */
 #  include "pngconf.h"
 #endif
 
@@ -433,7 +428,7 @@ extern "C" {
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  */
-typedef char* png_libpng_version_1_6_21;
+typedef char* png_libpng_version_1_6_36;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
@@ -574,8 +569,8 @@ typedef struct png_text_struct
    png_charp key;          /* keyword, 1-79 character description of "text" */
    png_charp text;         /* comment, may be an empty string (ie "")
                               or a NULL pointer */
-   png_size_t text_length; /* length of the text string */
-   png_size_t itxt_length; /* length of the itxt string */
+   size_t text_length;     /* length of the text string */
+   size_t itxt_length;     /* length of the itxt string */
    png_charp lang;         /* language code, 0-79 characters
                               or a NULL pointer */
    png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
@@ -626,17 +621,17 @@ typedef png_time * * png_timepp;
  */
 typedef struct png_unknown_chunk_t
 {
-    png_byte name[5]; /* Textual chunk name with '\0' terminator */
-    png_byte *data;   /* Data, should not be modified on read! */
-    png_size_t size;
-
-    /* On write 'location' must be set using the flag values listed below.
-     * Notice that on read it is set by libpng however the values stored have
-     * more bits set than are listed below.  Always treat the value as a
-     * bitmask.  On write set only one bit - setting multiple bits may cause the
-     * chunk to be written in multiple places.
-     */
-    png_byte location; /* mode of operation at read time */
+   png_byte name[5]; /* Textual chunk name with '\0' terminator */
+   png_byte *data;   /* Data, should not be modified on read! */
+   size_t size;
+
+   /* On write 'location' must be set using the flag values listed below.
+    * Notice that on read it is set by libpng however the values stored have
+    * more bits set than are listed below.  Always treat the value as a
+    * bitmask.  On write set only one bit - setting multiple bits may cause the
+    * chunk to be written in multiple places.
+    */
+   png_byte location; /* mode of operation at read time */
 }
 png_unknown_chunk;
 
@@ -653,7 +648,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
 /* Maximum positive integer used in PNG is (2^31)-1 */
 #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
 #define PNG_UINT_32_MAX ((png_uint_32)(-1))
-#define PNG_SIZE_MAX ((png_size_t)(-1))
+#define PNG_SIZE_MAX ((size_t)(-1))
 
 /* These are constants for fixed point values encoded in the
  * PNG specification manner (x100000)
@@ -734,24 +729,23 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
  * data in the info_struct to be written into the output file.  The values
  * of the PNG_INFO_<chunk> defines should NOT be changed.
  */
-#define PNG_INFO_gAMA 0x0001
-#define PNG_INFO_sBIT 0x0002
-#define PNG_INFO_cHRM 0x0004
-#define PNG_INFO_PLTE 0x0008
-#define PNG_INFO_tRNS 0x0010
-#define PNG_INFO_bKGD 0x0020
-#define PNG_INFO_hIST 0x0040
-#define PNG_INFO_pHYs 0x0080
-#define PNG_INFO_oFFs 0x0100
-#define PNG_INFO_tIME 0x0200
-#define PNG_INFO_pCAL 0x0400
-#define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
-#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
-#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
-#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
-#if INT_MAX >= 0x8000 /* else this might break */
-#define PNG_INFO_IDAT 0x8000   /* ESR, 1.0.6 */
-#endif
+#define PNG_INFO_gAMA 0x0001U
+#define PNG_INFO_sBIT 0x0002U
+#define PNG_INFO_cHRM 0x0004U
+#define PNG_INFO_PLTE 0x0008U
+#define PNG_INFO_tRNS 0x0010U
+#define PNG_INFO_bKGD 0x0020U
+#define PNG_INFO_hIST 0x0040U
+#define PNG_INFO_pHYs 0x0080U
+#define PNG_INFO_oFFs 0x0100U
+#define PNG_INFO_tIME 0x0200U
+#define PNG_INFO_pCAL 0x0400U
+#define PNG_INFO_sRGB 0x0800U  /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000U  /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000U  /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
+#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
 
 /* This is used for the transformation routines, as some of them
  * change these values for the row.  It also should enable using
@@ -760,7 +754,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
 typedef struct png_row_info_struct
 {
    png_uint_32 width;    /* width of row */
-   png_size_t rowbytes;  /* number of bytes in row */
+   size_t rowbytes;      /* number of bytes in row */
    png_byte color_type;  /* color type of row */
    png_byte bit_depth;   /* bit depth of row */
    png_byte channels;    /* number of channels (1, 2, 3, or 4) */
@@ -779,7 +773,7 @@ typedef png_row_info * * png_row_infopp;
  * expected to return the read data in the buffer.
  */
 typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
-typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t));
+typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t));
 typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
 typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
     int));
@@ -916,8 +910,8 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
  * signature, and non-zero otherwise.  Having num_to_check == 0 or
  * start > 7 will always fail (ie return non-zero).
  */
-PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start,
-    png_size_t num_to_check));
+PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
+    size_t num_to_check));
 
 /* Simple signature checking function.  This is the same as calling
  * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
@@ -936,11 +930,11 @@ PNG_EXPORTA(5, png_structp, png_create_write_struct,
     png_error_ptr warn_fn),
     PNG_ALLOCATED);
 
-PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size,
+PNG_EXPORT(6, size_t, png_get_compression_buffer_size,
     (png_const_structrp png_ptr));
 
 PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
-    png_size_t size));
+    size_t size));
 
 /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
  * match up.
@@ -993,7 +987,7 @@ PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
 
 /* Write a PNG chunk - size, type, (optional) data, CRC. */
 PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
-    chunk_name, png_const_bytep data, png_size_t length));
+    chunk_name, png_const_bytep data, size_t length));
 
 /* Write the start of a PNG chunk - length and chunk name. */
 PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
@@ -1001,7 +995,7 @@ PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
 
 /* Write the data of a PNG chunk started with png_write_chunk_start(). */
 PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
-    png_const_bytep data, png_size_t length));
+    png_const_bytep data, size_t length));
 
 /* Finish a chunk started with png_write_chunk_start() (includes CRC). */
 PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));
@@ -1015,7 +1009,7 @@ PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
  * the API will be removed in the future.
  */
 PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
-    png_size_t png_info_struct_size), PNG_DEPRECATED);
+    size_t png_info_struct_size), PNG_DEPRECATED);
 
 /* Writes all the PNG information before the image. */
 PNG_EXPORT(20, void, png_write_info_before_PLTE,
@@ -1112,7 +1106,7 @@ PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
  * corresponding composited pixel, and the color channels are unassociated
  * (not premultiplied).  The gamma encoded color channels must be scaled
  * according to the contribution and to do this it is necessary to undo
- * the encoding, scale the color values, perform the composition and reencode
+ * the encoding, scale the color values, perform the composition and re-encode
  * the values.  This is the 'PNG' mode.
  *
  * The alternative is to 'associate' the alpha with the color information by
@@ -1168,7 +1162,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
  *
  * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
  *    In this case the output is assumed to be something like an sRGB conformant
- *    display preceeded by a power-law lookup table of power 1.45.  This is how
+ *    display preceded by a power-law lookup table of power 1.45.  This is how
  *    early Mac systems behaved.
  *
  * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
@@ -1215,7 +1209,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
  *
  * When the default gamma of PNG files doesn't match the output gamma.
  *    If you have PNG files with no gamma information png_set_alpha_mode allows
- *    you to provide a default gamma, but it also sets the ouput gamma to the
+ *    you to provide a default gamma, but it also sets the output gamma to the
  *    matching value.  If you know your PNG files have a gamma that doesn't
  *    match the output you can take advantage of the fact that
  *    png_set_alpha_mode always sets the output gamma but only sets the PNG
@@ -1322,7 +1316,7 @@ PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));
 #endif
 
 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */
+#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */
 /* Strip the second byte of information from a 16-bit depth file. */
 PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
 #endif
@@ -1473,8 +1467,8 @@ PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
 #define PNG_FILTER_UP      0x20
 #define PNG_FILTER_AVG     0x40
 #define PNG_FILTER_PAETH   0x80
-#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
-                         PNG_FILTER_AVG | PNG_FILTER_PAETH)
+#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP)
+#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH)
 
 /* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
  * These defines should NOT be changed.
@@ -1666,7 +1660,7 @@ PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
  *           chunk will cause an error at this point unless it is to be saved.
  * positive: The chunk was handled, libpng will ignore/discard it.
  *
- * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about
+ * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about
  * how this behavior will change in libpng 1.7
  */
 PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,
@@ -1691,7 +1685,7 @@ PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
 
 /* Function to be called when data becomes available */
 PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
-    png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size));
+    png_inforp info_ptr, png_bytep buffer, size_t buffer_size));
 
 /* A function which may be called *only* within png_process_data to stop the
  * processing of any more data.  The function returns the number of bytes
@@ -1700,7 +1694,7 @@ PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
  * 'save' is set to true the routine will first save all the pending data and
  * will always return 0.
  */
-PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save));
+PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save));
 
 /* A function which may be called *only* outside (after) a call to
  * png_process_data.  It returns the number of bytes of data to skip in the
@@ -1751,21 +1745,22 @@ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
 #define PNG_SET_WILL_FREE_DATA 1
 #define PNG_USER_WILL_FREE_DATA 2
 /* Flags for png_ptr->free_me and info_ptr->free_me */
-#define PNG_FREE_HIST 0x0008
-#define PNG_FREE_ICCP 0x0010
-#define PNG_FREE_SPLT 0x0020
-#define PNG_FREE_ROWS 0x0040
-#define PNG_FREE_PCAL 0x0080
-#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_HIST 0x0008U
+#define PNG_FREE_ICCP 0x0010U
+#define PNG_FREE_SPLT 0x0020U
+#define PNG_FREE_ROWS 0x0040U
+#define PNG_FREE_PCAL 0x0080U
+#define PNG_FREE_SCAL 0x0100U
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-#  define PNG_FREE_UNKN 0x0200
+#  define PNG_FREE_UNKN 0x0200U
 #endif
-/*      PNG_FREE_LIST 0x0400    removed in 1.6.0 because it is ignored */
-#define PNG_FREE_PLTE 0x1000
-#define PNG_FREE_TRNS 0x2000
-#define PNG_FREE_TEXT 0x4000
-#define PNG_FREE_ALL  0x7fff
-#define PNG_FREE_MUL  0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+/*      PNG_FREE_LIST 0x0400U   removed in 1.6.0 because it is ignored */
+#define PNG_FREE_PLTE 0x1000U
+#define PNG_FREE_TRNS 0x2000U
+#define PNG_FREE_TEXT 0x4000U
+#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */
+#define PNG_FREE_ALL  0xffffU
+#define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
 
 #ifdef PNG_USER_MEM_SUPPORTED
 PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
@@ -1844,7 +1839,7 @@ PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
     png_const_inforp info_ptr, png_uint_32 flag));
 
 /* Returns number of bytes needed to hold a transformed row. */
-PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr,
+PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr,
     png_const_inforp info_ptr));
 
 #ifdef PNG_INFO_IMAGE_SUPPORTED
@@ -1983,6 +1978,18 @@ PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
     png_fixed_point int_blue_Z))
 #endif
 
+#ifdef PNG_eXIf_SUPPORTED
+PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_bytep *exif));
+PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_bytep exif));
+
+PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr,
+    png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif));
+PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif));
+#endif
+
 #ifdef PNG_gAMA_SUPPORTED
 PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
     png_const_inforp info_ptr, double *file_gamma))
@@ -2001,9 +2008,6 @@ PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
 #ifdef PNG_hIST_SUPPORTED
 PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
     png_inforp info_ptr, png_uint_16p *hist));
-#endif
-
-#ifdef PNG_hIST_SUPPORTED
 PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
     png_inforp info_ptr, png_const_uint_16p hist));
 #endif
@@ -2204,7 +2208,7 @@ PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
  * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks
  * it simply resets the behavior to the libpng default.
  *
- * INTERACTION WTIH USER CHUNK CALLBACKS:
+ * INTERACTION WITH USER CHUNK CALLBACKS:
  * The per-chunk handling is always used when there is a png_user_chunk_ptr
  * callback and the callback returns 0; the chunk is then always stored *unless*
  * it is critical and the per-chunk setting is other than ALWAYS.  Notice that
@@ -2271,8 +2275,10 @@ PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
  *    except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
  *    be processed by libpng.
  */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
     int keep, png_const_bytep chunk_list, int num_chunks));
+#endif /* HANDLE_AS_UNKNOWN */
 
 /* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
  * the result is therefore true (non-zero) if special handling is required,
@@ -2280,7 +2286,7 @@ PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
  */
 PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
     png_const_bytep chunk_name));
-#endif
+#endif /* SET_UNKNOWN_CHUNKS */
 
 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
 PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
@@ -2501,33 +2507,37 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
 
  /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
 
-#  define png_composite(composite, fg, alpha, bg)         \
-     { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
-           * (png_uint_16)(alpha)                         \
-           + (png_uint_16)(bg)*(png_uint_16)(255          \
-           - (png_uint_16)(alpha)) + 128);                \
-       (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); }
-
-#  define png_composite_16(composite, fg, alpha, bg)       \
-     { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg)  \
-           * (png_uint_32)(alpha)                          \
-           + (png_uint_32)(bg)*(65535                      \
-           - (png_uint_32)(alpha)) + 32768);               \
-       (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); }
+#  define png_composite(composite, fg, alpha, bg)        \
+   {                                                     \
+      png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+          * (png_uint_16)(alpha)                         \
+          + (png_uint_16)(bg)*(png_uint_16)(255          \
+          - (png_uint_16)(alpha)) + 128);                \
+      (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
+   }
+
+#  define png_composite_16(composite, fg, alpha, bg)     \
+   {                                                     \
+      png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
+          * (png_uint_32)(alpha)                         \
+          + (png_uint_32)(bg)*(65535                     \
+          - (png_uint_32)(alpha)) + 32768);              \
+      (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
+   }
 
 #else  /* Standard method using integer division */
 
-#  define png_composite(composite, fg, alpha, bg)                        \
-     (composite) =                                                       \
-         (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
-         (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
-         127) / 255))
-
-#  define png_composite_16(composite, fg, alpha, bg)                         \
-     (composite) =                                                           \
-         (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
-         (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
-         32767) / 65535))
+#  define png_composite(composite, fg, alpha, bg)                      \
+   (composite) =                                                       \
+       (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
+       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+       127) / 255))
+
+#  define png_composite_16(composite, fg, alpha, bg)                       \
+   (composite) =                                                           \
+       (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+       (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
+       32767) / 65535))
 #endif /* READ_COMPOSITE_NODIV */
 
 #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
@@ -2563,38 +2573,38 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
  * format for negative values, which is almost certainly true.
  */
 #  define PNG_get_uint_32(buf) \
-     (((png_uint_32)(*(buf)) << 24) + \
-      ((png_uint_32)(*((buf) + 1)) << 16) + \
-      ((png_uint_32)(*((buf) + 2)) << 8) + \
-      ((png_uint_32)(*((buf) + 3))))
+   (((png_uint_32)(*(buf)) << 24) + \
+    ((png_uint_32)(*((buf) + 1)) << 16) + \
+    ((png_uint_32)(*((buf) + 2)) << 8) + \
+    ((png_uint_32)(*((buf) + 3))))
 
    /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
     * function) incorrectly returned a value of type png_uint_32.
     */
 #  define PNG_get_uint_16(buf) \
-     ((png_uint_16) \
-      (((unsigned int)(*(buf)) << 8) + \
-       ((unsigned int)(*((buf) + 1)))))
+   ((png_uint_16) \
+    (((unsigned int)(*(buf)) << 8) + \
+    ((unsigned int)(*((buf) + 1)))))
 
 #  define PNG_get_int_32(buf) \
-     ((png_int_32)((*(buf) & 0x80) \
-      ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
-      : (png_int_32)png_get_uint_32(buf)))
+   ((png_int_32)((*(buf) & 0x80) \
+    ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
+    : (png_int_32)png_get_uint_32(buf)))
 
-   /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
   * but defining a macro name prefixed with PNG_PREFIX.
   */
+/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+ * but defining a macro name prefixed with PNG_PREFIX.
+ */
 #  ifndef PNG_PREFIX
-#     define png_get_uint_32(buf) PNG_get_uint_32(buf)
-#     define png_get_uint_16(buf) PNG_get_uint_16(buf)
-#     define png_get_int_32(buf)  PNG_get_int_32(buf)
+#    define png_get_uint_32(buf) PNG_get_uint_32(buf)
+#    define png_get_uint_16(buf) PNG_get_uint_16(buf)
+#    define png_get_int_32(buf)  PNG_get_int_32(buf)
 #  endif
 #else
 #  ifdef PNG_PREFIX
-      /* No macros; revert to the (redefined) function */
-#     define PNG_get_uint_32 (png_get_uint_32)
-#     define PNG_get_uint_16 (png_get_uint_16)
-#     define PNG_get_int_32  (png_get_int_32)
+   /* No macros; revert to the (redefined) function */
+#    define PNG_get_uint_32 (png_get_uint_32)
+#    define PNG_get_uint_16 (png_get_uint_16)
+#    define PNG_get_int_32  (png_get_int_32)
 #  endif
 #endif
 
@@ -2617,7 +2627,7 @@ PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
  * The simplified API hides the details of both libpng and the PNG file format
  * itself.  It allows PNG files to be read into a very limited number of
  * in-memory bitmap formats or to be written from the same formats.  If these
- * formats do not accomodate your needs then you can, and should, use the more
+ * formats do not accommodate your needs then you can, and should, use the more
  * sophisticated APIs above - these support a wide variety of in-memory formats
  * and a wide variety of sophisticated transformations to those formats as well
  * as a wide variety of APIs to manipulate ancillary information.
@@ -2723,7 +2733,7 @@ typedef struct
  *
  * When the simplified API needs to convert between sRGB and linear colorspaces,
  * the actual sRGB transfer curve defined in the sRGB specification (see the
- * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+ * article at <https://en.wikipedia.org/wiki/SRGB>) is used, not the gamma=1/2.2
  * approximation used elsewhere in libpng.
  *
  * When an alpha channel is present it is expected to denote pixel coverage
@@ -2778,6 +2788,8 @@ typedef struct
 #  define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
 #endif
 
+#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
+
 /* Commonly used formats have predefined macros.
  *
  * First the single byte (sRGB) formats:
@@ -2889,12 +2901,19 @@ typedef struct
     * is the minimum 'row stride', the minimum count of components between each
     * row.  For a color-mapped image this is the minimum number of bytes in a
     * row.
+    *
+    * WARNING: this macro overflows for some images with more than one component
+    * and very large image widths.  libpng will refuse to process an image where
+    * this macro would overflow.
     */
 
 #define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
    (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
    /* Return the size, in bytes, of an image buffer given a png_image and a row
     * stride - the number of components to leave space for in each row.
+    *
+    * WARNING: this macro overflows a 32-bit integer for some large PNG images,
+    * libpng will refuse to process an image where such an overflow would occur.
     */
 
 #define PNG_IMAGE_SIZE(image)\
@@ -2917,7 +2936,7 @@ typedef struct
  * 'flags' field of png_image.
  */
 #define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01
-   /* This indicates the the RGB values of the in-memory bitmap do not
+   /* This indicates that the RGB values of the in-memory bitmap do not
     * correspond to the red, green and blue end-points defined by sRGB.
     */
 
@@ -2970,7 +2989,7 @@ PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
 #endif /* STDIO */
 
 PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
-   png_const_voidp memory, png_size_t size));
+   png_const_voidp memory, size_t size));
    /* The PNG header is read from the given memory buffer. */
 
 PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
@@ -3015,7 +3034,6 @@ PNG_EXPORT(238, void, png_image_free, (png_imagep image));
 #endif /* SIMPLIFIED_READ */
 
 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
-#ifdef PNG_STDIO_SUPPORTED
 /* WRITE APIS
  * ----------
  * For write you must initialize a png_image structure to describe the image to
@@ -3032,6 +3050,7 @@ PNG_EXPORT(238, void, png_image_free, (png_imagep image));
  *    values do not correspond to the colors in sRGB.
  * colormap_entries: set to the number of entries in the color-map (0 to 256)
  */
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
 PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
    const char *file, int convert_to_8bit, const void *buffer,
    png_int_32 row_stride, const void *colormap));
@@ -3041,8 +3060,9 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
    int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
    const void *colormap));
    /* Write the image to the given (FILE*). */
+#endif /* SIMPLIFIED_WRITE_STDIO */
 
-/* With both write APIs if image is in one of the linear formats with 16-bit
+/* With all write APIs if image is in one of the linear formats with 16-bit
  * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
  * gamma encoded according to the sRGB specification, otherwise a 16-bit linear
  * encoded PNG file is written.
@@ -3054,13 +3074,103 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
  *
  * With all APIs row_stride is handled as in the read APIs - it is the spacing
  * from one row to the next in component sized units (1 or 2 bytes) and if
- * negative indicates a bottom-up row layout in the buffer.  If row_stride is zero,
- * libpng will calculate it for you from the image width and number of channels.
+ * negative indicates a bottom-up row layout in the buffer.  If row_stride is
+ * zero, libpng will calculate it for you from the image width and number of
+ * channels.
  *
- * Note that the write API does not support interlacing, sub-8-bit pixels, indexed
- * PNG (color_type 3) or most ancillary chunks.
+ * Note that the write API does not support interlacing, sub-8-bit pixels or
+ * most ancillary chunks.  If you need to write text chunks (e.g. for copyright
+ * notices) you need to use one of the other APIs.
  */
-#endif /* STDIO */
+
+PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
+   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,
+   const void *buffer, png_int_32 row_stride, const void *colormap));
+   /* Write the image to the given memory buffer.  The function both writes the
+    * whole PNG data stream to *memory and updates *memory_bytes with the count
+    * of bytes written.
+    *
+    * 'memory' may be NULL.  In this case *memory_bytes is not read however on
+    * success the number of bytes which would have been written will still be
+    * stored in *memory_bytes.  On failure *memory_bytes will contain 0.
+    *
+    * If 'memory' is not NULL it must point to memory[*memory_bytes] of
+    * writeable memory.
+    *
+    * If the function returns success memory[*memory_bytes] (if 'memory' is not
+    * NULL) contains the written PNG data.  *memory_bytes will always be less
+    * than or equal to the original value.
+    *
+    * If the function returns false and *memory_bytes was not changed an error
+    * occurred during write.  If *memory_bytes was changed, or is not 0 if
+    * 'memory' was NULL, the write would have succeeded but for the memory
+    * buffer being too small.  *memory_bytes contains the required number of
+    * bytes and will be bigger that the original value.
+    */
+
+#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\
+   row_stride, colormap)\
+   png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\
+         row_stride, colormap)
+   /* Return the amount of memory in 'size' required to compress this image.
+    * The png_image structure 'image' must be filled in as in the above
+    * function and must not be changed before the actual write call, the buffer
+    * and all other parameters must also be identical to that in the final
+    * write call.  The 'size' variable need not be initialized.
+    *
+    * NOTE: the macro returns true/false, if false is returned 'size' will be
+    * set to zero and the write failed and probably will fail if tried again.
+    */
+
+/* You can pre-allocate the buffer by making sure it is of sufficient size
+ * regardless of the amount of compression achieved.  The buffer size will
+ * always be bigger than the original image and it will never be filled.  The
+ * following macros are provided to assist in allocating the buffer.
+ */
+#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)
+   /* The number of uncompressed bytes in the PNG byte encoding of the image;
+    * uncompressing the PNG IDAT data will give this number of bytes.
+    *
+    * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this
+    * macro can because of the extra bytes used in the PNG byte encoding.  You
+    * need to avoid this macro if your image size approaches 2^30 in width or
+    * height.  The same goes for the remainder of these macros; they all produce
+    * bigger numbers than the actual in-memory image size.
+    */
+#ifndef PNG_ZLIB_MAX_SIZE
+#  define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)
+   /* An upper bound on the number of compressed bytes given 'b' uncompressed
+    * bytes.  This is based on deflateBounds() in zlib; different
+    * implementations of zlib compression may conceivably produce more data so
+    * if your zlib implementation is not zlib itself redefine this macro
+    * appropriately.
+    */
+#endif
+
+#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\
+   PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))
+   /* An upper bound on the size of the data in the PNG IDAT chunks. */
+
+#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
+   ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
+    (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
+    12U+3U*(image).colormap_entries/*PLTE data*/+\
+    (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
+    12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
+    12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
+   /* A helper for the following macro; if your compiler cannot handle the
+    * following macro use this one with the result of
+    * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most
+    * compilers should handle this just fine.)
+    */
+
+#define PNG_IMAGE_PNG_SIZE_MAX(image)\
+   PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))
+   /* An upper bound on the total length of the PNG data stream for 'image'.
+    * The result is of type png_alloc_size_t, on 32-bit systems this may
+    * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will
+    * run out of buffer space but return a corrected size which should work.
+    */
 #endif /* SIMPLIFIED_WRITE */
 /*******************************************************************************
  *  END OF SIMPLIFIED API
@@ -3076,7 +3186,7 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
  * option and 'onoff' is 0 (off) or non-0 (on).  The value returned is given
  * by the PNG_OPTION_ defines below.
  *
- * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,
+ * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions,
  *           are detected at run time, however sometimes it may be impossible
  *           to do this in user mode, in which case it is necessary to discover
  *           the capabilities in an OS specific way.  Such capabilities are
@@ -3094,7 +3204,14 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
 #endif
 #define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
 #define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
-#define PNG_OPTION_NEXT  6 /* Next option - numbers must be even */
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+#  define PNG_MIPS_MSA   6 /* HARDWARE: MIPS Msa SIMD instructions supported */
+#endif
+#define PNG_IGNORE_ADLER32 8
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+#  define PNG_POWERPC_VSX   10 /* HARDWARE: PowerPC VSX SIMD instructions supported */
+#endif
+#define PNG_OPTION_NEXT  12 /* Next option - numbers must be even */
 
 /* Return values: NOTE: there are four values and 'off' is *not* zero */
 #define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
@@ -3118,7 +3235,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
  * one to use is one more than this.)
  */
 #ifdef PNG_EXPORT_LAST_ORDINAL
-  PNG_EXPORT_LAST_ORDINAL(244);
+  PNG_EXPORT_LAST_ORDINAL(249);
 #endif
 
 #ifdef __cplusplus
index 9344654..5e641b2 100644 (file)
--- a/pngconf.h
+++ b/pngconf.h
@@ -1,11 +1,12 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.6.21, January 15, 2016
+ * libpng version 1.6.36
  *
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
 
 #endif /* PNG_BUILDING_SYMBOL_TABLE */
 
-/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using
- * PNG_NO_CONST; this is no longer supported except for data declarations which
- * apparently still cause problems in 2011 on some compilers.
+/* Prior to 1.6.0, it was possible to turn off 'const' in declarations,
+ * using PNG_NO_CONST.  This is no longer supported.
  */
 #define PNG_CONST const /* backward compatibility only */
 
-/* This controls optimization of the reading of 16-bit and 32-bit values
- * from PNG files.  It can be set on a per-app-file basis - it
+/* This controls optimization of the reading of 16-bit and 32-bit
+ * values from PNG files.  It can be set on a per-app-file basis: it
  * just changes whether a macro is used when the function is called.
  * The library builder sets the default; if read functions are not
  * built into the library the macro implementation is forced on.
  *
  * These cases only differ if the operating system does not use the C
  * calling convention, at present this just means the above cases
- * (x86 DOS/Windows sytems) and, even then, this does not apply to
+ * (x86 DOS/Windows systems) and, even then, this does not apply to
  * Cygwin running on those systems.
  *
  * Note that the value must be defined in pnglibconf.h so that what
    * compatible with GCC or Visual C because of different calling conventions.
    */
 #  if PNG_API_RULE == 2
-    /* If this line results in an error, either because __watcall is not
-     * 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 using Watcom and applications must also be built using Watcom!
-     */
+   /* If this line results in an error, either because __watcall is not
+    * 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 using Watcom and applications must also be built using Watcom!
+    */
 #    define PNGCAPI __watcall
 #  endif
 
 #  if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
 #    define PNGCAPI __cdecl
 #    if PNG_API_RULE == 1
-       /* If this line results in an error __stdcall is not understood and
-        * PNG_API_RULE should not have been set to '1'.
-        */
+   /* If this line results in an error __stdcall is not understood and
+    * PNG_API_RULE should not have been set to '1'.
+    */
 #      define PNGAPI __stdcall
 #    endif
 #  else
-    /* An older compiler, or one not detected (erroneously) above,
-     * if necessary override on the command line to get the correct
-     * variants for the compiler.
-     */
+   /* An older compiler, or one not detected (erroneously) above,
+    * if necessary override on the command line to get the correct
+    * variants for the compiler.
+    */
 #    ifndef PNGCAPI
 #      define PNGCAPI _cdecl
 #    endif
 
 #  if (defined(_MSC_VER) && _MSC_VER < 800) ||\
       (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
-    /* older Borland and MSC
-     * compilers used '__export' and required this to be after
-     * the type.
-     */
+   /* older Borland and MSC
+    * compilers used '__export' and required this to be after
+    * the type.
+    */
 #    ifndef PNG_EXPORT_TYPE
 #      define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
 #    endif
 #  if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
 #    define PNGAPI _System
 #  else /* !Windows/x86 && !OS/2 */
-    /* Use the defaults, or define PNG*API on the command line (but
-     * this will have to be done for every compile!)
-     */
+   /* Use the defaults, or define PNG*API on the command line (but
+    * this will have to be done for every compile!)
+    */
 #  endif /* other system, !OS/2 */
 #endif /* !Windows/x86 */
 
  */
 #ifndef PNG_IMPEXP
 #  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
 #  endif
 
    * less efficient code.
    */
 #  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__)
 #      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
 #    endif
 #  error "libpng requires a signed 32-bit (or more) type"
 #endif
 
-#if UINT_MAX > 4294967294
+#if UINT_MAX > 4294967294U
    typedef unsigned int png_uint_32;
-#elif ULONG_MAX > 4294967294
+#elif ULONG_MAX > 4294967294U
    typedef unsigned long int png_uint_32;
 #else
 #  error "libpng requires an unsigned 32-bit (or more) type"
 #endif
 
-/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,
- * requires an ISOC90 compiler and relies on consistent behavior of sizeof.
+/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t.
+ * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant
+ * behavior of sizeof and ptrdiff_t are required.
+ * The legacy typedefs are provided here for backwards compatibility.
  */
 typedef size_t png_size_t;
 typedef ptrdiff_t png_ptrdiff_t;
@@ -537,13 +539,12 @@ typedef ptrdiff_t png_ptrdiff_t;
 #  endif
 #endif
 
-/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no
- * smaller than png_uint_32.  Casts from png_size_t or png_uint_32 to
- * png_alloc_size_t are not necessary; in fact, it is recommended not to use
- * them at all so that the compiler can complain when something turns out to be
- * problematic.
+/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller
+ * than png_uint_32.  Casts from size_t or png_uint_32 to png_alloc_size_t are
+ * not necessary; in fact, it is recommended not to use them at all, so that
+ * the compiler can complain when something turns out to be problematic.
  *
- * Casts in the other direction (from png_alloc_size_t to png_size_t or
+ * Casts in the other direction (from png_alloc_size_t to size_t or
  * png_uint_32) should be explicitly applied; however, we do not expect to
  * encounter practical situations that require such conversions.
  *
@@ -553,7 +554,7 @@ typedef ptrdiff_t png_ptrdiff_t;
 #ifdef PNG_SMALL_SIZE_T
    typedef png_uint_32 png_alloc_size_t;
 #else
-   typedef png_size_t png_alloc_size_t;
+   typedef size_t png_alloc_size_t;
 #endif
 
 /* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
@@ -589,8 +590,8 @@ typedef char                  * png_charp;
 typedef const char            * png_const_charp;
 typedef png_fixed_point       * png_fixed_point_p;
 typedef const png_fixed_point * png_const_fixed_point_p;
-typedef png_size_t            * png_size_tp;
-typedef const png_size_t      * png_const_size_tp;
+typedef size_t                * png_size_tp;
+typedef const size_t          * png_const_size_tp;
 
 #ifdef PNG_STDIO_SUPPORTED
 typedef FILE            * png_FILE_p;
index 15a7ed0..00d5a45 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
  *
- * Last changed in libpng 1.6.8 [December 19, 2013]
+ * Copyright (c) 2018 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
index 6904bea..ec3a709 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -26,7 +26,7 @@ static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
 #ifdef PNG_WARNINGS_SUPPORTED
 static void /* PRIVATE */
 png_default_warning PNGARG((png_const_structrp png_ptr,
-   png_const_charp warning_message));
+    png_const_charp warning_message));
 #endif /* WARNINGS */
 
 /* This function is called whenever there is a fatal error.  This function
@@ -37,14 +37,14 @@ png_default_warning PNGARG((png_const_structrp png_ptr,
 #ifdef PNG_ERROR_TEXT_SUPPORTED
 PNG_FUNCTION(void,PNGAPI
 png_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
    char msg[16];
    if (png_ptr != NULL)
    {
       if ((png_ptr->flags &
-         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0
+         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
       {
          if (*error_message == PNG_LITERAL_SHARP)
          {
@@ -65,18 +65,18 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message),
 
             else
                error_message += offset;
-      }
+         }
 
-      else
-      {
-         if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+         else
          {
-            msg[0] = '0';
-            msg[1] = '\0';
-            error_message = msg;
+            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+            {
+               msg[0] = '0';
+               msg[1] = '\0';
+               error_message = msg;
+            }
          }
-       }
-     }
+      }
    }
 #endif
    if (png_ptr != NULL && png_ptr->error_fn != NULL)
@@ -110,7 +110,7 @@ png_err,(png_const_structrp png_ptr),PNG_NORETURN)
  */
 size_t
 png_safecat(png_charp buffer, size_t bufsize, size_t pos,
-   png_const_charp string)
+    png_const_charp string)
 {
    if (buffer != NULL && pos < bufsize)
    {
@@ -131,7 +131,7 @@ png_safecat(png_charp buffer, size_t bufsize, size_t pos,
  */
 png_charp
 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 mincount = 1; /* minimum number required */
@@ -163,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
          case PNG_NUMBER_FORMAT_02u:
             /* Expects at least 2 digits. */
             mincount = 2;
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
          case PNG_NUMBER_FORMAT_u:
             *--end = digits[number % 10];
@@ -173,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
          case PNG_NUMBER_FORMAT_02x:
             /* This format expects at least two digits */
             mincount = 2;
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
          case PNG_NUMBER_FORMAT_x:
             *--end = digits[number & 0xf];
@@ -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)
       (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
-         warning_message + offset);
+          warning_message + offset);
    else
       png_default_warning(png_ptr, warning_message + offset);
 }
@@ -245,7 +245,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
  */
 void
 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)
       (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,
 
 void
 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];
    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,
 
 void
 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_charp str;
@@ -282,7 +282,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
 
 void
 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,
     * 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)
 void /* PRIVATE */
 png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
 {
-  if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
-     png_warning(png_ptr, error_message);
-  else
-     png_error(png_ptr, error_message);
+   if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
+      png_warning(png_ptr, error_message);
+   else
+      png_error(png_ptr, error_message);
 
 #  ifndef PNG_ERROR_TEXT_SUPPORTED
       PNG_UNUSED(error_message)
@@ -404,10 +404,10 @@ png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
 void /* PRIVATE */
 png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
 {
-  if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
-     png_warning(png_ptr, error_message);
-  else
-     png_error(png_ptr, error_message);
+   if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
+      png_warning(png_ptr, error_message);
+   else
+      png_error(png_ptr, error_message);
 
 #  ifndef PNG_ERROR_TEXT_SUPPORTED
       PNG_UNUSED(error_message)
@@ -425,7 +425,7 @@ png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
  * if the character is invalid.
  */
 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
-static PNG_CONST char png_digit[16] = {
+static const char png_digit[16] = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    'A', 'B', 'C', 'D', 'E', 'F'
 };
@@ -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)
 PNG_FUNCTION(void,PNGAPI
 png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
    char msg[18+PNG_MAX_ERROR_TEXT];
    if (png_ptr == NULL)
@@ -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_ln ((sizeof fixed_message)-1)
-   int  iin;
+   unsigned int  iin;
    char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
    memcpy(msg, fixed_message, fixed_message_ln);
    iin = 0;
@@ -620,7 +620,7 @@ png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
       else
       {
          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)
             return NULL; /* new NULL return on OOM */
@@ -709,7 +709,7 @@ png_free_jmpbuf(png_structrp png_ptr)
  */
 static PNG_FUNCTION(void /* PRIVATE */,
 png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
-   PNG_NORETURN)
+    PNG_NORETURN)
 {
 #ifdef PNG_CONSOLE_IO_SUPPORTED
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@@ -883,9 +883,9 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
     */
 PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
 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;
+   png_const_structrp png_ptr = png_nonconst_ptr;
    png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
 
    /* An error is always logged here, overwriting anything (typically a warning)
@@ -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: */
       {
          size_t pos = png_safecat(image->message, (sizeof image->message), 0,
-            "bad longjmp: ");
+             "bad longjmp: ");
          png_safecat(image->message, (sizeof image->message), pos,
              error_message);
       }
@@ -920,7 +920,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
 void /* PRIVATE */ PNGCBAPI
 png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
 {
-   const png_const_structrp png_ptr = png_nonconst_ptr;
+   png_const_structrp png_ptr = png_nonconst_ptr;
    png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
 
    /* A warning is only logged if there is no prior warning or error. */
index ca44982..5abf1ef 100644 (file)
--- a/pngget.c
+++ b/pngget.c
@@ -1,10 +1,10 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -26,7 +26,7 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
    return(0);
 }
 
-png_size_t PNGAPI
+size_t PNGAPI
 png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
 {
    if (png_ptr != NULL && info_ptr != NULL)
@@ -338,7 +338,7 @@ ppi_from_ppm(png_uint_32 ppm)
    png_fixed_point result;
    if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
        5000) != 0)
-      return result;
+      return (png_uint_32)result;
 
    /* Overflow. */
    return 0;
@@ -367,7 +367,7 @@ png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
 static png_fixed_point
 png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
 {
-   /* Convert from metres * 1,000,000 to inches * 100,000, meters to
+   /* Convert from meters * 1,000,000 to inches * 100,000, meters to
     * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
     * Notice that this can overflow - a warning is output and 0 is
     * returned.
@@ -456,11 +456,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
    return (retval);
 }
 #endif /* pHYs */
-#endif  /* INCH_CONVERSIONS */
+#endif /* INCH_CONVERSIONS */
 
 /* png_get_channels really belongs in here, too, but it's been around longer */
 
-#endif  /* EASY_ACCESS */
+#endif /* EASY_ACCESS */
 
 
 png_byte PNGAPI
@@ -486,7 +486,7 @@ png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
 #ifdef PNG_bKGD_SUPPORTED
 png_uint_32 PNGAPI
 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 &&
        (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
@@ -526,28 +526,28 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
 
       if (white_x != NULL)
          *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)
          *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)
          *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
-            "cHRM red X");
+             "cHRM red X");
       if (red_y != NULL)
          *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
-            "cHRM red Y");
+             "cHRM red Y");
       if (green_x != NULL)
          *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)
          *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)
          *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
-            "cHRM blue X");
+             "cHRM blue X");
       if (blue_y != NULL)
          *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
-            "cHRM blue Y");
+             "cHRM blue Y");
       return (PNG_INFO_cHRM);
    }
 
@@ -556,42 +556,42 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
 
 png_uint_32 PNGAPI
 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 *green_Y, double *green_Z, double *blue_X, double *blue_Y,
-   double *blue_Z)
+    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 *blue_Z)
 {
    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)");
 
       if (red_X != NULL)
          *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
-            "cHRM red X");
+             "cHRM red X");
       if (red_Y != NULL)
          *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
-            "cHRM red Y");
+             "cHRM red Y");
       if (red_Z != NULL)
          *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
-            "cHRM red Z");
+             "cHRM red Z");
       if (green_X != NULL)
          *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)
          *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)
          *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)
          *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)
          *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)
          *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);
    }
 
@@ -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");
 
    if (png_ptr != NULL && info_ptr != NULL &&
-      (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
-      file_gamma != NULL)
+       (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+       file_gamma != NULL)
    {
       *file_gamma = info_ptr->colorspace.gamma;
       return (PNG_INFO_gAMA);
@@ -704,7 +704,7 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
       file_gamma != NULL)
    {
       *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
-         "png_get_gAMA");
+          "png_get_gAMA");
       return (PNG_INFO_gAMA);
    }
 
@@ -741,8 +741,7 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
 
    if (png_ptr != NULL && info_ptr != NULL &&
        (info_ptr->valid & PNG_INFO_iCCP) != 0 &&
-       name != NULL && compression_type != NULL && profile != NULL &&
-           proflen != NULL)
+       name != NULL && profile != NULL && proflen != NULL)
    {
       *name = info_ptr->iccp_name;
       *profile = info_ptr->iccp_profile;
@@ -750,11 +749,13 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
       /* This is somewhat irrelevant since the profile data returned has
        * actually been uncompressed.
        */
-      *compression_type = PNG_COMPRESSION_TYPE_BASE;
+      if (compression_type != NULL)
+         *compression_type = PNG_COMPRESSION_TYPE_BASE;
       return (PNG_INFO_iCCP);
    }
 
    return (0);
+
 }
 #endif
 
@@ -773,6 +774,35 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
 }
 #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
 png_uint_32 PNGAPI
 png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
@@ -901,7 +931,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");
       *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
-         "sCAL height");
+          "sCAL height");
       return (PNG_INFO_sCAL);
    }
 
@@ -1135,26 +1165,26 @@ png_get_user_chunk_ptr(png_const_structrp png_ptr)
 }
 #endif
 
-png_size_t PNGAPI
+size_t PNGAPI
 png_get_compression_buffer_size(png_const_structrp png_ptr)
 {
    if (png_ptr == NULL)
       return 0;
 
 #ifdef PNG_WRITE_SUPPORTED
-      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
 #endif
    {
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-         return png_ptr->IDAT_read_size;
+      return png_ptr->IDAT_read_size;
 #else
-         return PNG_IDAT_READ_SIZE;
+      return PNG_IDAT_READ_SIZE;
 #endif
    }
 
 #ifdef PNG_WRITE_SUPPORTED
-      else
-         return png_ptr->zbuffer_size;
+   else
+      return png_ptr->zbuffer_size;
 #endif
 }
 
index 361ed8b..1f98ded 100644 (file)
--- a/pnginfo.h
+++ b/pnginfo.h
@@ -1,10 +1,10 @@
 
 /* pnginfo.h - header file for PNG reference library
  *
- * Last changed in libpng 1.6.1 [March 28, 2013]
- * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
 struct png_info_def
 {
    /* The following are necessary for every PNG file */
-   png_uint_32 width;  /* width of image in pixels (from IHDR) */
-   png_uint_32 height; /* height of image in pixels (from IHDR) */
-   png_uint_32 valid;  /* valid chunk data (see PNG_INFO_ below) */
-   png_size_t rowbytes; /* bytes needed to hold an untransformed row */
+   png_uint_32 width;       /* width of image in pixels (from IHDR) */
+   png_uint_32 height;      /* height of image in pixels (from IHDR) */
+   png_uint_32 valid;       /* valid chunk data (see PNG_INFO_ below) */
+   size_t rowbytes;         /* bytes needed to hold an untransformed row */
    png_colorp palette;      /* array of color values (valid & PNG_INFO_PLTE) */
    png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
    png_uint_16 num_trans;   /* number of transparent palette color (tRNS) */
@@ -185,6 +185,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
    png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
 #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
    /* The hIST chunk contains the relative frequency or importance of the
     * various palette entries, so that a viewer can intelligently select a
@@ -239,7 +247,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
    /* The sCAL chunk describes the actual physical dimensions of the
     * subject matter of the graphic.  The chunk contains a unit specification
     * a byte value, and two ASCII strings representing floating-point
-    * values.  The values are width and height corresponsing to one pixel
+    * values.  The values are width and height corresponding to one pixel
     * in the image.  Data values are valid if (valid & PNG_INFO_sCAL) is
     * non-zero.
     */
index 7bcfd00..09ed9c1 100644 (file)
--- a/pngmem.c
+++ b/pngmem.c
@@ -1,10 +1,10 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -66,7 +66,7 @@ png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
  */
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 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
     * 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),
  */
 static png_voidp
 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)
       return png_malloc_base(png_ptr, req * element_size);
@@ -120,7 +120,7 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
 
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 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)
       png_error(png_ptr, "internal error: array alloc");
@@ -130,7 +130,7 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements,
 
 PNG_FUNCTION(png_voidp /* PRIVATE */,
 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: */
    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,
    if (add_elements <= INT_MAX - old_elements)
    {
       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)
       {
@@ -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);
 
          memset((char*)new_array + element_size*(unsigned)old_elements, 0,
-            element_size*(unsigned)add_elements);
+             element_size*(unsigned)add_elements);
 
          return new_array;
       }
@@ -187,7 +187,7 @@ png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
 #ifdef PNG_USER_MEM_SUPPORTED
 PNG_FUNCTION(png_voidp,PNGAPI
 png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED PNG_DEPRECATED)
+    PNG_ALLOCATED PNG_DEPRECATED)
 {
    png_voidp ret;
 
@@ -210,7 +210,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
  */
 PNG_FUNCTION(png_voidp,PNGAPI
 png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
-   PNG_ALLOCATED)
+    PNG_ALLOCATED)
 {
    if (png_ptr != NULL)
    {
index 0dc1e53..e283627 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -34,7 +34,7 @@ if (png_ptr->buffer_size < N) \
 
 void PNGAPI
 png_process_data(png_structrp png_ptr, png_inforp info_ptr,
-    png_bytep buffer, png_size_t buffer_size)
+    png_bytep buffer, size_t buffer_size)
 {
    if (png_ptr == NULL || info_ptr == NULL)
       return;
@@ -47,7 +47,7 @@ png_process_data(png_structrp png_ptr, png_inforp info_ptr,
    }
 }
 
-png_size_t PNGAPI
+size_t PNGAPI
 png_process_data_pause(png_structrp png_ptr, int save)
 {
    if (png_ptr != NULL)
@@ -60,7 +60,7 @@ png_process_data_pause(png_structrp png_ptr, int save)
       else
       {
          /* This includes any pending saved bytes: */
-         png_size_t remaining = png_ptr->buffer_size;
+         size_t remaining = png_ptr->buffer_size;
          png_ptr->buffer_size = 0;
 
          /* So subtract the saved buffer size, unless all the data
@@ -77,11 +77,11 @@ png_process_data_pause(png_structrp png_ptr, int save)
 png_uint_32 PNGAPI
 png_process_data_skip(png_structrp png_ptr)
 {
-  /* TODO: Deprecate and remove this API.
  * Somewhere the implementation of this seems to have been lost,
  * or abandoned.  It was only to support some internal back-door access
  * to png_struct) in libpng-1.4.x.
  */
+/* TODO: Deprecate and remove this API.
+ * Somewhere the implementation of this seems to have been lost,
+ * or abandoned.  It was only to support some internal back-door access
+ * to png_struct) in libpng-1.4.x.
+ */
    png_app_warning(png_ptr,
 "png_process_data_skip is not implemented in any current version of libpng");
    return 0;
@@ -133,8 +133,8 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
 void /* PRIVATE */
 png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
 {
-   png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
-       num_to_check = 8 - num_checked;
+   size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */
+   size_t num_to_check = 8 - num_checked;
 
    if (png_ptr->buffer_size < num_to_check)
    {
@@ -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_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
       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;
    }
 
@@ -210,12 +211,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
           (png_ptr->mode & PNG_HAVE_PLTE) == 0)
          png_error(png_ptr, "Missing PLTE before IDAT");
 
-      png_ptr->mode |= PNG_HAVE_IDAT;
       png_ptr->process_mode = PNG_READ_IDAT_MODE;
 
-      if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
-         if (png_ptr->push_length == 0)
-            return;
+      if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+         if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
+            if (png_ptr->push_length == 0)
+               return;
+
+      png_ptr->mode |= PNG_HAVE_IDAT;
 
       if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
          png_benign_error(png_ptr, "Too many IDATs found");
@@ -408,14 +411,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
    {
       PNG_PUSH_SAVE_BUFFER_IF_FULL
       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;
 }
 
 void PNGCBAPI
-png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
 {
    png_bytep ptr;
 
@@ -425,7 +428,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
    ptr = buffer;
    if (png_ptr->save_buffer_size != 0)
    {
-      png_size_t save_size;
+      size_t save_size;
 
       if (length < png_ptr->save_buffer_size)
          save_size = length;
@@ -442,7 +445,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
    }
    if (length != 0 && png_ptr->current_buffer_size != 0)
    {
-      png_size_t save_size;
+      size_t save_size;
 
       if (length < png_ptr->current_buffer_size)
          save_size = length;
@@ -464,7 +467,7 @@ png_push_save_buffer(png_structrp png_ptr)
    {
       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
       {
-         png_size_t i, istop;
+         size_t i, istop;
          png_bytep sp;
          png_bytep dp;
 
@@ -479,7 +482,7 @@ png_push_save_buffer(png_structrp png_ptr)
    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
        png_ptr->save_buffer_max)
    {
-      png_size_t new_max;
+      size_t new_max;
       png_bytep old_buffer;
 
       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
@@ -491,7 +494,7 @@ png_push_save_buffer(png_structrp png_ptr)
       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
       old_buffer = png_ptr->save_buffer;
       png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
-          (png_size_t)new_max);
+          (size_t)new_max);
 
       if (png_ptr->save_buffer == NULL)
       {
@@ -499,7 +502,10 @@ png_push_save_buffer(png_structrp png_ptr)
          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_ptr->save_buffer_max = new_max;
    }
@@ -516,7 +522,7 @@ png_push_save_buffer(png_structrp png_ptr)
 
 void /* PRIVATE */
 png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
+    size_t buffer_length)
 {
    png_ptr->current_buffer = buffer;
    png_ptr->current_buffer_size = buffer_length;
@@ -556,7 +562,7 @@ png_push_read_IDAT(png_structrp png_ptr)
 
    if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
    {
-      png_size_t save_size = png_ptr->save_buffer_size;
+      size_t save_size = png_ptr->save_buffer_size;
       png_uint_32 idat_size = png_ptr->idat_size;
 
       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
@@ -566,7 +572,7 @@ png_push_read_IDAT(png_structrp png_ptr)
        * will break on either 16-bit or 64-bit platforms.
        */
       if (idat_size < save_size)
-         save_size = (png_size_t)idat_size;
+         save_size = (size_t)idat_size;
 
       else
          idat_size = (png_uint_32)save_size;
@@ -583,7 +589,7 @@ png_push_read_IDAT(png_structrp png_ptr)
 
    if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
    {
-      png_size_t save_size = png_ptr->current_buffer_size;
+      size_t save_size = png_ptr->current_buffer_size;
       png_uint_32 idat_size = png_ptr->idat_size;
 
       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
@@ -592,7 +598,7 @@ png_push_read_IDAT(png_structrp png_ptr)
        * larger - this cannot overflow.
        */
       if (idat_size < save_size)
-         save_size = (png_size_t)idat_size;
+         save_size = (size_t)idat_size;
 
       else
          idat_size = (png_uint_32)save_size;
@@ -619,7 +625,7 @@ png_push_read_IDAT(png_structrp png_ptr)
 
 void /* PRIVATE */
 png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
-   png_size_t buffer_length)
+    size_t buffer_length)
 {
    /* The caller checks for a non-zero buffer length. */
    if (!(buffer_length > 0) || buffer == NULL)
@@ -679,7 +685,12 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
             png_warning(png_ptr, "Truncated compressed data in IDAT");
 
          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 */
          return;
@@ -777,7 +788,7 @@ png_push_process_row(png_structrp png_ptr)
    {
       if (png_ptr->pass < 6)
          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
+             png_ptr->transformations);
 
       switch (png_ptr->pass)
       {
@@ -961,20 +972,20 @@ png_read_push_finish_row(png_structrp png_ptr)
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+   static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
 
    /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+   static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
 
    /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+   static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
 
    /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+   static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
 
    /* Height of interlace block.  This is not currently used - if you need
     * it, uncomment it here and in png.h
-   static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+   static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
    */
 #endif
 
@@ -1039,7 +1050,7 @@ png_push_have_row(png_structrp png_ptr, png_bytep row)
 {
    if (png_ptr->row_fn != NULL)
       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
-         (int)png_ptr->pass);
+          (int)png_ptr->pass);
 }
 
 #ifdef PNG_READ_INTERLACING_SUPPORTED
index 1295b51..973c3ea 100644 (file)
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -1,10 +1,10 @@
 
 /* pngpriv.h - private declarations for use inside libpng
  *
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -35,7 +35,9 @@
  * Windows/Visual Studio) there is no effect; the OS specific tests below are
  * still required (as of 2011-05-02.)
  */
-#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+#endif
 
 #ifndef PNG_VERSION_INFO_ONLY
 /* Standard library headers not required by png.h: */
 #     else /* !defined __ARM_NEON__ */
          /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
           */
-#        define PNG_ARM_NEON_IMPLEMENTATION 2
+#        if !defined(__aarch64__)
+            /* The assembler code currently does not work on ARM64 */
+#          define PNG_ARM_NEON_IMPLEMENTATION 2
+#        endif /* __aarch64__ */
 #     endif /* __ARM_NEON__ */
 #  endif /* !PNG_ARM_NEON_IMPLEMENTATION */
 
 #  endif
 #endif /* PNG_ARM_NEON_OPT > 0 */
 
+#ifndef PNG_MIPS_MSA_OPT
+#  if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+#     define PNG_MIPS_MSA_OPT 2
+#  else
+#     define PNG_MIPS_MSA_OPT 0
+#  endif
+#endif
+
+#ifndef PNG_POWERPC_VSX_OPT
+#  if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
+#     define PNG_POWERPC_VSX_OPT 2
+#  else
+#     define PNG_POWERPC_VSX_OPT 0
+#  endif
+#endif
+
+#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
+#      else
+#         define PNG_INTEL_SSE_OPT 0
+#      endif
+#   else
+#      define PNG_INTEL_SSE_OPT 0
+#   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
+#else
+#   define PNG_INTEL_SSE_IMPLEMENTATION 0
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
+#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
+#     if defined(__mips_msa)
+#        if defined(__clang__)
+#        elif defined(__GNUC__)
+#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
+#              define PNG_MIPS_MSA_IMPLEMENTATION 2
+#           endif /* no GNUC support */
+#        endif /* __GNUC__ */
+#     else /* !defined __mips_msa */
+#        define PNG_MIPS_MSA_IMPLEMENTATION 2
+#     endif /* __mips_msa */
+#  endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
+
+#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
+#     define PNG_MIPS_MSA_IMPLEMENTATION 1
+#  endif
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+
+#if PNG_POWERPC_VSX_OPT > 0
+#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
+#  define PNG_POWERPC_VSX_IMPLEMENTATION 1
+#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.
 #  define png_fixed_error(s1,s2) png_err(s1)
 #endif
 
+/* Some fixed point APIs are still required even if not exported because
+ * they get used by the corresponding floating point APIs.  This magic
+ * deals with this:
+ */
+#ifdef PNG_FIXED_POINT_SUPPORTED
+#  define PNGFAPI PNGAPI
+#else
+#  define PNGFAPI /* PRIVATE */
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Other defines specific to compilers can go here.  Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
 /* C allows up-casts from (void*) to any pointer and (const void*) to any
  * pointer to a const object.  C++ regards this as a type error and requires an
  * explicit, static, cast and provides the static_cast<> rune to ensure that
    static_cast<type>(static_cast<const void*>(value))
 #else
 #  define png_voidcast(type, value) (value)
-#  define png_constcast(type, value) ((type)(value))
+#  ifdef _WIN64
+#     ifdef __GNUC__
+         typedef unsigned long long png_ptruint;
+#     else
+         typedef unsigned __int64 png_ptruint;
+#     endif
+#  else
+      typedef unsigned long png_ptruint;
+#  endif
+#  define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
 #  define png_aligncast(type, value) ((void*)(value))
 #  define png_aligncastconst(type, value) ((const void*)(value))
 #endif /* __cplusplus */
 
-/* Some fixed point APIs are still required even if not exported because
- * they get used by the corresponding floating point APIs.  This magic
- * deals with this:
- */
-#ifdef PNG_FIXED_POINT_SUPPORTED
-#  define PNGFAPI PNGAPI
-#else
-#  define PNGFAPI /* PRIVATE */
-#endif
-
-#ifndef PNG_VERSION_INFO_ONLY
-/* Other defines specific to compilers can go here.  Try to keep
- * them inside an appropriate ifdef/endif pair for portability.
- */
 #if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
     defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
    /* png.c requires the following ANSI-C constants if the conversion of
 
 #  if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
     defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
-     /* We need to check that <math.h> hasn't already been included earlier
-      * as it seems it doesn't agree with <fp.h>, yet we should really use
-      * <fp.h> if possible.
-      */
+   /* We need to check that <math.h> hasn't already been included earlier
+    * as it seems it doesn't agree with <fp.h>, yet we should really use
+    * <fp.h> if possible.
+    */
 #    if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
 #      include <fp.h>
 #    endif
 #    include <math.h>
 #  endif
 #  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
-     /* Amiga SAS/C: We must include builtin FPU functions when compiling using
-      * MATH=68881
-      */
+   /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+    * MATH=68881
+    */
 #    include <m68881.h>
 #  endif
 #endif
 /* This implicitly assumes alignment is always to a power of 2. */
 #ifdef png_alignof
 #  define png_isaligned(ptr, type)\
-   ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
+   (((type)((const char*)ptr-(const char*)0) & \
+   (type)(png_alignof(type)-1)) == 0)
 #else
 #  define png_isaligned(ptr, type) 0
 #endif
  * are defined in png.h because they need to be visible to applications
  * that call png_set_unknown_chunk().
  */
-/* #define PNG_HAVE_IHDR            0x01 (defined in png.h) */
-/* #define PNG_HAVE_PLTE            0x02 (defined in png.h) */
-#define PNG_HAVE_IDAT               0x04
-/* #define PNG_AFTER_IDAT           0x08 (defined in png.h) */
-#define PNG_HAVE_IEND               0x10
-                   /*               0x20 (unused) */
-                   /*               0x40 (unused) */
-                   /*               0x80 (unused) */
-#define PNG_HAVE_CHUNK_HEADER      0x100
-#define PNG_WROTE_tIME             0x200
-#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
-#define PNG_BACKGROUND_IS_GRAY     0x800
-#define PNG_HAVE_PNG_SIGNATURE    0x1000
-#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
-                   /*             0x4000 (unused) */
-#define PNG_IS_READ_STRUCT        0x8000 /* Else is a write struct */
+/* #define PNG_HAVE_IHDR            0x01U (defined in png.h) */
+/* #define PNG_HAVE_PLTE            0x02U (defined in png.h) */
+#define PNG_HAVE_IDAT               0x04U
+/* #define PNG_AFTER_IDAT           0x08U (defined in png.h) */
+#define PNG_HAVE_IEND               0x10U
+                   /*               0x20U (unused) */
+                   /*               0x40U (unused) */
+                   /*               0x80U (unused) */
+#define PNG_HAVE_CHUNK_HEADER      0x100U
+#define PNG_WROTE_tIME             0x200U
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
+#define PNG_BACKGROUND_IS_GRAY     0x800U
+#define PNG_HAVE_PNG_SIGNATURE    0x1000U
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
+                   /*             0x4000U (unused) */
+#define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
 
 /* Flags for the transformations the PNG library does on the image data */
-#define PNG_BGR                 0x0001
-#define PNG_INTERLACE           0x0002
-#define PNG_PACK                0x0004
-#define PNG_SHIFT               0x0008
-#define PNG_SWAP_BYTES          0x0010
-#define PNG_INVERT_MONO         0x0020
-#define PNG_QUANTIZE            0x0040
-#define PNG_COMPOSE             0x0080     /* Was PNG_BACKGROUND */
-#define PNG_BACKGROUND_EXPAND   0x0100
-#define PNG_EXPAND_16           0x0200     /* Added to libpng 1.5.2 */
-#define PNG_16_TO_8             0x0400     /* Becomes 'chop' in 1.5.4 */
-#define PNG_RGBA                0x0800
-#define PNG_EXPAND              0x1000
-#define PNG_GAMMA               0x2000
-#define PNG_GRAY_TO_RGB         0x4000
-#define PNG_FILLER              0x8000
-#define PNG_PACKSWAP           0x10000
-#define PNG_SWAP_ALPHA         0x20000
-#define PNG_STRIP_ALPHA        0x40000
-#define PNG_INVERT_ALPHA       0x80000
-#define PNG_USER_TRANSFORM    0x100000
-#define PNG_RGB_TO_GRAY_ERR   0x200000
-#define PNG_RGB_TO_GRAY_WARN  0x400000
-#define PNG_RGB_TO_GRAY       0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
-#define PNG_ENCODE_ALPHA      0x800000 /* Added to libpng-1.5.4 */
-#define PNG_ADD_ALPHA        0x1000000 /* Added to libpng-1.2.7 */
-#define PNG_EXPAND_tRNS      0x2000000 /* Added to libpng-1.2.9 */
-#define PNG_SCALE_16_TO_8    0x4000000 /* Added to libpng-1.5.4 */
-                       /*    0x8000000 unused */
-                       /*   0x10000000 unused */
-                       /*   0x20000000 unused */
-                       /*   0x40000000 unused */
+#define PNG_BGR                 0x0001U
+#define PNG_INTERLACE           0x0002U
+#define PNG_PACK                0x0004U
+#define PNG_SHIFT               0x0008U
+#define PNG_SWAP_BYTES          0x0010U
+#define PNG_INVERT_MONO         0x0020U
+#define PNG_QUANTIZE            0x0040U
+#define PNG_COMPOSE             0x0080U    /* Was PNG_BACKGROUND */
+#define PNG_BACKGROUND_EXPAND   0x0100U
+#define PNG_EXPAND_16           0x0200U    /* Added to libpng 1.5.2 */
+#define PNG_16_TO_8             0x0400U    /* Becomes 'chop' in 1.5.4 */
+#define PNG_RGBA                0x0800U
+#define PNG_EXPAND              0x1000U
+#define PNG_GAMMA               0x2000U
+#define PNG_GRAY_TO_RGB         0x4000U
+#define PNG_FILLER              0x8000U
+#define PNG_PACKSWAP           0x10000U
+#define PNG_SWAP_ALPHA         0x20000U
+#define PNG_STRIP_ALPHA        0x40000U
+#define PNG_INVERT_ALPHA       0x80000U
+#define PNG_USER_TRANSFORM    0x100000U
+#define PNG_RGB_TO_GRAY_ERR   0x200000U
+#define PNG_RGB_TO_GRAY_WARN  0x400000U
+#define PNG_RGB_TO_GRAY       0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ENCODE_ALPHA      0x800000U /* Added to libpng-1.5.4 */
+#define PNG_ADD_ALPHA        0x1000000U /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS      0x2000000U /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8    0x4000000U /* Added to libpng-1.5.4 */
+                       /*    0x8000000U unused */
+                       /*   0x10000000U unused */
+                       /*   0x20000000U unused */
+                       /*   0x40000000U unused */
 /* Flags for png_create_struct */
-#define PNG_STRUCT_PNG   0x0001
-#define PNG_STRUCT_INFO  0x0002
+#define PNG_STRUCT_PNG   0x0001U
+#define PNG_STRUCT_INFO  0x0002U
 
 /* Flags for the png_ptr->flags rather than declaring a byte for each one */
-#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001
-#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002 /* Added to libpng-1.6.0 */
-                                  /*      0x0004    unused */
-#define PNG_FLAG_ZSTREAM_ENDED            0x0008 /* Added to libpng-1.6.0 */
-                                  /*      0x0010    unused */
-                                  /*      0x0020    unused */
-#define PNG_FLAG_ROW_INIT                 0x0040
-#define PNG_FLAG_FILLER_AFTER             0x0080
-#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100
-#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200
-#define PNG_FLAG_CRC_CRITICAL_USE         0x0400
-#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800
-#define PNG_FLAG_ASSUME_sRGB              0x1000 /* Added to libpng-1.5.4 */
-#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000 /* Added to libpng-1.5.4 */
-#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000 /* Added to libpng-1.5.4 */
-/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000 */
-/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000 */
-#define PNG_FLAG_LIBRARY_MISMATCH        0x20000
-#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000
-#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000
-#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000 /* Added to libpng-1.4.0 */
-#define PNG_FLAG_APP_WARNINGS_WARN      0x200000 /* Added to libpng-1.6.0 */
-#define PNG_FLAG_APP_ERRORS_WARN        0x400000 /* Added to libpng-1.6.0 */
-                                  /*    0x800000    unused */
-                                  /*   0x1000000    unused */
-                                  /*   0x2000000    unused */
-                                  /*   0x4000000    unused */
-                                  /*   0x8000000    unused */
-                                  /*  0x10000000    unused */
-                                  /*  0x20000000    unused */
-                                  /*  0x40000000    unused */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001U
+#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002U /* Added to libpng-1.6.0 */
+                                  /*      0x0004U    unused */
+#define PNG_FLAG_ZSTREAM_ENDED            0x0008U /* Added to libpng-1.6.0 */
+                                  /*      0x0010U    unused */
+                                  /*      0x0020U    unused */
+#define PNG_FLAG_ROW_INIT                 0x0040U
+#define PNG_FLAG_FILLER_AFTER             0x0080U
+#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100U
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200U
+#define PNG_FLAG_CRC_CRITICAL_USE         0x0400U
+#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800U
+#define PNG_FLAG_ASSUME_sRGB              0x1000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000U /* Added to libpng-1.5.4 */
+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000U */
+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000U */
+#define PNG_FLAG_LIBRARY_MISMATCH        0x20000U
+#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000U
+#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000U
+#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000U /* Added to libpng-1.4.0 */
+#define PNG_FLAG_APP_WARNINGS_WARN      0x200000U /* Added to libpng-1.6.0 */
+#define PNG_FLAG_APP_ERRORS_WARN        0x400000U /* Added to libpng-1.6.0 */
+                                  /*    0x800000U    unused */
+                                  /*   0x1000000U    unused */
+                                  /*   0x2000000U    unused */
+                                  /*   0x4000000U    unused */
+                                  /*   0x8000000U    unused */
+                                  /*  0x10000000U    unused */
+                                  /*  0x20000000U    unused */
+                                  /*  0x40000000U    unused */
 
 #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
                                      PNG_FLAG_CRC_ANCILLARY_NOWARN)
 /* Added to libpng-1.2.6 JB */
 #define PNG_ROWBYTES(pixel_bits, width) \
     ((pixel_bits) >= 8 ? \
-    ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
-    (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
+    ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \
+    (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) )
+
+/* This returns the number of trailing bits in the last byte of a row, 0 if the
+ * last byte is completely full of pixels.  It is, in principle, (pixel_bits x
+ * width) % 8, but that would overflow for large 'width'.  The second macro is
+ * the same except that it returns the number of unused bits in the last byte;
+ * (8-TRAILBITS), but 0 when TRAILBITS is 0.
+ *
+ * NOTE: these macros are intended to be self-evidently correct and never
+ * overflow on the assumption that pixel_bits is in the range 0..255.  The
+ * arguments are evaluated only once and they can be signed (e.g. as a result of
+ * the integral promotions).  The result of the expression always has type
+ * (png_uint_32), however the compiler always knows it is in the range 0..7.
+ */
+#define PNG_TRAILBITS(pixel_bits, width) \
+    (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
+
+#define PNG_PADBITS(pixel_bits, width) \
+    ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
 
 /* PNG_OUT_OF_RANGE returns true if value is outside the range
  * ideal-delta..ideal+delta.  Each argument is evaluated twice.
 #define png_PLTE PNG_U32( 80,  76,  84,  69)
 #define png_bKGD PNG_U32( 98,  75,  71,  68)
 #define png_cHRM PNG_U32( 99,  72,  82,  77)
+#define png_eXIf PNG_U32(101,  88,  73, 102) /* registered July 2017 */
 #define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
 #define png_gAMA PNG_U32(103,  65,  77,  65)
 #define png_gIFg PNG_U32(103,  73,  70, 103)
     * PNG files the -I directives must match.
     *
     * The most likely explanation is that you passed a -I in CFLAGS. This will
-    * not work; all the preprocessor directories and in particular all the -I
+    * not work; all the preprocessor directives and in particular all the -I
     * directives must be in CPPFLAGS.
     */
 #endif
@@ -936,15 +1055,15 @@ PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
  */
 
 PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
-    png_bytep data, png_size_t length),PNG_EMPTY);
+    png_bytep data, size_t length),PNG_EMPTY);
 
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
-    png_bytep buffer, png_size_t length),PNG_EMPTY);
+    png_bytep buffer, size_t length),PNG_EMPTY);
 #endif
 
 PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
-    png_bytep data, png_size_t length),PNG_EMPTY);
+    png_bytep data, size_t length),PNG_EMPTY);
 
 #ifdef PNG_WRITE_FLUSH_SUPPORTED
 #  ifdef PNG_STDIO_SUPPORTED
@@ -958,7 +1077,7 @@ PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
 
 /* Write the "data" buffer to whatever output you are using */
 PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
-    png_const_bytep data, png_size_t length),PNG_EMPTY);
+    png_const_bytep data, size_t length),PNG_EMPTY);
 
 /* Read and check the PNG file signature */
 PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
@@ -970,7 +1089,7 @@ PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
 
 /* Read data from whatever input you are using into the "data" buffer */
 PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
-    png_size_t length),PNG_EMPTY);
+    size_t length),PNG_EMPTY);
 
 /* Read bytes into buf, and update png_ptr->crc */
 PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
@@ -988,7 +1107,7 @@ PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);
  * since this is the maximum buffer size we can specify.
  */
 PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
-   png_const_bytep ptr, png_size_t length),PNG_EMPTY);
+   png_const_bytep ptr, size_t length),PNG_EMPTY);
 
 #ifdef PNG_WRITE_FLUSH_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
@@ -1025,7 +1144,7 @@ PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
 #ifdef PNG_WRITE_cHRM_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
     const png_xy *xy), PNG_EMPTY);
-    /* The xy value must have been previously validated */
+   /* The xy value must have been previously validated */
 #endif
 
 #ifdef PNG_WRITE_sRGB_SUPPORTED
@@ -1033,6 +1152,11 @@ PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
     int intent),PNG_EMPTY);
 #endif
 
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
+    png_bytep exif, int num_exif),PNG_EMPTY);
+#endif
+
 #ifdef PNG_WRITE_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
    png_const_charp name, png_const_bytep profile), PNG_EMPTY);
@@ -1066,7 +1190,7 @@ PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
 /* Chunks that have keywords */
 #ifdef PNG_WRITE_tEXt_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
-   png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY);
+   png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY);
 #endif
 
 #ifdef PNG_WRITE_zTXt_SUPPORTED
@@ -1174,6 +1298,7 @@ PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
     row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
 
+#if PNG_ARM_NEON_OPT > 0
 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_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_neon,(png_row_infop
@@ -1188,6 +1313,56 @@ 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);
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
+    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_POWERPC_VSX_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
+    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop
+    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_INTEL_SSE_IMPLEMENTATION > 0
+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);
+#endif
 
 /* Choose the best filter to use and filter the row data */
 PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
@@ -1215,7 +1390,7 @@ PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
 /* Initialize the row buffers, etc. */
 PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
 
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
 PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
       PNG_EMPTY);
 #  define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
@@ -1281,6 +1456,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr,
+    png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
 #ifdef PNG_READ_gAMA_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
@@ -1356,9 +1536,12 @@ PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 #endif
 
-PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
     png_uint_32 chunk_name),PNG_EMPTY);
 
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
+    png_uint_32 chunk_length),PNG_EMPTY);
+
 PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
    /* This is the function that gets called for unknown chunks.  The 'keep'
@@ -1400,10 +1583,10 @@ PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
     PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
-    png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+    png_bytep buffer, size_t buffer_length),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
-    png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+    png_bytep buffer, size_t buffer_length),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
     PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,
@@ -1413,7 +1596,7 @@ PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
 PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
    png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
-     png_bytep row),PNG_EMPTY);
+    png_bytep row),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
     png_inforp info_ptr),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
@@ -1452,13 +1635,13 @@ PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
 
 PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
     png_inforp info_ptr), PNG_EMPTY);
-    /* Synchronize the info 'valid' flags with the colorspace */
+   /* Synchronize the info 'valid' flags with the colorspace */
 
 PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
     png_inforp info_ptr), PNG_EMPTY);
-    /* Copy the png_struct colorspace to the info_struct and call the above to
-     * synchronize the flags.  Checks for NULL info_ptr and does nothing.
-     */
+   /* Copy the png_struct colorspace to the info_struct and call the above to
+    * synchronize the flags.  Checks for NULL info_ptr and does nothing.
+    */
 #endif
 
 /* Added at libpng version 1.4.0 */
@@ -1492,9 +1675,11 @@ PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
    /* The 'name' is used for information only */
 
 /* Routines for checking parts of an ICC profile. */
+#ifdef PNG_READ_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_charp name,
    png_uint_32 profile_length), PNG_EMPTY);
+#endif /* READ_iCCP */
 PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_charp name,
    png_uint_32 profile_length,
@@ -1671,13 +1856,13 @@ PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
 
 #ifdef PNG_FLOATING_POINT_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
-   png_charp ascii, png_size_t size, double fp, unsigned int precision),
+   png_charp ascii, size_t size, double fp, unsigned int precision),
    PNG_EMPTY);
 #endif /* FLOATING_POINT */
 
 #ifdef PNG_FIXED_POINT_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
-   png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY);
+   png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY);
 #endif /* FIXED_POINT */
 #endif /* sCAL */
 
@@ -1770,7 +1955,7 @@ PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
  * the problem character.)  This has not been tested within libpng.
  */
 PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
-   png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
+   size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
 
 /* This is the same but it checks a complete string and returns true
  * only if it just contains a floating point number.  As of 1.5.4 this
@@ -1779,7 +1964,7 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
  * for negative or zero values using the sticky flag.
  */
 PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
-   png_size_t size),PNG_EMPTY);
+   size_t size),PNG_EMPTY);
 #endif /* pCAL || sCAL */
 
 #if defined(PNG_GAMMA_SUPPORTED) ||\
@@ -1854,7 +2039,7 @@ typedef struct png_control
    png_voidp   error_buf;           /* Always a jmp_buf at present. */
 
    png_const_bytep memory;          /* Memory buffer. */
-   png_size_t      size;            /* Size of the memory buffer. */
+   size_t          size;            /* Size of the memory buffer. */
 
    unsigned int for_write       :1; /* Otherwise it is a read structure */
    unsigned int owned_file      :1; /* We own the file in io_ptr */
@@ -1913,13 +2098,48 @@ PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
     * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
     * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
     */
+#  if PNG_ARM_NEON_OPT > 0
 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
 #endif
 
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
+   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
+#  if PNG_INTEL_SSE_IMPLEMENTATION > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
+   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#  endif
+#endif
+
 PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
    png_const_charp key, png_bytep new_key), PNG_EMPTY);
 
+#if PNG_ARM_NEON_IMPLEMENTATION == 1
+PNG_INTERNAL_FUNCTION(void,
+                      png_riffle_palette_rgba,
+                      (png_structrp, png_row_infop),
+                      PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,
+                      png_do_expand_palette_neon_rgba,
+                      (png_structrp,
+                       png_row_infop,
+                       png_const_bytep,
+                       const png_bytepp,
+                       const png_bytepp),
+                      PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,
+                      png_do_expand_palette_neon_rgb,
+                      (png_structrp,
+                       png_row_infop,
+                       png_const_bytep,
+                       const png_bytepp,
+                       const png_bytepp),
+                      PNG_EMPTY);
+#endif
+
 /* Maintainer: Put new private prototypes here ^ */
 
 #include "pngdebug.h"
index dca3d7d..f8e7621 100644 (file)
--- a/pngread.c
+++ b/pngread.c
@@ -1,10 +1,10 @@
 
 /* pngread.c - read a PNG file
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -28,10 +28,10 @@ png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
 {
 #ifndef PNG_USER_MEM_SUPPORTED
    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
-      error_fn, warn_fn, NULL, NULL, NULL);
+        error_fn, warn_fn, NULL, NULL, NULL);
 #else
    return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
-       warn_fn, NULL, NULL, NULL);
+        warn_fn, NULL, NULL, NULL);
 }
 
 /* Alternate create PNG structure for reading, and allocate any memory
@@ -43,7 +43,7 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
     png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
 {
    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
-      error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
 #endif /* USER_MEM */
 
    if (png_ptr != NULL)
@@ -127,7 +127,10 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
       }
 
       else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+      {
+         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
          png_ptr->mode |= PNG_AFTER_IDAT;
+      }
 
       /* This should be a binary subdivision search or a hash for
        * matching the chunk name rather than a linear search.
@@ -172,6 +175,11 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
          png_handle_cHRM(png_ptr, info_ptr, length);
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+      else if (chunk_name == png_eXIf)
+         png_handle_eXIf(png_ptr, info_ptr, length);
+#endif
+
 #ifdef PNG_READ_gAMA_SUPPORTED
       else if (chunk_name == png_gAMA)
          png_handle_gAMA(png_ptr, info_ptr, length);
@@ -249,7 +257,7 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
 
       else
          png_handle_unknown(png_ptr, info_ptr, length,
-            PNG_HANDLE_CHUNK_AS_DEFAULT);
+             PNG_HANDLE_CHUNK_AS_DEFAULT);
    }
 }
 #endif /* SEQUENTIAL_READ */
@@ -276,7 +284,7 @@ png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
       else
          png_app_error(png_ptr,
-            "png_read_update_info/png_start_read_image: duplicate call");
+             "png_read_update_info/png_start_read_image: duplicate call");
    }
 }
 
@@ -299,7 +307,7 @@ png_start_read_image(png_structrp png_ptr)
       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
       else
          png_app_error(png_ptr,
-            "png_start_read_image/png_read_update_info: duplicate call");
+             "png_start_read_image/png_read_update_info: duplicate call");
    }
 }
 #endif /* SEQUENTIAL_READ */
@@ -356,9 +364,9 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
 
          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
          {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 s0   = (png_uint_32)(*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
             png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
             png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
             *(rp    ) = (png_byte)((red >> 8) & 0xff);
@@ -531,13 +539,14 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
       png_error(png_ptr, "Invalid attempt to read row data");
 
    /* Fill the row with IDAT data: */
+   png_ptr->row_buf[0]=255; /* to force error if no data was found */
    png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
 
    if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
    {
       if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
          png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
-            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
       else
          png_error(png_ptr, "bad adaptive filter value");
    }
@@ -581,7 +590,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
    {
       if (png_ptr->pass < 6)
          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
-            png_ptr->transformations);
+             png_ptr->transformations);
 
       if (dsp_row != NULL)
          png_combine_row(png_ptr, dsp_row, 1/*display*/);
@@ -716,7 +725,7 @@ png_read_image(png_structrp png_ptr, png_bytepp image)
           * but the caller should do it!
           */
          png_warning(png_ptr, "Interlace handling should be turned on when "
-            "using png_read_image");
+             "using png_read_image");
          /* Make sure this is set correctly */
          png_ptr->num_rows = png_ptr->height;
       }
@@ -776,8 +785,8 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
    /* Report invalid palette index; added at libng-1.5.10 */
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-      png_ptr->num_palette_max > png_ptr->num_palette)
-     png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+       png_ptr->num_palette_max > png_ptr->num_palette)
+      png_benign_error(png_ptr, "Read palette index exceeding num_palette");
 #endif
 
    do
@@ -785,6 +794,9 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
       png_uint_32 length = png_read_chunk_header(png_ptr);
       png_uint_32 chunk_name = png_ptr->chunk_name;
 
+      if (chunk_name != png_IDAT)
+         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
       if (chunk_name == png_IEND)
          png_handle_IEND(png_ptr, info_ptr, length);
 
@@ -799,9 +811,9 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
       {
          if (chunk_name == png_IDAT)
          {
-            if ((length > 0) ||
-                (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
-               png_benign_error(png_ptr, "Too many IDATs found");
+            if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+                || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+               png_benign_error(png_ptr, ".Too many IDATs found");
          }
          png_handle_unknown(png_ptr, info_ptr, length, keep);
          if (chunk_name == png_PLTE)
@@ -812,10 +824,14 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
       else if (chunk_name == png_IDAT)
       {
          /* Zero length IDATs are legal after the last IDAT has been
-          * read, but not after other chunks have been read.
+          * read, but not after other chunks have been read.  1.6 does not
+          * always read all the deflate data; specifically it cannot be relied
+          * upon to read the Adler32 at the end.  If it doesn't ignore IDAT
+          * chunks which are longer than zero as well:
           */
-         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
-            png_benign_error(png_ptr, "Too many IDATs found");
+         if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+             || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+            png_benign_error(png_ptr, "..Too many IDATs found");
 
          png_crc_finish(png_ptr, length);
       }
@@ -832,6 +848,11 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
          png_handle_cHRM(png_ptr, info_ptr, length);
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+      else if (chunk_name == png_eXIf)
+         png_handle_eXIf(png_ptr, info_ptr, length);
+#endif
+
 #ifdef PNG_READ_gAMA_SUPPORTED
       else if (chunk_name == png_gAMA)
          png_handle_gAMA(png_ptr, info_ptr, length);
@@ -909,7 +930,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
 
       else
          png_handle_unknown(png_ptr, info_ptr, length,
-            PNG_HANDLE_CHUNK_AS_DEFAULT);
+             PNG_HANDLE_CHUNK_AS_DEFAULT);
    } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
 }
 #endif /* SEQUENTIAL_READ */
@@ -1020,8 +1041,7 @@ png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
 #ifdef PNG_INFO_IMAGE_SUPPORTED
 void PNGAPI
 png_read_png(png_structrp png_ptr, png_inforp info_ptr,
-                           int transforms,
-                           voidp params)
+    int transforms, voidp params)
 {
    if (png_ptr == NULL || info_ptr == NULL)
       return;
@@ -1297,7 +1317,7 @@ png_image_read_init(png_imagep image)
          if (info_ptr != NULL)
          {
             png_controlp control = png_voidcast(png_controlp,
-               png_malloc_warn(png_ptr, (sizeof *control)));
+                png_malloc_warn(png_ptr, (sizeof *control)));
 
             if (control != NULL)
             {
@@ -1384,7 +1404,9 @@ png_image_read_header(png_voidp argument)
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
 
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    png_set_benign_errors(png_ptr, 1/*warn*/);
+#endif
    png_read_info(png_ptr, info_ptr);
 
    /* Do this the fast way; just read directly out of png_struct. */
@@ -1422,7 +1444,7 @@ png_image_read_header(png_voidp argument)
             break;
 
          case PNG_COLOR_TYPE_PALETTE:
-            cmap_entries = png_ptr->num_palette;
+            cmap_entries = (png_uint_32)png_ptr->num_palette;
             break;
 
          default:
@@ -1460,12 +1482,12 @@ png_image_begin_read_from_stdio(png_imagep image, FILE* file)
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_stdio: invalid argument");
+             "png_image_begin_read_from_stdio: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1498,19 +1520,19 @@ png_image_begin_read_from_file(png_imagep image, const char *file_name)
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_file: invalid argument");
+             "png_image_begin_read_from_file: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
 #endif /* STDIO */
 
 static void PNGCBAPI
-png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
+png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need)
 {
    if (png_ptr != NULL)
    {
@@ -1521,7 +1543,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
          if (cp != NULL)
          {
             png_const_bytep memory = cp->memory;
-            png_size_t size = cp->size;
+            size_t size = cp->size;
 
             if (memory != NULL && size >= need)
             {
@@ -1540,7 +1562,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
 }
 
 int PNGAPI png_image_begin_read_from_memory(png_imagep image,
-   png_const_voidp memory, png_size_t size)
+    png_const_voidp memory, size_t size)
 {
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
@@ -1563,12 +1585,12 @@ int PNGAPI png_image_begin_read_from_memory(png_imagep image,
 
       else
          return png_image_error(image,
-            "png_image_begin_read_from_memory: invalid argument");
+             "png_image_begin_read_from_memory: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+          "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
 
    return 0;
 }
@@ -1599,7 +1621,7 @@ png_image_skip_unused_chunks(png_structrp png_ptr)
     * errors (which are unfortunately quite common.)
     */
    {
-         static PNG_CONST png_byte chunks_to_process[] = {
+         static const png_byte chunks_to_process[] = {
             98,  75,  71,  68, '\0',  /* bKGD */
             99,  72,  82,  77, '\0',  /* cHRM */
            103,  65,  77,  65, '\0',  /* gAMA */
@@ -1614,12 +1636,12 @@ png_image_skip_unused_chunks(png_structrp png_ptr)
         * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
         */
        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
-         NULL, -1);
+           NULL, -1);
 
        /* But do not ignore image data handling chunks */
        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
-         chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
-    }
+           chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
+   }
 }
 
 #  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
@@ -1686,7 +1708,7 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
 #ifdef __GNUC__
       default:
          png_error(display->image->opaque->png_ptr,
-            "unexpected encoding (internal error)");
+             "unexpected encoding (internal error)");
 #endif
    }
 
@@ -1695,8 +1717,8 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
 
 static png_uint_32
 png_colormap_compose(png_image_read_control *display,
-   png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
-   png_uint_32 background, int encoding)
+    png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+    png_uint_32 background, int encoding)
 {
    /* The file value is composed on the background, the background has the given
     * encoding and so does the result, the file is encoded with P_FILE and the
@@ -1732,14 +1754,14 @@ png_colormap_compose(png_image_read_control *display,
  */
 static void
 png_create_colormap_entry(png_image_read_control *display,
-   png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
-   png_uint_32 alpha, int encoding)
+    png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+    png_uint_32 alpha, int encoding)
 {
    png_imagep image = display->image;
-   const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
-      P_LINEAR : P_sRGB;
-   const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
-      (red != green || green != blue);
+   int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
+       P_LINEAR : P_sRGB;
+   int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
+       (red != green || green != blue);
 
    if (ip > 255)
       png_error(image->opaque->png_ptr, "color-map index out of range");
@@ -1847,13 +1869,13 @@ png_create_colormap_entry(png_image_read_control *display,
    /* Store the value. */
    {
 #     ifdef PNG_FORMAT_AFIRST_SUPPORTED
-         const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+         int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
             (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
 #     else
 #        define afirst 0
 #     endif
 #     ifdef PNG_FORMAT_BGR_SUPPORTED
-         const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+         int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
 #     else
 #        define bgr 0
 #     endif
@@ -1872,7 +1894,7 @@ png_create_colormap_entry(png_image_read_control *display,
          {
             case 4:
                entry[afirst ? 0 : 3] = (png_uint_16)alpha;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case 3:
                if (alpha < 65535)
@@ -1894,7 +1916,7 @@ png_create_colormap_entry(png_image_read_control *display,
 
             case 2:
                entry[1 ^ afirst] = (png_uint_16)alpha;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
             case 1:
                if (alpha < 65535)
@@ -1923,6 +1945,7 @@ png_create_colormap_entry(png_image_read_control *display,
          {
             case 4:
                entry[afirst ? 0 : 3] = (png_byte)alpha;
+               /* FALLTHROUGH */
             case 3:
                entry[afirst + (2 ^ bgr)] = (png_byte)blue;
                entry[afirst + 1] = (png_byte)green;
@@ -1931,6 +1954,7 @@ png_create_colormap_entry(png_image_read_control *display,
 
             case 2:
                entry[1 ^ afirst] = (png_byte)alpha;
+               /* FALLTHROUGH */
             case 1:
                entry[afirst] = (png_byte)green;
                break;
@@ -1957,7 +1981,7 @@ make_gray_file_colormap(png_image_read_control *display)
    for (i=0; i<256; ++i)
       png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
 
-   return i;
+   return (int)i;
 }
 
 static int
@@ -1968,7 +1992,7 @@ make_gray_colormap(png_image_read_control *display)
    for (i=0; i<256; ++i)
       png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
 
-   return i;
+   return (int)i;
 }
 #define PNG_GRAY_COLORMAP_ENTRIES 256
 
@@ -2019,10 +2043,10 @@ make_ga_colormap(png_image_read_control *display)
 
       for (g=0; g<6; ++g)
          png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
-            P_sRGB);
+             P_sRGB);
    }
 
-   return i;
+   return (int)i;
 }
 
 #define PNG_GA_COLORMAP_ENTRIES 256
@@ -2043,11 +2067,11 @@ make_rgb_colormap(png_image_read_control *display)
 
          for (b=0; b<6; ++b)
             png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
-               P_sRGB);
+                P_sRGB);
       }
    }
 
-   return i;
+   return (int)i;
 }
 
 #define PNG_RGB_COLORMAP_ENTRIES 216
@@ -2061,11 +2085,11 @@ png_image_read_colormap(png_voidp argument)
 {
    png_image_read_control *display =
       png_voidcast(png_image_read_control*, argument);
-   const png_imagep image = display->image;
+   png_imagep image = display->image;
 
-   const png_structrp png_ptr = image->opaque->png_ptr;
-   const png_uint_32 output_format = image->format;
-   const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
+   png_structrp png_ptr = image->opaque->png_ptr;
+   png_uint_32 output_format = image->format;
+   int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
       P_LINEAR : P_sRGB;
 
    unsigned int cmap_entries;
@@ -2095,7 +2119,7 @@ png_image_read_colormap(png_voidp argument)
 
       else if (display->background == NULL /* no way to remove it */)
          png_error(png_ptr,
-            "a background color must be supplied to remove alpha/transparency");
+             "background color must be supplied to remove alpha/transparency");
 
       /* Get a copy of the background color (this avoids repeating the checks
        * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
@@ -2190,7 +2214,7 @@ png_image_read_colormap(png_voidp argument)
                 */
                if (i != trans)
                   png_create_colormap_entry(display, i, val, val, val, 255,
-                     P_FILE/*8-bit with file gamma*/);
+                      P_FILE/*8-bit with file gamma*/);
 
                /* Else this entry is transparent.  The colors don't matter if
                 * there is an alpha channel (back_alpha == 0), but it does no
@@ -2202,7 +2226,7 @@ png_image_read_colormap(png_voidp argument)
                 */
                else
                   png_create_colormap_entry(display, i, back_r, back_g, back_b,
-                     back_alpha, output_encoding);
+                      back_alpha, output_encoding);
             }
 
             /* We need libpng to preserve the original encoding. */
@@ -2240,7 +2264,7 @@ png_image_read_colormap(png_voidp argument)
             if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray[16] color-map: too few entries");
 
-            cmap_entries = make_gray_colormap(display);
+            cmap_entries = (unsigned int)make_gray_colormap(display);
 
             if (png_ptr->num_trans > 0)
             {
@@ -2267,7 +2291,7 @@ png_image_read_colormap(png_voidp argument)
                          * matches.
                          */
                         png_create_colormap_entry(display, gray, back_g, back_g,
-                           back_g, 65535, P_LINEAR);
+                            back_g, 65535, P_LINEAR);
                      }
 
                      /* The background passed to libpng, however, must be the
@@ -2281,8 +2305,8 @@ png_image_read_colormap(png_voidp argument)
                       * doesn't.
                       */
                      png_set_background_fixed(png_ptr, &c,
-                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                        0/*gamma: not used*/);
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                         0/*gamma: not used*/);
 
                      output_processing = PNG_CMAP_NONE;
                      break;
@@ -2312,7 +2336,7 @@ png_image_read_colormap(png_voidp argument)
                 * background color at full precision.
                 */
                png_create_colormap_entry(display, 254, back_r, back_g, back_b,
-                  back_alpha, output_encoding);
+                   back_alpha, output_encoding);
             }
 
             else
@@ -2338,7 +2362,7 @@ png_image_read_colormap(png_voidp argument)
             if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray+alpha color-map: too few entries");
 
-            cmap_entries = make_ga_colormap(display);
+            cmap_entries = (unsigned int)make_ga_colormap(display);
 
             background_index = PNG_CMAP_GA_BACKGROUND;
             output_processing = PNG_CMAP_GA;
@@ -2372,7 +2396,7 @@ png_image_read_colormap(png_voidp argument)
                if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "gray-alpha color-map: too few entries");
 
-               cmap_entries = make_gray_colormap(display);
+               cmap_entries = (unsigned int)make_gray_colormap(display);
 
                if (output_encoding == P_LINEAR)
                {
@@ -2380,7 +2404,7 @@ png_image_read_colormap(png_voidp argument)
 
                   /* And make sure the corresponding palette entry matches. */
                   png_create_colormap_entry(display, gray, back_g, back_g,
-                     back_g, 65535, P_LINEAR);
+                      back_g, 65535, P_LINEAR);
                }
 
                /* The background passed to libpng, however, must be the sRGB
@@ -2390,8 +2414,8 @@ png_image_read_colormap(png_voidp argument)
                c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
 
                png_set_background_fixed(png_ptr, &c,
-                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                  0/*gamma: not used*/);
+                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                   0/*gamma: not used*/);
 
                output_processing = PNG_CMAP_NONE;
             }
@@ -2411,7 +2435,7 @@ png_image_read_colormap(png_voidp argument)
                {
                   png_uint_32 gray = (i * 256 + 115) / 231;
                   png_create_colormap_entry(display, i++, gray, gray, gray,
-                     255, P_sRGB);
+                      255, P_sRGB);
                }
 
                /* NOTE: this preserves the full precision of the application
@@ -2420,13 +2444,13 @@ png_image_read_colormap(png_voidp argument)
                background_index = i;
                png_create_colormap_entry(display, i++, back_r, back_g, back_b,
 #ifdef __COVERITY__
-                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
-                  * here.
-                  */ 255U,
+                   /* Coverity claims that output_encoding
+                    * cannot be 2 (P_LINEAR) here.
+                    */ 255U,
 #else
-                  output_encoding == P_LINEAR ? 65535U : 255U,
+                    output_encoding == P_LINEAR ? 65535U : 255U,
 #endif
-                  output_encoding);
+                    output_encoding);
 
                /* For non-opaque input composite on the sRGB background - this
                 * requires inverting the encoding for each component.  The input
@@ -2464,9 +2488,9 @@ png_image_read_colormap(png_voidp argument)
                      png_uint_32 gray = png_sRGB_table[g*51] * alpha;
 
                      png_create_colormap_entry(display, i++,
-                        PNG_sRGB_FROM_LINEAR(gray + back_rx),
-                        PNG_sRGB_FROM_LINEAR(gray + back_gx),
-                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
+                         PNG_sRGB_FROM_LINEAR(gray + back_rx),
+                         PNG_sRGB_FROM_LINEAR(gray + back_gx),
+                         PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
                   }
                }
 
@@ -2492,7 +2516,7 @@ png_image_read_colormap(png_voidp argument)
              * png_set_tRNS_to_alpha before png_set_background_fixed.
              */
             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
-               -1);
+                -1);
             data_encoding = P_sRGB;
 
             /* The output will now be one or two 8-bit gray or gray+alpha
@@ -2511,7 +2535,7 @@ png_image_read_colormap(png_voidp argument)
                if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "rgb[ga] color-map: too few entries");
 
-               cmap_entries = make_ga_colormap(display);
+               cmap_entries = (unsigned int)make_ga_colormap(display);
                background_index = PNG_CMAP_GA_BACKGROUND;
                output_processing = PNG_CMAP_GA;
             }
@@ -2537,12 +2561,12 @@ png_image_read_colormap(png_voidp argument)
                   png_ptr->num_trans > 0) &&
                   png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)
                {
-                  cmap_entries = make_gray_file_colormap(display);
+                  cmap_entries = (unsigned int)make_gray_file_colormap(display);
                   data_encoding = P_FILE;
                }
 
                else
-                  cmap_entries = make_gray_colormap(display);
+                  cmap_entries = (unsigned int)make_gray_colormap(display);
 
                /* But if the input has alpha or transparency it must be removed
                 */
@@ -2568,13 +2592,13 @@ png_image_read_colormap(png_voidp argument)
                         gray = png_sRGB_table[gray]; /* now P_LINEAR */
 
                      gray = PNG_DIV257(png_gamma_16bit_correct(gray,
-                        png_ptr->colorspace.gamma)); /* now P_FILE */
+                         png_ptr->colorspace.gamma)); /* now P_FILE */
 
                      /* And make sure the corresponding palette entry contains
                       * exactly the required sRGB value.
                       */
                      png_create_colormap_entry(display, gray, back_g, back_g,
-                        back_g, 0/*unused*/, output_encoding);
+                         back_g, 0/*unused*/, output_encoding);
                   }
 
                   else if (output_encoding == P_LINEAR)
@@ -2599,8 +2623,8 @@ png_image_read_colormap(png_voidp argument)
                    */
                   expand_tRNS = 1;
                   png_set_background_fixed(png_ptr, &c,
-                     PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                     0/*gamma: not used*/);
+                      PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                      0/*gamma: not used*/);
                }
 
                output_processing = PNG_CMAP_NONE;
@@ -2630,11 +2654,11 @@ png_image_read_colormap(png_voidp argument)
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb+alpha color-map: too few entries");
 
-                  cmap_entries = make_rgb_colormap(display);
+                  cmap_entries = (unsigned int)make_rgb_colormap(display);
 
                   /* Add a transparent entry. */
                   png_create_colormap_entry(display, cmap_entries, 255, 255,
-                     255, 0, P_sRGB);
+                      255, 0, P_sRGB);
 
                   /* This is stored as the background index for the processing
                    * algorithm.
@@ -2655,7 +2679,7 @@ png_image_read_colormap(png_voidp argument)
                          */
                         for (b=0; b<256; b = (b << 1) | 0x7f)
                            png_create_colormap_entry(display, cmap_entries++,
-                              r, g, b, 128, P_sRGB);
+                               r, g, b, 128, P_sRGB);
                      }
                   }
 
@@ -2679,10 +2703,10 @@ png_image_read_colormap(png_voidp argument)
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb-alpha color-map: too few entries");
 
-                  cmap_entries = make_rgb_colormap(display);
+                  cmap_entries = (unsigned int)make_rgb_colormap(display);
 
                   png_create_colormap_entry(display, cmap_entries, back_r,
-                        back_g, back_b, 0/*unused*/, output_encoding);
+                      back_g, back_b, 0/*unused*/, output_encoding);
 
                   if (output_encoding == P_LINEAR)
                   {
@@ -2704,9 +2728,9 @@ png_image_read_colormap(png_voidp argument)
                    * index.
                    */
                   if (memcmp((png_const_bytep)display->colormap +
-                        sample_size * cmap_entries,
-                     (png_const_bytep)display->colormap +
-                        sample_size * PNG_RGB_INDEX(r,g,b),
+                      sample_size * cmap_entries,
+                      (png_const_bytep)display->colormap +
+                          sample_size * PNG_RGB_INDEX(r,g,b),
                      sample_size) != 0)
                   {
                      /* The background color must be added. */
@@ -2724,13 +2748,13 @@ png_image_read_colormap(png_voidp argument)
                             */
                            for (b=0; b<256; b = (b << 1) | 0x7f)
                               png_create_colormap_entry(display, cmap_entries++,
-                                 png_colormap_compose(display, r, P_sRGB, 128,
-                                    back_r, output_encoding),
-                                 png_colormap_compose(display, g, P_sRGB, 128,
-                                    back_g, output_encoding),
-                                 png_colormap_compose(display, b, P_sRGB, 128,
-                                    back_b, output_encoding),
-                                 0/*unused*/, output_encoding);
+                                  png_colormap_compose(display, r, P_sRGB, 128,
+                                      back_r, output_encoding),
+                                  png_colormap_compose(display, g, P_sRGB, 128,
+                                      back_g, output_encoding),
+                                  png_colormap_compose(display, b, P_sRGB, 128,
+                                      back_b, output_encoding),
+                                  0/*unused*/, output_encoding);
                         }
                      }
 
@@ -2748,8 +2772,8 @@ png_image_read_colormap(png_voidp argument)
                      c.blue = (png_uint_16)back_b;
 
                      png_set_background_fixed(png_ptr, &c,
-                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                        0/*gamma: not used*/);
+                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                         0/*gamma: not used*/);
 
                      output_processing = PNG_CMAP_RGB;
                   }
@@ -2764,7 +2788,7 @@ png_image_read_colormap(png_voidp argument)
                if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "rgb color-map: too few entries");
 
-               cmap_entries = make_rgb_colormap(display);
+               cmap_entries = (unsigned int)make_rgb_colormap(display);
                output_processing = PNG_CMAP_RGB;
             }
          }
@@ -2778,7 +2802,7 @@ png_image_read_colormap(png_voidp argument)
             unsigned int num_trans = png_ptr->num_trans;
             png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
             png_const_colorp colormap = png_ptr->palette;
-            const int do_background = trans != NULL &&
+            int do_background = trans != NULL &&
                (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
             unsigned int i;
 
@@ -2788,11 +2812,11 @@ png_image_read_colormap(png_voidp argument)
 
             output_processing = PNG_CMAP_NONE;
             data_encoding = P_FILE; /* Don't change from color-map indices */
-            cmap_entries = png_ptr->num_palette;
+            cmap_entries = (unsigned int)png_ptr->num_palette;
             if (cmap_entries > 256)
                cmap_entries = 256;
 
-            if (cmap_entries > image->colormap_entries)
+            if (cmap_entries > (unsigned int)image->colormap_entries)
                png_error(png_ptr, "palette color-map: too few entries");
 
             for (i=0; i < cmap_entries; ++i)
@@ -2801,7 +2825,7 @@ png_image_read_colormap(png_voidp argument)
                {
                   if (trans[i] == 0)
                      png_create_colormap_entry(display, i, back_r, back_g,
-                        back_b, 0, output_encoding);
+                         back_b, 0, output_encoding);
 
                   else
                   {
@@ -2809,22 +2833,22 @@ png_image_read_colormap(png_voidp argument)
                       * on the sRGB color in 'back'.
                       */
                      png_create_colormap_entry(display, i,
-                        png_colormap_compose(display, colormap[i].red, P_FILE,
-                           trans[i], back_r, output_encoding),
-                        png_colormap_compose(display, colormap[i].green, P_FILE,
-                           trans[i], back_g, output_encoding),
-                        png_colormap_compose(display, colormap[i].blue, P_FILE,
-                           trans[i], back_b, output_encoding),
-                        output_encoding == P_LINEAR ? trans[i] * 257U :
-                           trans[i],
-                        output_encoding);
+                         png_colormap_compose(display, colormap[i].red,
+                             P_FILE, trans[i], back_r, output_encoding),
+                         png_colormap_compose(display, colormap[i].green,
+                             P_FILE, trans[i], back_g, output_encoding),
+                         png_colormap_compose(display, colormap[i].blue,
+                             P_FILE, trans[i], back_b, output_encoding),
+                         output_encoding == P_LINEAR ? trans[i] * 257U :
+                             trans[i],
+                         output_encoding);
                   }
                }
 
                else
                   png_create_colormap_entry(display, i, colormap[i].red,
-                     colormap[i].green, colormap[i].blue,
-                     i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
+                      colormap[i].green, colormap[i].blue,
+                      i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
             }
 
             /* The PNG data may have indices packed in fewer than 8 bits, it
@@ -2850,7 +2874,7 @@ png_image_read_colormap(png_voidp argument)
       case P_sRGB:
          /* Change to 8-bit sRGB */
          png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
-         /* FALL THROUGH */
+         /* FALLTHROUGH */
 
       case P_FILE:
          if (png_ptr->bit_depth > 8)
@@ -2904,7 +2928,7 @@ png_image_read_colormap(png_voidp argument)
          png_error(png_ptr, "bad background index (internal error)");
    }
 
-   display->colormap_processing = output_processing;
+   display->colormap_processing = (int)output_processing;
 
    return 1/*ok*/;
 }
@@ -2914,7 +2938,7 @@ static int
 png_image_read_and_map(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    int passes;
@@ -3051,7 +3075,7 @@ png_image_read_and_map(png_voidp argument)
 
                      if (alpha >= 196)
                         *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
-                           inrow[2]);
+                            inrow[2]);
 
                      else if (alpha < 64)
                         *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
@@ -3103,7 +3127,7 @@ static int
 png_image_read_colormapped(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_controlp control = image->opaque;
    png_structrp png_ptr = control->png_ptr;
@@ -3168,8 +3192,7 @@ png_image_read_colormapped(png_voidp argument)
             image->colormap_entries == 244 /* 216 + 1 + 27 */)
             break;
 
-         /* goto bad_output; */
-         /* FALL THROUGH */
+         goto bad_output;
 
       default:
       bad_output:
@@ -3213,14 +3236,14 @@ png_image_read_colormapped(png_voidp argument)
 
    else
    {
-      png_alloc_size_t row_bytes = display->row_bytes;
+      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
 
       while (--passes >= 0)
       {
          png_uint_32      y = image->height;
          png_bytep        row = png_voidcast(png_bytep, display->first_row);
 
-         while (y-- > 0)
+         for (; y > 0; --y)
          {
             png_read_row(png_ptr, row, NULL);
             row += row_bytes;
@@ -3236,7 +3259,7 @@ static int
 png_image_read_composite(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    int passes;
@@ -3363,7 +3386,7 @@ static int
 png_image_read_background(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -3423,8 +3446,7 @@ png_image_read_background(png_voidp argument)
 
             for (pass = 0; pass < passes; ++pass)
             {
-               png_bytep        row = png_voidcast(png_bytep,
-                                                   display->first_row);
+               png_bytep row = png_voidcast(png_bytep, display->first_row);
                unsigned int     startx, stepx, stepy;
                png_uint_32      y;
 
@@ -3452,7 +3474,7 @@ png_image_read_background(png_voidp argument)
                   for (; y<height; y += stepy)
                   {
                      png_bytep inrow = png_voidcast(png_bytep,
-                        display->local_row);
+                         display->local_row);
                      png_bytep outrow = first_row + y * step_row;
                      png_const_bytep end_row = outrow + width;
 
@@ -3497,7 +3519,7 @@ png_image_read_background(png_voidp argument)
                   for (; y<height; y += stepy)
                   {
                      png_bytep inrow = png_voidcast(png_bytep,
-                        display->local_row);
+                         display->local_row);
                      png_bytep outrow = first_row + y * step_row;
                      png_const_bytep end_row = outrow + width;
 
@@ -3544,13 +3566,14 @@ png_image_read_background(png_voidp argument)
           */
          {
             png_uint_16p first_row = png_voidcast(png_uint_16p,
-               display->first_row);
+                display->first_row);
             /* The division by two is safe because the caller passed in a
              * stride which was multiplied by 2 (below) to get row_bytes.
              */
             ptrdiff_t    step_row = display->row_bytes / 2;
-            int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
-            unsigned int outchannels = 1+preserve_alpha;
+            unsigned int preserve_alpha = (image->format &
+                PNG_FORMAT_FLAG_ALPHA) != 0;
+            unsigned int outchannels = 1U+preserve_alpha;
             int swap_alpha = 0;
 
 #           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
@@ -3594,7 +3617,7 @@ png_image_read_background(png_voidp argument)
 
                   /* Read the row, which is packed: */
                   png_read_row(png_ptr, png_voidcast(png_bytep,
-                     display->local_row), NULL);
+                      display->local_row), NULL);
                   inrow = png_voidcast(png_const_uint_16p, display->local_row);
 
                   /* Now do the pre-multiplication on each pixel in this row.
@@ -3643,7 +3666,7 @@ static int
 png_image_read_direct(png_voidp argument)
 {
    png_image_read_control *display = png_voidcast(png_image_read_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -3694,7 +3717,7 @@ png_image_read_direct(png_voidp argument)
                do_local_background = 1/*maybe*/;
 
             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
-               PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+                PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
          }
 
          change &= ~PNG_FORMAT_FLAG_COLOR;
@@ -3736,7 +3759,13 @@ png_image_read_direct(png_voidp argument)
          mode = PNG_ALPHA_PNG;
          output_gamma = PNG_DEFAULT_sRGB;
       }
-
+      
+      if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0)
+      {
+         mode = PNG_ALPHA_OPTIMIZED;
+         change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+      }
+      
       /* If 'do_local_background' is set check for the presence of gamma
        * correction; this is part of the work-round for the libpng bug
        * described above.
@@ -3753,7 +3782,7 @@ png_image_read_direct(png_voidp argument)
           * final value.
           */
          if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
-               PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
+             PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
             do_local_background = 0;
 
          else if (mode == PNG_ALPHA_STANDARD)
@@ -3816,8 +3845,8 @@ png_image_read_direct(png_voidp argument)
                 * pixels.
                 */
                png_set_background_fixed(png_ptr, &c,
-                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
-                  0/*gamma: not used*/);
+                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+                   0/*gamma: not used*/);
             }
 
             else /* compose on row: implemented below. */
@@ -3848,16 +3877,16 @@ png_image_read_direct(png_voidp argument)
             else
                filler = 255;
 
-#           ifdef PNG_FORMAT_AFIRST_SUPPORTED
-               if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
-               {
-                  where = PNG_FILLER_BEFORE;
-                  change &= ~PNG_FORMAT_FLAG_AFIRST;
-               }
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+            if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+            {
+               where = PNG_FILLER_BEFORE;
+               change &= ~PNG_FORMAT_FLAG_AFIRST;
+            }
 
-               else
-#           endif
-               where = PNG_FILLER_AFTER;
+            else
+#endif
+            where = PNG_FILLER_AFTER;
 
             png_set_add_alpha(png_ptr, filler, where);
          }
@@ -3917,7 +3946,7 @@ png_image_read_direct(png_voidp argument)
        */
       if (linear != 0)
       {
-         PNG_CONST png_uint_16 le = 0x0001;
+         png_uint_16 le = 0x0001;
 
          if ((*(png_const_bytep) & le) != 0)
             png_set_swap(png_ptr);
@@ -3962,15 +3991,19 @@ png_image_read_direct(png_voidp argument)
       else if (do_local_compose != 0) /* internal error */
          png_error(png_ptr, "png_image_read: alpha channel lost");
 
+      if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) {
+         info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+      }
+
       if (info_ptr->bit_depth == 16)
          info_format |= PNG_FORMAT_FLAG_LINEAR;
 
-#     ifdef PNG_FORMAT_BGR_SUPPORTED
-         if ((png_ptr->transformations & PNG_BGR) != 0)
-            info_format |= PNG_FORMAT_FLAG_BGR;
-#     endif
+#ifdef PNG_FORMAT_BGR_SUPPORTED
+      if ((png_ptr->transformations & PNG_BGR) != 0)
+         info_format |= PNG_FORMAT_FLAG_BGR;
+#endif
 
-#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
          if (do_local_background == 2)
          {
             if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
@@ -4047,14 +4080,14 @@ png_image_read_direct(png_voidp argument)
 
    else
    {
-      png_alloc_size_t row_bytes = display->row_bytes;
+      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
 
       while (--passes >= 0)
       {
          png_uint_32      y = image->height;
          png_bytep        row = png_voidcast(png_bytep, display->first_row);
 
-         while (y-- > 0)
+         for (; y > 0; --y)
          {
             png_read_row(png_ptr, row, NULL);
             row += row_bytes;
@@ -4067,67 +4100,117 @@ png_image_read_direct(png_voidp argument)
 
 int PNGAPI
 png_image_finish_read(png_imagep image, png_const_colorp background,
-   void *buffer, png_int_32 row_stride, void *colormap)
+    void *buffer, png_int_32 row_stride, void *colormap)
 {
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
-      png_uint_32 check;
+      /* Check for row_stride overflow.  This check is not performed on the
+       * original PNG format because it may not occur in the output PNG format
+       * and libpng deals with the issues of reading the original.
+       */
+      unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
+
+      /* The following checks just the 'row_stride' calculation to ensure it
+       * fits in a signed 32-bit value.  Because channels/components can be
+       * either 1 or 2 bytes in size the length of a row can still overflow 32
+       * bits; this is just to verify that the 'row_stride' argument can be
+       * represented.
+       */
+      if (image->width <= 0x7fffffffU/channels) /* no overflow */
+      {
+         png_uint_32 check;
+         png_uint_32 png_row_stride = image->width * channels;
 
-      if (row_stride == 0)
-         row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+         if (row_stride == 0)
+            row_stride = (png_int_32)/*SAFE*/png_row_stride;
 
-      if (row_stride < 0)
-         check = -row_stride;
+         if (row_stride < 0)
+            check = (png_uint_32)(-row_stride);
 
-      else
-         check = row_stride;
+         else
+            check = (png_uint_32)row_stride;
 
-      if (image->opaque != NULL && buffer != NULL &&
-         check >= PNG_IMAGE_ROW_STRIDE(*image))
-      {
-         if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
-            (image->colormap_entries > 0 && colormap != NULL))
+         /* This verifies 'check', the absolute value of the actual stride
+          * passed in and detects overflow in the application calculation (i.e.
+          * if the app did actually pass in a non-zero 'row_stride'.
+          */
+         if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
          {
-            int result;
-            png_image_read_control display;
-
-            memset(&display, 0, (sizeof display));
-            display.image = image;
-            display.buffer = buffer;
-            display.row_stride = row_stride;
-            display.colormap = colormap;
-            display.background = background;
-            display.local_row = NULL;
-
-            /* Choose the correct 'end' routine; for the color-map case all the
-             * setup has already been done.
+            /* Now check for overflow of the image buffer calculation; this
+             * limits the whole image size to 32 bits for API compatibility with
+             * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+             *
+             * The PNG_IMAGE_BUFFER_SIZE macro is:
+             *
+             *    (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))
+             *
+             * And the component size is always 1 or 2, so make sure that the
+             * number of *bytes* that the application is saying are available
+             * does actually fit into a 32-bit number.
+             *
+             * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE
+             * will be changed to use png_alloc_size_t; bigger images can be
+             * accommodated on 64-bit systems.
              */
-            if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
-               result =
-                  png_safe_execute(image, png_image_read_colormap, &display) &&
-                  png_safe_execute(image, png_image_read_colormapped, &display);
+            if (image->height <=
+                0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check)
+            {
+               if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
+                  (image->colormap_entries > 0 && colormap != NULL))
+               {
+                  int result;
+                  png_image_read_control display;
+
+                  memset(&display, 0, (sizeof display));
+                  display.image = image;
+                  display.buffer = buffer;
+                  display.row_stride = row_stride;
+                  display.colormap = colormap;
+                  display.background = background;
+                  display.local_row = NULL;
+
+                  /* Choose the correct 'end' routine; for the color-map case
+                   * all the setup has already been done.
+                   */
+                  if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
+                     result =
+                         png_safe_execute(image,
+                             png_image_read_colormap, &display) &&
+                             png_safe_execute(image,
+                             png_image_read_colormapped, &display);
 
-            else
-               result =
-                  png_safe_execute(image, png_image_read_direct, &display);
+                  else
+                     result =
+                        png_safe_execute(image,
+                            png_image_read_direct, &display);
+
+                  png_image_free(image);
+                  return result;
+               }
 
-            png_image_free(image);
-            return result;
+               else
+                  return png_image_error(image,
+                      "png_image_finish_read[color-map]: no color-map");
+            }
+
+            else
+               return png_image_error(image,
+                   "png_image_finish_read: image too large");
          }
 
          else
             return png_image_error(image,
-               "png_image_finish_read[color-map]: no color-map");
+                "png_image_finish_read: invalid argument");
       }
 
       else
          return png_image_error(image,
-            "png_image_finish_read: invalid argument");
+             "png_image_finish_read: row_stride too large");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_finish_read: damaged PNG_IMAGE_VERSION");
+          "png_image_finish_read: damaged PNG_IMAGE_VERSION");
 
    return 0;
 }
index 5101d54..7946358 100644 (file)
--- a/pngrio.c
+++ b/pngrio.c
@@ -1,10 +1,10 @@
 
 /* pngrio.c - functions for data input
  *
- * Last changed in libpng 1.6.17 [March 26, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -29,7 +29,7 @@
  * to read more than 64K on a 16-bit machine.
  */
 void /* PRIVATE */
-png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
+png_read_data(png_structrp png_ptr, png_bytep data, size_t length)
 {
    png_debug1(4, "reading %d bytes", (int)length);
 
@@ -47,14 +47,14 @@ png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
  * than changing the library.
  */
 void PNGCBAPI
-png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+png_default_read_data(png_structp png_ptr, png_bytep data, size_t length)
 {
-   png_size_t check;
+   size_t check;
 
    if (png_ptr == NULL)
       return;
 
-   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+   /* fread() returns 0 on error, so it is OK to store this in a size_t
     * instead of an int, which is what fread() actually returns.
     */
    check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
@@ -85,7 +85,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  */
 void PNGAPI
 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)
       return;
index e233178..ccc58ce 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
 
 #include "pngpriv.h"
 
+#ifdef PNG_ARM_NEON_IMPLEMENTATION
+#  if PNG_ARM_NEON_IMPLEMENTATION == 1
+#    define PNG_ARM_NEON_INTRINSICS_AVAILABLE
+#    if defined(_MSC_VER) && defined(_M_ARM64)
+#      include <arm64_neon.h>
+#    else
+#      include <arm_neon.h>
+#    endif
+#  endif
+#endif
+
 #ifdef PNG_READ_SUPPORTED
 
 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
@@ -48,7 +59,8 @@ png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
 
       case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
          png_warning(png_ptr,
-            "Can't discard critical data on CRC error");
+             "Can't discard critical data on CRC error");
+         /* FALLTHROUGH */
       case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
 
       case PNG_CRC_DEFAULT:
@@ -101,7 +113,7 @@ png_rtran_ok(png_structrp png_ptr, int need_IHDR)
    {
       if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
          png_app_error(png_ptr,
-            "invalid after png_start_read_image or png_read_update_info");
+             "invalid after png_start_read_image or png_read_update_info");
 
       else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
          png_app_error(png_ptr, "invalid before the PNG header has been read");
@@ -159,7 +171,7 @@ png_set_background(png_structrp png_ptr,
    png_set_background_fixed(png_ptr, background_color, background_gamma_code,
       need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
 }
-#  endif  /* FLOATING_POINT */
+#  endif /* FLOATING_POINT */
 #endif /* READ_BACKGROUND */
 
 /* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
@@ -209,7 +221,7 @@ png_set_strip_alpha(png_structrp png_ptr)
 #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
 static png_fixed_point
 translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
-   int is_screen)
+    int is_screen)
 {
    /* Check for flag values.  The main reason for having the old Mac value as a
     * flag is that it is pretty near impossible to work out what the correct
@@ -273,7 +285,7 @@ convert_gamma_value(png_structrp png_ptr, double output_gamma)
 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
 void PNGFAPI
 png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
-   png_fixed_point output_gamma)
+    png_fixed_point output_gamma)
 {
    int compose = 0;
    png_fixed_point file_gamma;
@@ -289,9 +301,12 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
     * is expected to be 1 or greater, but this range test allows for some
     * viewing correction values.  The intent is to weed out users of this API
     * who use the inverse of the gamma value accidentally!  Since some of these
-    * values are reasonable this may have to be changed.
+    * values are reasonable this may have to be changed:
+    *
+    * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit
+    * gamma of 36, and its reciprocal.)
     */
-   if (output_gamma < 70000 || output_gamma > 300000)
+   if (output_gamma < 1000 || output_gamma > 10000000)
       png_error(png_ptr, "output gamma out of expected range");
 
    /* The default file gamma is the inverse of the output gamma; the output
@@ -374,7 +389,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
 
       if ((png_ptr->transformations & PNG_COMPOSE) != 0)
          png_error(png_ptr,
-            "conflicting calls to set alpha mode and background");
+             "conflicting calls to set alpha mode and background");
 
       png_ptr->transformations |= PNG_COMPOSE;
    }
@@ -385,7 +400,7 @@ void PNGAPI
 png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
 {
    png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
-      output_gamma));
+       output_gamma));
 }
 #  endif
 #endif
@@ -426,7 +441,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
       int i;
 
       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
-          (png_uint_32)(num_palette * (sizeof (png_byte))));
+          (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
       for (i = 0; i < num_palette; i++)
          png_ptr->quantize_index[i] = (png_byte)i;
    }
@@ -443,7 +458,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
 
          /* Initialize an array to sort colors */
          png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * (sizeof (png_byte))));
+             (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
 
          /* Initialize the quantize_sort array */
          for (i = 0; i < num_palette; i++)
@@ -577,9 +592,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
 
          /* Initialize palette index arrays */
          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * (sizeof (png_byte))));
+             (png_alloc_size_t)((png_uint_32)num_palette *
+             (sizeof (png_byte))));
          png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)(num_palette * (sizeof (png_byte))));
+             (png_alloc_size_t)((png_uint_32)num_palette *
+             (sizeof (png_byte))));
 
          /* Initialize the sort array */
          for (i = 0; i < num_palette; i++)
@@ -588,7 +605,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
             png_ptr->palette_to_index[i] = (png_byte)i;
          }
 
-         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
+         hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
              (sizeof (png_dsortp))));
 
          num_new_palette = num_palette;
@@ -619,7 +636,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
                   {
 
                      t = (png_dsortp)png_malloc_warn(png_ptr,
-                         (png_uint_32)(sizeof (png_dsort)));
+                         (png_alloc_size_t)(sizeof (png_dsort)));
 
                      if (t == NULL)
                          break;
@@ -741,12 +758,12 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
       int num_red = (1 << PNG_QUANTIZE_RED_BITS);
       int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
       int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
-      png_size_t num_entries = ((png_size_t)1 << total_bits);
+      size_t num_entries = ((size_t)1 << total_bits);
 
       png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
-          (png_uint_32)(num_entries * (sizeof (png_byte))));
+          (png_alloc_size_t)(num_entries * (sizeof (png_byte))));
 
-      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+      distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
           (sizeof (png_byte))));
 
       memset(distance, 0xff, num_entries * (sizeof (png_byte)));
@@ -799,7 +816,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
 #ifdef PNG_READ_GAMMA_SUPPORTED
 void PNGFAPI
 png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
-   png_fixed_point file_gamma)
+    png_fixed_point file_gamma)
 {
    png_debug(1, "in png_set_gamma_fixed");
 
@@ -841,7 +858,7 @@ void PNGAPI
 png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
 {
    png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
-      convert_gamma_value(png_ptr, file_gamma));
+       convert_gamma_value(png_ptr, file_gamma));
 }
 #  endif /* FLOATING_POINT */
 #endif /* READ_GAMMA */
@@ -987,7 +1004,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
        * that it just worked and get a memory overwrite.
        */
       png_error(png_ptr,
-        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
+          "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
 
       /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
    }
@@ -1014,7 +1031,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
       {
          if (red >= 0 && green >= 0)
             png_app_warning(png_ptr,
-               "ignoring out of range rgb_to_gray coefficients");
+                "ignoring out of range rgb_to_gray coefficients");
 
          /* Use the defaults, from the cHRM chunk if set, else the historical
           * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
@@ -1023,7 +1040,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
           * something has already provided a default.
           */
          if (png_ptr->rgb_to_gray_red_coeff == 0 &&
-            png_ptr->rgb_to_gray_green_coeff == 0)
+             png_ptr->rgb_to_gray_green_coeff == 0)
          {
             png_ptr->rgb_to_gray_red_coeff   = 6968;
             png_ptr->rgb_to_gray_green_coeff = 23434;
@@ -1040,10 +1057,10 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
 
 void PNGAPI
 png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
-   double green)
+    double green)
 {
    png_set_rgb_to_gray_fixed(png_ptr, error_action,
-      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
+       png_fixed(png_ptr, red, "rgb to gray red coefficient"),
       png_fixed(png_ptr, green, "rgb to gray green coefficient"));
 }
 #endif /* FLOATING POINT */
@@ -1250,7 +1267,7 @@ png_init_rgb_transformations(png_structrp png_ptr)
             default:
 
             case 8:
-               /* FALL THROUGH (Already 8 bits) */
+               /* FALLTHROUGH */ /*  (Already 8 bits) */
 
             case 16:
                /* Already a full 16 bits */
@@ -1300,7 +1317,7 @@ png_init_read_transformations(png_structrp png_ptr)
       {
          if (png_ptr->screen_gamma != 0) /* screen set too */
             gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
-               png_ptr->screen_gamma);
+                png_ptr->screen_gamma);
 
          else
             /* Assume the output matches the input; a long time default behavior
@@ -1311,7 +1328,7 @@ png_init_read_transformations(png_structrp png_ptr)
 
       else if (png_ptr->screen_gamma != 0)
          /* The converse - assume the file matches the screen, note that this
-          * perhaps undesireable default can (from 1.5.4) be changed by calling
+          * perhaps undesirable default can (from 1.5.4) be changed by calling
           * png_set_alpha_mode (even if the alpha handling mode isn't required
           * or isn't changed from the default.)
           */
@@ -1581,7 +1598,7 @@ png_init_read_transformations(png_structrp png_ptr)
           */
          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
             png_warning(png_ptr,
-               "libpng does not support gamma+background+rgb_to_gray");
+                "libpng does not support gamma+background+rgb_to_gray");
 
          if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
          {
@@ -1617,13 +1634,13 @@ png_init_read_transformations(png_structrp png_ptr)
                   case PNG_BACKGROUND_GAMMA_FILE:
                      g = png_reciprocal(png_ptr->colorspace.gamma);
                      gs = png_reciprocal2(png_ptr->colorspace.gamma,
-                        png_ptr->screen_gamma);
+                         png_ptr->screen_gamma);
                      break;
 
                   case PNG_BACKGROUND_GAMMA_UNIQUE:
                      g = png_reciprocal(png_ptr->background_gamma);
                      gs = png_reciprocal2(png_ptr->background_gamma,
-                        png_ptr->screen_gamma);
+                         png_ptr->screen_gamma);
                      break;
                   default:
                      g = PNG_FP_1;    /* back_1 */
@@ -1651,11 +1668,11 @@ png_init_read_transformations(png_structrp png_ptr)
                if (png_gamma_significant(g) != 0)
                {
                   back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
-                     g);
+                      g);
                   back_1.green = png_gamma_8bit_correct(
-                     png_ptr->background.green, g);
+                      png_ptr->background.green, g);
                   back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
-                     g);
+                      g);
                }
 
                else
@@ -1726,7 +1743,7 @@ png_init_read_transformations(png_structrp png_ptr)
                case PNG_BACKGROUND_GAMMA_FILE:
                   g = png_reciprocal(png_ptr->colorspace.gamma);
                   gs = png_reciprocal2(png_ptr->colorspace.gamma,
-                     png_ptr->screen_gamma);
+                      png_ptr->screen_gamma);
                   break;
 
                case PNG_BACKGROUND_GAMMA_UNIQUE:
@@ -1879,7 +1896,7 @@ png_init_read_transformations(png_structrp png_ptr)
 
       png_ptr->transformations &= ~PNG_SHIFT;
 
-      /* significant bits can be in the range 1 to 7 for a meaninful result, if
+      /* significant bits can be in the range 1 to 7 for a meaningful result, if
        * the number of significant bits is 0 then no shift is done (this is an
        * error condition which is silently ignored.)
        */
@@ -1912,7 +1929,7 @@ png_init_read_transformations(png_structrp png_ptr)
             png_ptr->palette[i].blue = (png_byte)component;
          }
    }
-#endif  /* READ_SHIFT */
+#endif /* READ_SHIFT */
 }
 
 /* Modify the info structure to reflect the transformations.  The
@@ -2145,9 +2162,9 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
       {
          case 1:
          {
-            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
-            png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+            png_bytep sp = row + (size_t)((row_width - 1) >> 3);
+            png_bytep dp = row + (size_t)row_width - 1;
+            png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
             for (i = 0; i < row_width; i++)
             {
                *dp = (png_byte)((*sp >> shift) & 0x01);
@@ -2169,9 +2186,9 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
          case 2:
          {
 
-            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
-            png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+            png_bytep sp = row + (size_t)((row_width - 1) >> 2);
+            png_bytep dp = row + (size_t)row_width - 1;
+            png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
             for (i = 0; i < row_width; i++)
             {
                *dp = (png_byte)((*sp >> shift) & 0x03);
@@ -2192,9 +2209,9 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
 
          case 4:
          {
-            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
-            png_bytep dp = row + (png_size_t)row_width - 1;
-            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+            png_bytep sp = row + (size_t)((row_width - 1) >> 1);
+            png_bytep dp = row + (size_t)row_width - 1;
+            png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
             for (i = 0; i < row_width; i++)
             {
                *dp = (png_byte)((*sp >> shift) & 0x0f);
@@ -2457,95 +2474,94 @@ png_do_chop(png_row_infop row_info, png_bytep row)
 static void
 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
 {
+   png_uint_32 row_width = row_info->width;
+
    png_debug(1, "in png_do_read_swap_alpha");
 
+   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    {
-      png_uint_32 row_width = row_info->width;
-      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+      /* This converts from RGBA to ARGB */
+      if (row_info->bit_depth == 8)
       {
-         /* This converts from RGBA to ARGB */
-         if (row_info->bit_depth == 8)
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save;
-            png_uint_32 i;
+         png_bytep sp = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_byte save;
+         png_uint_32 i;
 
-            for (i = 0; i < row_width; i++)
-            {
-               save = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save;
-            }
+         for (i = 0; i < row_width; i++)
+         {
+            save = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = save;
          }
+      }
 
 #ifdef PNG_READ_16BIT_SUPPORTED
-         /* This converts from RRGGBBAA to AARRGGBB */
-         else
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save[2];
-            png_uint_32 i;
+      /* This converts from RRGGBBAA to AARRGGBB */
+      else
+      {
+         png_bytep sp = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_byte save[2];
+         png_uint_32 i;
 
-            for (i = 0; i < row_width; i++)
-            {
-               save[0] = *(--sp);
-               save[1] = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save[0];
-               *(--dp) = save[1];
-            }
+         for (i = 0; i < row_width; i++)
+         {
+            save[0] = *(--sp);
+            save[1] = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = save[0];
+            *(--dp) = save[1];
          }
-#endif
       }
+#endif
+   }
 
-      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+   {
+      /* This converts from GA to AG */
+      if (row_info->bit_depth == 8)
       {
-         /* This converts from GA to AG */
-         if (row_info->bit_depth == 8)
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save;
-            png_uint_32 i;
+         png_bytep sp = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_byte save;
+         png_uint_32 i;
 
-            for (i = 0; i < row_width; i++)
-            {
-               save = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save;
-            }
+         for (i = 0; i < row_width; i++)
+         {
+            save = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = save;
          }
+      }
 
 #ifdef PNG_READ_16BIT_SUPPORTED
-         /* This converts from GGAA to AAGG */
-         else
-         {
-            png_bytep sp = row + row_info->rowbytes;
-            png_bytep dp = sp;
-            png_byte save[2];
-            png_uint_32 i;
+      /* This converts from GGAA to AAGG */
+      else
+      {
+         png_bytep sp = row + row_info->rowbytes;
+         png_bytep dp = sp;
+         png_byte save[2];
+         png_uint_32 i;
 
-            for (i = 0; i < row_width; i++)
-            {
-               save[0] = *(--sp);
-               save[1] = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = *(--sp);
-               *(--dp) = save[0];
-               *(--dp) = save[1];
-            }
+         for (i = 0; i < row_width; i++)
+         {
+            save[0] = *(--sp);
+            save[1] = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = *(--sp);
+            *(--dp) = save[0];
+            *(--dp) = save[1];
          }
-#endif
       }
+#endif
    }
 }
 #endif
@@ -2675,8 +2691,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
          {
             /* This changes the data from G to GX */
-            png_bytep sp = row + (png_size_t)row_width;
-            png_bytep dp =  sp + (png_size_t)row_width;
+            png_bytep sp = row + (size_t)row_width;
+            png_bytep dp =  sp + (size_t)row_width;
             for (i = 1; i < row_width; i++)
             {
                *(--dp) = lo_filler;
@@ -2691,8 +2707,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          else
          {
             /* This changes the data from G to XG */
-            png_bytep sp = row + (png_size_t)row_width;
-            png_bytep dp = sp  + (png_size_t)row_width;
+            png_bytep sp = row + (size_t)row_width;
+            png_bytep dp = sp  + (size_t)row_width;
             for (i = 0; i < row_width; i++)
             {
                *(--dp) = *(--sp);
@@ -2710,8 +2726,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
          {
             /* This changes the data from GG to GGXX */
-            png_bytep sp = row + (png_size_t)row_width * 2;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            png_bytep sp = row + (size_t)row_width * 2;
+            png_bytep dp = sp  + (size_t)row_width * 2;
             for (i = 1; i < row_width; i++)
             {
                *(--dp) = lo_filler;
@@ -2729,8 +2745,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          else
          {
             /* This changes the data from GG to XXGG */
-            png_bytep sp = row + (png_size_t)row_width * 2;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            png_bytep sp = row + (size_t)row_width * 2;
+            png_bytep dp = sp  + (size_t)row_width * 2;
             for (i = 0; i < row_width; i++)
             {
                *(--dp) = *(--sp);
@@ -2752,8 +2768,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
          {
             /* This changes the data from RGB to RGBX */
-            png_bytep sp = row + (png_size_t)row_width * 3;
-            png_bytep dp = sp  + (png_size_t)row_width;
+            png_bytep sp = row + (size_t)row_width * 3;
+            png_bytep dp = sp  + (size_t)row_width;
             for (i = 1; i < row_width; i++)
             {
                *(--dp) = lo_filler;
@@ -2770,8 +2786,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          else
          {
             /* This changes the data from RGB to XRGB */
-            png_bytep sp = row + (png_size_t)row_width * 3;
-            png_bytep dp = sp + (png_size_t)row_width;
+            png_bytep sp = row + (size_t)row_width * 3;
+            png_bytep dp = sp + (size_t)row_width;
             for (i = 0; i < row_width; i++)
             {
                *(--dp) = *(--sp);
@@ -2791,8 +2807,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
          {
             /* This changes the data from RRGGBB to RRGGBBXX */
-            png_bytep sp = row + (png_size_t)row_width * 6;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            png_bytep sp = row + (size_t)row_width * 6;
+            png_bytep dp = sp  + (size_t)row_width * 2;
             for (i = 1; i < row_width; i++)
             {
                *(--dp) = lo_filler;
@@ -2814,8 +2830,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
          else
          {
             /* This changes the data from RRGGBB to XXRRGGBB */
-            png_bytep sp = row + (png_size_t)row_width * 6;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            png_bytep sp = row + (size_t)row_width * 6;
+            png_bytep dp = sp  + (size_t)row_width * 2;
             for (i = 0; i < row_width; i++)
             {
                *(--dp) = *(--sp);
@@ -2856,8 +2872,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
          if (row_info->bit_depth == 8)
          {
             /* This changes G to RGB */
-            png_bytep sp = row + (png_size_t)row_width - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            png_bytep sp = row + (size_t)row_width - 1;
+            png_bytep dp = sp  + (size_t)row_width * 2;
             for (i = 0; i < row_width; i++)
             {
                *(dp--) = *sp;
@@ -2869,8 +2885,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
          else
          {
             /* This changes GG to RRGGBB */
-            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            png_bytep sp = row + (size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (size_t)row_width * 4;
             for (i = 0; i < row_width; i++)
             {
                *(dp--) = *sp;
@@ -2888,8 +2904,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
          if (row_info->bit_depth == 8)
          {
             /* This changes GA to RGBA */
-            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 2;
+            png_bytep sp = row + (size_t)row_width * 2 - 1;
+            png_bytep dp = sp  + (size_t)row_width * 2;
             for (i = 0; i < row_width; i++)
             {
                *(dp--) = *(sp--);
@@ -2902,8 +2918,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
          else
          {
             /* This changes GGAA to RRGGBBAA */
-            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
-            png_bytep dp = sp  + (png_size_t)row_width * 4;
+            png_bytep sp = row + (size_t)row_width * 4 - 1;
+            png_bytep dp = sp  + (size_t)row_width * 4;
             for (i = 0; i < row_width; i++)
             {
                *(dp--) = *(sp--);
@@ -2931,7 +2947,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
  * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
  * versions dated 1998 through November 2002 have been archived at
- * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
+ * https://web.archive.org/web/20000816232553/www.inforamp.net/
  * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
  * Charles Poynton poynton at poynton.com
  *
@@ -2974,14 +2990,13 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  *  values this results in an implicit assumption that the original PNG RGB
  *  values were linear.
  *
- *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
+ *  Other integer coefficients can be used via png_set_rgb_to_gray().  Because
  *  the API takes just red and green coefficients the blue coefficient is
  *  calculated to make the sum 32768.  This will result in different rounding
  *  to that used above.
  */
 static int
 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
-
 {
    int rgb_error = 0;
 
@@ -2990,12 +3005,11 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
    if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
        (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
    {
-      PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
-      PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
-      PNG_CONST png_uint_32 bc = 32768 - rc - gc;
-      PNG_CONST png_uint_32 row_width = row_info->width;
-      PNG_CONST int have_alpha =
-         (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+      png_uint_32 bc = 32768 - rc - gc;
+      png_uint_32 row_width = row_info->width;
+      int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
 
       if (row_info->bit_depth == 8)
       {
@@ -3203,715 +3217,718 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
 
    png_debug(1, "in png_do_compose");
 
+   switch (row_info->color_type)
    {
-      switch (row_info->color_type)
+      case PNG_COLOR_TYPE_GRAY:
       {
-         case PNG_COLOR_TYPE_GRAY:
+         switch (row_info->bit_depth)
          {
-            switch (row_info->bit_depth)
+            case 1:
+            {
+               sp = row;
+               shift = 7;
+               for (i = 0; i < row_width; i++)
+               {
+                  if ((png_uint_16)((*sp >> shift) & 0x01)
+                     == png_ptr->trans_color.gray)
+                  {
+                     unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
+                     tmp |=
+                         (unsigned int)(png_ptr->background.gray << shift);
+                     *sp = (png_byte)(tmp & 0xff);
+                  }
+
+                  if (shift == 0)
+                  {
+                     shift = 7;
+                     sp++;
+                  }
+
+                  else
+                     shift--;
+               }
+               break;
+            }
+
+            case 2:
             {
-               case 1:
+#ifdef PNG_READ_GAMMA_SUPPORTED
+               if (gamma_table != NULL)
                {
                   sp = row;
-                  shift = 7;
+                  shift = 6;
                   for (i = 0; i < row_width; i++)
                   {
-                     if ((png_uint_16)((*sp >> shift) & 0x01)
-                        == png_ptr->trans_color.gray)
+                     if ((png_uint_16)((*sp >> shift) & 0x03)
+                         == png_ptr->trans_color.gray)
                      {
-                        unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
-                        tmp |= png_ptr->background.gray << shift;
+                        unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+                        tmp |=
+                           (unsigned int)png_ptr->background.gray << shift;
+                        *sp = (png_byte)(tmp & 0xff);
+                     }
+
+                     else
+                     {
+                        unsigned int p = (*sp >> shift) & 0x03;
+                        unsigned int g = (gamma_table [p | (p << 2) |
+                            (p << 4) | (p << 6)] >> 6) & 0x03;
+                        unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+                        tmp |= (unsigned int)(g << shift);
                         *sp = (png_byte)(tmp & 0xff);
                      }
 
                      if (shift == 0)
                      {
-                        shift = 7;
+                        shift = 6;
                         sp++;
                      }
 
                      else
-                        shift--;
+                        shift -= 2;
                   }
-                  break;
                }
 
-               case 2:
+               else
+#endif
                {
-#ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_table != NULL)
+                  sp = row;
+                  shift = 6;
+                  for (i = 0; i < row_width; i++)
                   {
-                     sp = row;
-                     shift = 6;
-                     for (i = 0; i < row_width; i++)
+                     if ((png_uint_16)((*sp >> shift) & 0x03)
+                         == png_ptr->trans_color.gray)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0x03)
-                            == png_ptr->trans_color.gray)
-                        {
-                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
-                           tmp |= png_ptr->background.gray << shift;
-                           *sp = (png_byte)(tmp & 0xff);
-                        }
-
-                        else
-                        {
-                           unsigned int p = (*sp >> shift) & 0x03;
-                           unsigned int g = (gamma_table [p | (p << 2) |
-                               (p << 4) | (p << 6)] >> 6) & 0x03;
-                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
-                           tmp |= g << shift;
-                           *sp = (png_byte)(tmp & 0xff);
-                        }
-
-                        if (shift == 0)
-                        {
-                           shift = 6;
-                           sp++;
-                        }
-
-                        else
-                           shift -= 2;
+                        unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+                        tmp |=
+                            (unsigned int)png_ptr->background.gray << shift;
+                        *sp = (png_byte)(tmp & 0xff);
                      }
-                  }
 
-                  else
-#endif
-                  {
-                     sp = row;
-                     shift = 6;
-                     for (i = 0; i < row_width; i++)
+                     if (shift == 0)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0x03)
-                            == png_ptr->trans_color.gray)
-                        {
-                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
-                           tmp |= png_ptr->background.gray << shift;
-                           *sp = (png_byte)(tmp & 0xff);
-                        }
-
-                        if (shift == 0)
-                        {
-                           shift = 6;
-                           sp++;
-                        }
-
-                        else
-                           shift -= 2;
+                        shift = 6;
+                        sp++;
                      }
+
+                     else
+                        shift -= 2;
                   }
-                  break;
                }
+               break;
+            }
 
-               case 4:
-               {
+            case 4:
+            {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_table != NULL)
+               if (gamma_table != NULL)
+               {
+                  sp = row;
+                  shift = 4;
+                  for (i = 0; i < row_width; i++)
                   {
-                     sp = row;
-                     shift = 4;
-                     for (i = 0; i < row_width; i++)
+                     if ((png_uint_16)((*sp >> shift) & 0x0f)
+                         == png_ptr->trans_color.gray)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0x0f)
-                            == png_ptr->trans_color.gray)
-                        {
-                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
-                           tmp |= png_ptr->background.gray << shift;
-                           *sp = (png_byte)(tmp & 0xff);
-                        }
-
-                        else
-                        {
-                           unsigned int p = (*sp >> shift) & 0x0f;
-                           unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
-                              0x0f;
-                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
-                           tmp |= g << shift;
-                           *sp = (png_byte)(tmp & 0xff);
-                        }
+                        unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
+                        tmp |=
+                           (unsigned int)(png_ptr->background.gray << shift);
+                        *sp = (png_byte)(tmp & 0xff);
+                     }
 
-                        if (shift == 0)
-                        {
-                           shift = 4;
-                           sp++;
-                        }
+                     else
+                     {
+                        unsigned int p = (*sp >> shift) & 0x0f;
+                        unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
+                           0x0f;
+                        unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
+                        tmp |= (unsigned int)(g << shift);
+                        *sp = (png_byte)(tmp & 0xff);
+                     }
 
-                        else
-                           shift -= 4;
+                     if (shift == 0)
+                     {
+                        shift = 4;
+                        sp++;
                      }
+
+                     else
+                        shift -= 4;
                   }
+               }
 
-                  else
+               else
 #endif
+               {
+                  sp = row;
+                  shift = 4;
+                  for (i = 0; i < row_width; i++)
                   {
-                     sp = row;
-                     shift = 4;
-                     for (i = 0; i < row_width; i++)
+                     if ((png_uint_16)((*sp >> shift) & 0x0f)
+                         == png_ptr->trans_color.gray)
                      {
-                        if ((png_uint_16)((*sp >> shift) & 0x0f)
-                            == png_ptr->trans_color.gray)
-                        {
-                           unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
-                           tmp |= png_ptr->background.gray << shift;
-                           *sp = (png_byte)(tmp & 0xff);
-                        }
-
-                        if (shift == 0)
-                        {
-                           shift = 4;
-                           sp++;
-                        }
+                        unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
+                        tmp |=
+                           (unsigned int)(png_ptr->background.gray << shift);
+                        *sp = (png_byte)(tmp & 0xff);
+                     }
 
-                        else
-                           shift -= 4;
+                     if (shift == 0)
+                     {
+                        shift = 4;
+                        sp++;
                      }
+
+                     else
+                        shift -= 4;
                   }
-                  break;
                }
+               break;
+            }
 
-               case 8:
-               {
+            case 8:
+            {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_table != NULL)
+               if (gamma_table != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp++)
                   {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp++)
-                     {
-                        if (*sp == png_ptr->trans_color.gray)
-                           *sp = (png_byte)png_ptr->background.gray;
+                     if (*sp == png_ptr->trans_color.gray)
+                        *sp = (png_byte)png_ptr->background.gray;
 
-                        else
-                           *sp = gamma_table[*sp];
-                     }
+                     else
+                        *sp = gamma_table[*sp];
                   }
-                  else
+               }
+               else
 #endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp++)
                   {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp++)
-                     {
-                        if (*sp == png_ptr->trans_color.gray)
-                           *sp = (png_byte)png_ptr->background.gray;
-                     }
+                     if (*sp == png_ptr->trans_color.gray)
+                        *sp = (png_byte)png_ptr->background.gray;
                   }
-                  break;
                }
+               break;
+            }
 
-               case 16:
-               {
+            case 16:
+            {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-                  if (gamma_16 != NULL)
+               if (gamma_16 != NULL)
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 2)
                   {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp += 2)
-                     {
-                        png_uint_16 v;
-
-                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                     png_uint_16 v;
 
-                        if (v == png_ptr->trans_color.gray)
-                        {
-                           /* Background is already in screen gamma */
-                           *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                           *(sp + 1) = (png_byte)(png_ptr->background.gray
-                                & 0xff);
-                        }
+                     v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
-                        else
-                        {
-                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                           *sp = (png_byte)((v >> 8) & 0xff);
-                           *(sp + 1) = (png_byte)(v & 0xff);
-                        }
+                     if (v == png_ptr->trans_color.gray)
+                     {
+                        /* Background is already in screen gamma */
+                        *sp = (png_byte)((png_ptr->background.gray >> 8)
+                             & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.gray
+                             & 0xff);
+                     }
+
+                     else
+                     {
+                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                        *sp = (png_byte)((v >> 8) & 0xff);
+                        *(sp + 1) = (png_byte)(v & 0xff);
                      }
                   }
-                  else
+               }
+               else
 #endif
+               {
+                  sp = row;
+                  for (i = 0; i < row_width; i++, sp += 2)
                   {
-                     sp = row;
-                     for (i = 0; i < row_width; i++, sp += 2)
-                     {
-                        png_uint_16 v;
+                     png_uint_16 v;
 
-                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                     v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
-                        if (v == png_ptr->trans_color.gray)
-                        {
-                           *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                           *(sp + 1) = (png_byte)(png_ptr->background.gray
-                                & 0xff);
-                        }
+                     if (v == png_ptr->trans_color.gray)
+                     {
+                        *sp = (png_byte)((png_ptr->background.gray >> 8)
+                             & 0xff);
+                        *(sp + 1) = (png_byte)(png_ptr->background.gray
+                             & 0xff);
                      }
                   }
-                  break;
                }
-
-               default:
-                  break;
+               break;
             }
-            break;
+
+            default:
+               break;
          }
+         break;
+      }
 
-         case PNG_COLOR_TYPE_RGB:
+      case PNG_COLOR_TYPE_RGB:
+      {
+         if (row_info->bit_depth == 8)
          {
-            if (row_info->bit_depth == 8)
-            {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_table != NULL)
+            if (gamma_table != NULL)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 3)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 3)
+                  if (*sp == png_ptr->trans_color.red &&
+                      *(sp + 1) == png_ptr->trans_color.green &&
+                      *(sp + 2) == png_ptr->trans_color.blue)
                   {
-                     if (*sp == png_ptr->trans_color.red &&
-                         *(sp + 1) == png_ptr->trans_color.green &&
-                         *(sp + 2) == png_ptr->trans_color.blue)
-                     {
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
+                     *sp = (png_byte)png_ptr->background.red;
+                     *(sp + 1) = (png_byte)png_ptr->background.green;
+                     *(sp + 2) = (png_byte)png_ptr->background.blue;
+                  }
 
-                     else
-                     {
-                        *sp = gamma_table[*sp];
-                        *(sp + 1) = gamma_table[*(sp + 1)];
-                        *(sp + 2) = gamma_table[*(sp + 2)];
-                     }
+                  else
+                  {
+                     *sp = gamma_table[*sp];
+                     *(sp + 1) = gamma_table[*(sp + 1)];
+                     *(sp + 2) = gamma_table[*(sp + 2)];
                   }
                }
-               else
+            }
+            else
 #endif
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 3)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 3)
+                  if (*sp == png_ptr->trans_color.red &&
+                      *(sp + 1) == png_ptr->trans_color.green &&
+                      *(sp + 2) == png_ptr->trans_color.blue)
                   {
-                     if (*sp == png_ptr->trans_color.red &&
-                         *(sp + 1) == png_ptr->trans_color.green &&
-                         *(sp + 2) == png_ptr->trans_color.blue)
-                     {
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
+                     *sp = (png_byte)png_ptr->background.red;
+                     *(sp + 1) = (png_byte)png_ptr->background.green;
+                     *(sp + 2) = (png_byte)png_ptr->background.blue;
                   }
                }
             }
-            else /* if (row_info->bit_depth == 16) */
-            {
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_16 != NULL)
+            if (gamma_16 != NULL)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 6)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 6)
-                  {
-                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                  png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
-                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
+                  png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                      + *(sp + 3));
 
-                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
-                         + *(sp + 5));
+                  png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                      + *(sp + 5));
 
-                     if (r == png_ptr->trans_color.red &&
-                         g == png_ptr->trans_color.green &&
-                         b == png_ptr->trans_color.blue)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
+                  if (r == png_ptr->trans_color.red &&
+                      g == png_ptr->trans_color.green &&
+                      b == png_ptr->trans_color.blue)
+                  {
+                     /* Background is already in screen gamma */
+                     *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                     *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                             & 0xff);
+                     *(sp + 3) = (png_byte)(png_ptr->background.green
+                             & 0xff);
+                     *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                             & 0xff);
+                     *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+                  }
 
-                     else
-                     {
-                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
+                  else
+                  {
+                     png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                     *sp = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(v & 0xff);
 
-                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
-                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(v & 0xff);
+                     v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                     *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 3) = (png_byte)(v & 0xff);
 
-                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
-                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(v & 0xff);
-                     }
+                     v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                     *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 5) = (png_byte)(v & 0xff);
                   }
                }
+            }
 
-               else
+            else
 #endif
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 6)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 6)
-                  {
-                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                  png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
-                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
+                  png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                      + *(sp + 3));
 
-                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
-                         + *(sp + 5));
+                  png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                      + *(sp + 5));
 
-                     if (r == png_ptr->trans_color.red &&
-                         g == png_ptr->trans_color.green &&
-                         b == png_ptr->trans_color.blue)
-                     {
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
+                  if (r == png_ptr->trans_color.red &&
+                      g == png_ptr->trans_color.green &&
+                      b == png_ptr->trans_color.blue)
+                  {
+                     *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                     *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                             & 0xff);
+                     *(sp + 3) = (png_byte)(png_ptr->background.green
+                             & 0xff);
+                     *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                             & 0xff);
+                     *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
                   }
                }
             }
-            break;
          }
+         break;
+      }
 
-         case PNG_COLOR_TYPE_GRAY_ALPHA:
+      case PNG_COLOR_TYPE_GRAY_ALPHA:
+      {
+         if (row_info->bit_depth == 8)
          {
-            if (row_info->bit_depth == 8)
-            {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
-                   gamma_table != NULL)
+            if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                gamma_table != NULL)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 2)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 2)
-                  {
-                     png_uint_16 a = *(sp + 1);
+                  png_uint_16 a = *(sp + 1);
 
-                     if (a == 0xff)
-                        *sp = gamma_table[*sp];
+                  if (a == 0xff)
+                     *sp = gamma_table[*sp];
 
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)png_ptr->background.gray;
-                     }
+                  else if (a == 0)
+                  {
+                     /* Background is already in screen gamma */
+                     *sp = (png_byte)png_ptr->background.gray;
+                  }
 
-                     else
-                     {
-                        png_byte v, w;
+                  else
+                  {
+                     png_byte v, w;
 
-                        v = gamma_to_1[*sp];
-                        png_composite(w, v, a, png_ptr->background_1.gray);
-                        if (optimize == 0)
-                           w = gamma_from_1[w];
-                        *sp = w;
-                     }
+                     v = gamma_to_1[*sp];
+                     png_composite(w, v, a, png_ptr->background_1.gray);
+                     if (optimize == 0)
+                        w = gamma_from_1[w];
+                     *sp = w;
                   }
                }
-               else
+            }
+            else
 #endif
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 2)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 2)
-                  {
-                     png_byte a = *(sp + 1);
+                  png_byte a = *(sp + 1);
 
-                     if (a == 0)
-                        *sp = (png_byte)png_ptr->background.gray;
+                  if (a == 0)
+                     *sp = (png_byte)png_ptr->background.gray;
 
-                     else if (a < 0xff)
-                        png_composite(*sp, *sp, a, png_ptr->background.gray);
-                  }
+                  else if (a < 0xff)
+                     png_composite(*sp, *sp, a, png_ptr->background.gray);
                }
             }
-            else /* if (png_ptr->bit_depth == 16) */
-            {
+         }
+         else /* if (png_ptr->bit_depth == 16) */
+         {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
-                   gamma_16_to_1 != NULL)
+            if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                gamma_16_to_1 != NULL)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 4)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
+                  png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+                      + *(sp + 3));
+
+                  if (a == (png_uint_16)0xffff)
                   {
-                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
+                     png_uint_16 v;
 
-                     if (a == (png_uint_16)0xffff)
-                     {
-                        png_uint_16 v;
+                     v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                     *sp = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(v & 0xff);
+                  }
 
-                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-                     }
+                  else if (a == 0)
+                  {
+                     /* Background is already in screen gamma */
+                     *sp = (png_byte)((png_ptr->background.gray >> 8)
+                             & 0xff);
+                     *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+                  }
 
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
-                     }
+                  else
+                  {
+                     png_uint_16 g, v, w;
 
+                     g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                     png_composite_16(v, g, a, png_ptr->background_1.gray);
+                     if (optimize != 0)
+                        w = v;
                      else
-                     {
-                        png_uint_16 g, v, w;
-
-                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
-                        png_composite_16(v, g, a, png_ptr->background_1.gray);
-                        if (optimize != 0)
-                           w = v;
-                        else
-                           w = gamma_16_from_1[(v & 0xff) >>
-                               gamma_shift][v >> 8];
-                        *sp = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(w & 0xff);
-                     }
+                        w = gamma_16_from_1[(v & 0xff) >>
+                            gamma_shift][v >> 8];
+                     *sp = (png_byte)((w >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(w & 0xff);
                   }
                }
-               else
+            }
+            else
 #endif
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 4)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
-                  {
-                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
-                         + *(sp + 3));
+                  png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+                      + *(sp + 3));
 
-                     if (a == 0)
-                     {
-                        *sp = (png_byte)((png_ptr->background.gray >> 8)
-                                & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
-                     }
+                  if (a == 0)
+                  {
+                     *sp = (png_byte)((png_ptr->background.gray >> 8)
+                             & 0xff);
+                     *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+                  }
 
-                     else if (a < 0xffff)
-                     {
-                        png_uint_16 g, v;
+                  else if (a < 0xffff)
+                  {
+                     png_uint_16 g, v;
 
-                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-                        png_composite_16(v, g, a, png_ptr->background.gray);
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-                     }
+                     g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                     png_composite_16(v, g, a, png_ptr->background.gray);
+                     *sp = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(v & 0xff);
                   }
                }
             }
-            break;
          }
+         break;
+      }
 
-         case PNG_COLOR_TYPE_RGB_ALPHA:
+      case PNG_COLOR_TYPE_RGB_ALPHA:
+      {
+         if (row_info->bit_depth == 8)
          {
-            if (row_info->bit_depth == 8)
-            {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
-                   gamma_table != NULL)
+            if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+                gamma_table != NULL)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 4)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
+                  png_byte a = *(sp + 3);
+
+                  if (a == 0xff)
                   {
-                     png_byte a = *(sp + 3);
+                     *sp = gamma_table[*sp];
+                     *(sp + 1) = gamma_table[*(sp + 1)];
+                     *(sp + 2) = gamma_table[*(sp + 2)];
+                  }
 
-                     if (a == 0xff)
-                     {
-                        *sp = gamma_table[*sp];
-                        *(sp + 1) = gamma_table[*(sp + 1)];
-                        *(sp + 2) = gamma_table[*(sp + 2)];
-                     }
+                  else if (a == 0)
+                  {
+                     /* Background is already in screen gamma */
+                     *sp = (png_byte)png_ptr->background.red;
+                     *(sp + 1) = (png_byte)png_ptr->background.green;
+                     *(sp + 2) = (png_byte)png_ptr->background.blue;
+                  }
 
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
+                  else
+                  {
+                     png_byte v, w;
 
-                     else
-                     {
-                        png_byte v, w;
-
-                        v = gamma_to_1[*sp];
-                        png_composite(w, v, a, png_ptr->background_1.red);
-                        if (optimize == 0) w = gamma_from_1[w];
-                        *sp = w;
-
-                        v = gamma_to_1[*(sp + 1)];
-                        png_composite(w, v, a, png_ptr->background_1.green);
-                        if (optimize == 0) w = gamma_from_1[w];
-                        *(sp + 1) = w;
-
-                        v = gamma_to_1[*(sp + 2)];
-                        png_composite(w, v, a, png_ptr->background_1.blue);
-                        if (optimize == 0) w = gamma_from_1[w];
-                        *(sp + 2) = w;
-                     }
+                     v = gamma_to_1[*sp];
+                     png_composite(w, v, a, png_ptr->background_1.red);
+                     if (optimize == 0) w = gamma_from_1[w];
+                     *sp = w;
+
+                     v = gamma_to_1[*(sp + 1)];
+                     png_composite(w, v, a, png_ptr->background_1.green);
+                     if (optimize == 0) w = gamma_from_1[w];
+                     *(sp + 1) = w;
+
+                     v = gamma_to_1[*(sp + 2)];
+                     png_composite(w, v, a, png_ptr->background_1.blue);
+                     if (optimize == 0) w = gamma_from_1[w];
+                     *(sp + 2) = w;
                   }
                }
-               else
+            }
+            else
 #endif
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 4)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 4)
-                  {
-                     png_byte a = *(sp + 3);
+                  png_byte a = *(sp + 3);
 
-                     if (a == 0)
-                     {
-                        *sp = (png_byte)png_ptr->background.red;
-                        *(sp + 1) = (png_byte)png_ptr->background.green;
-                        *(sp + 2) = (png_byte)png_ptr->background.blue;
-                     }
+                  if (a == 0)
+                  {
+                     *sp = (png_byte)png_ptr->background.red;
+                     *(sp + 1) = (png_byte)png_ptr->background.green;
+                     *(sp + 2) = (png_byte)png_ptr->background.blue;
+                  }
 
-                     else if (a < 0xff)
-                     {
-                        png_composite(*sp, *sp, a, png_ptr->background.red);
+                  else if (a < 0xff)
+                  {
+                     png_composite(*sp, *sp, a, png_ptr->background.red);
 
-                        png_composite(*(sp + 1), *(sp + 1), a,
-                            png_ptr->background.green);
+                     png_composite(*(sp + 1), *(sp + 1), a,
+                         png_ptr->background.green);
 
-                        png_composite(*(sp + 2), *(sp + 2), a,
-                            png_ptr->background.blue);
-                     }
+                     png_composite(*(sp + 2), *(sp + 2), a,
+                         png_ptr->background.blue);
                   }
                }
             }
-            else /* if (row_info->bit_depth == 16) */
-            {
+         }
+         else /* if (row_info->bit_depth == 16) */
+         {
 #ifdef PNG_READ_GAMMA_SUPPORTED
-               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
-                   gamma_16_to_1 != NULL)
+            if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+                gamma_16_to_1 != NULL)
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 8)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 8)
+                  png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                      << 8) + (png_uint_16)(*(sp + 7)));
+
+                  if (a == (png_uint_16)0xffff)
                   {
-                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
-                         << 8) + (png_uint_16)(*(sp + 7)));
+                     png_uint_16 v;
 
-                     if (a == (png_uint_16)0xffff)
-                     {
-                        png_uint_16 v;
+                     v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+                     *sp = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(v & 0xff);
 
-                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
-
-                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
-                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(v & 0xff);
+                     v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                     *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 3) = (png_byte)(v & 0xff);
 
-                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
-                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(v & 0xff);
-                     }
+                     v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                     *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 5) = (png_byte)(v & 0xff);
+                  }
 
-                     else if (a == 0)
-                     {
-                        /* Background is already in screen gamma */
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
+                  else if (a == 0)
+                  {
+                     /* Background is already in screen gamma */
+                     *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                     *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                             & 0xff);
+                     *(sp + 3) = (png_byte)(png_ptr->background.green
+                             & 0xff);
+                     *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                             & 0xff);
+                     *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+                  }
 
-                     else
-                     {
-                        png_uint_16 v, w;
-
-                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
-                        png_composite_16(w, v, a, png_ptr->background_1.red);
-                        if (optimize == 0)
-                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
-                                8];
-                        *sp = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(w & 0xff);
-
-                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
-                        png_composite_16(w, v, a, png_ptr->background_1.green);
-                        if (optimize == 0)
-                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
-                                8];
-
-                        *(sp + 2) = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(w & 0xff);
-
-                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
-                        png_composite_16(w, v, a, png_ptr->background_1.blue);
-                        if (optimize == 0)
-                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
-                                8];
-
-                        *(sp + 4) = (png_byte)((w >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(w & 0xff);
-                     }
+                  else
+                  {
+                     png_uint_16 v, w;
+
+                     v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+                     png_composite_16(w, v, a, png_ptr->background_1.red);
+                     if (optimize == 0)
+                        w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
+                             8];
+                     *sp = (png_byte)((w >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(w & 0xff);
+
+                     v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+                     png_composite_16(w, v, a, png_ptr->background_1.green);
+                     if (optimize == 0)
+                        w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
+                             8];
+
+                     *(sp + 2) = (png_byte)((w >> 8) & 0xff);
+                     *(sp + 3) = (png_byte)(w & 0xff);
+
+                     v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+                     png_composite_16(w, v, a, png_ptr->background_1.blue);
+                     if (optimize == 0)
+                        w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
+                             8];
+
+                     *(sp + 4) = (png_byte)((w >> 8) & 0xff);
+                     *(sp + 5) = (png_byte)(w & 0xff);
                   }
                }
+            }
 
-               else
+            else
 #endif
+            {
+               sp = row;
+               for (i = 0; i < row_width; i++, sp += 8)
                {
-                  sp = row;
-                  for (i = 0; i < row_width; i++, sp += 8)
-                  {
-                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
-                         << 8) + (png_uint_16)(*(sp + 7)));
+                  png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+                      << 8) + (png_uint_16)(*(sp + 7)));
 
-                     if (a == 0)
-                     {
-                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
-                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
-                                & 0xff);
-                        *(sp + 3) = (png_byte)(png_ptr->background.green
-                                & 0xff);
-                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
-                                & 0xff);
-                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
-                     }
+                  if (a == 0)
+                  {
+                     *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+                     *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+                             & 0xff);
+                     *(sp + 3) = (png_byte)(png_ptr->background.green
+                             & 0xff);
+                     *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+                             & 0xff);
+                     *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+                  }
 
-                     else if (a < 0xffff)
-                     {
-                        png_uint_16 v;
+                  else if (a < 0xffff)
+                  {
+                     png_uint_16 v;
 
-                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
-                            + *(sp + 3));
-                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
-                            + *(sp + 5));
+                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+                         + *(sp + 3));
+                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+                         + *(sp + 5));
 
-                        png_composite_16(v, r, a, png_ptr->background.red);
-                        *sp = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 1) = (png_byte)(v & 0xff);
+                     png_composite_16(v, r, a, png_ptr->background.red);
+                     *sp = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 1) = (png_byte)(v & 0xff);
 
-                        png_composite_16(v, g, a, png_ptr->background.green);
-                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 3) = (png_byte)(v & 0xff);
+                     png_composite_16(v, g, a, png_ptr->background.green);
+                     *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 3) = (png_byte)(v & 0xff);
 
-                        png_composite_16(v, b, a, png_ptr->background.blue);
-                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
-                        *(sp + 5) = (png_byte)(v & 0xff);
-                     }
+                     png_composite_16(v, b, a, png_ptr->background.blue);
+                     *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+                     *(sp + 5) = (png_byte)(v & 0xff);
                   }
                }
             }
-            break;
          }
-
-         default:
-            break;
+         break;
       }
+
+      default:
+         break;
    }
 }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE */
@@ -4135,12 +4152,11 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
    {
       if (row_info->bit_depth == 8)
       {
-         PNG_CONST png_bytep table = png_ptr->gamma_from_1;
+         png_bytep table = png_ptr->gamma_from_1;
 
          if (table != NULL)
          {
-            PNG_CONST int step =
-               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
+            int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
 
             /* The alpha channel is the last component: */
             row += step - 1;
@@ -4154,13 +4170,12 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
 
       else if (row_info->bit_depth == 16)
       {
-         PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
-         PNG_CONST int gamma_shift = png_ptr->gamma_shift;
+         png_uint_16pp table = png_ptr->gamma_16_from_1;
+         int gamma_shift = png_ptr->gamma_shift;
 
          if (table != NULL)
          {
-            PNG_CONST int step =
-               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
+            int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
 
             /* The alpha channel is the last component: */
             row += step - 2;
@@ -4191,8 +4206,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
  * upon whether you supply trans and num_trans.
  */
 static void
-png_do_expand_palette(png_row_infop row_info, png_bytep row,
-   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
+png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
+    png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
+    int num_trans)
 {
    int shift, value;
    png_bytep sp, dp;
@@ -4209,8 +4225,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
          {
             case 1:
             {
-               sp = row + (png_size_t)((row_width - 1) >> 3);
-               dp = row + (png_size_t)row_width - 1;
+               sp = row + (size_t)((row_width - 1) >> 3);
+               dp = row + (size_t)row_width - 1;
                shift = 7 - (int)((row_width + 7) & 0x07);
                for (i = 0; i < row_width; i++)
                {
@@ -4236,8 +4252,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
 
             case 2:
             {
-               sp = row + (png_size_t)((row_width - 1) >> 2);
-               dp = row + (png_size_t)row_width - 1;
+               sp = row + (size_t)((row_width - 1) >> 2);
+               dp = row + (size_t)row_width - 1;
                shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
                for (i = 0; i < row_width; i++)
                {
@@ -4259,8 +4275,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
 
             case 4:
             {
-               sp = row + (png_size_t)((row_width - 1) >> 1);
-               dp = row + (png_size_t)row_width - 1;
+               sp = row + (size_t)((row_width - 1) >> 1);
+               dp = row + (size_t)row_width - 1;
                shift = (int)((row_width & 0x01) << 2);
                for (i = 0; i < row_width; i++)
                {
@@ -4293,17 +4309,28 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
          {
             if (num_trans > 0)
             {
-               sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 2) - 1;
+               sp = row + (size_t)row_width - 1;
+               dp = row + ((size_t)row_width << 2) - 1;
 
-               for (i = 0; i < row_width; i++)
+               i = 0;
+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+               if (png_ptr->riffled_palette != NULL)
+               {
+                  /* The RGBA optimization works with png_ptr->bit_depth == 8
+                   * but sometimes row_info->bit_depth has been changed to 8.
+                   * In these cases, the palette hasn't been riffled.
+                   */
+                  i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row,
+                      &sp, &dp);
+               }
+#endif
+
+               for (; i < row_width; i++)
                {
                   if ((int)(*sp) >= num_trans)
                      *dp-- = 0xff;
-
                   else
                      *dp-- = trans_alpha[*sp];
-
                   *dp-- = palette[*sp].blue;
                   *dp-- = palette[*sp].green;
                   *dp-- = palette[*sp].red;
@@ -4318,10 +4345,15 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
 
             else
             {
-               sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width * 3) - 1;
+               sp = row + (size_t)row_width - 1;
+               dp = row + (size_t)(row_width * 3) - 1;
+               i = 0;
+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+               i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row,
+                   &sp, &dp);
+#endif
 
-               for (i = 0; i < row_width; i++)
+               for (; i < row_width; i++)
                {
                   *dp-- = palette[*sp].blue;
                   *dp-- = palette[*sp].green;
@@ -4354,195 +4386,130 @@ png_do_expand(png_row_infop row_info, png_bytep row,
 
    png_debug(1, "in png_do_expand");
 
+   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
    {
-      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
-      {
-         unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
+      unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
 
-         if (row_info->bit_depth < 8)
+      if (row_info->bit_depth < 8)
+      {
+         switch (row_info->bit_depth)
          {
-            switch (row_info->bit_depth)
+            case 1:
             {
-               case 1:
+               gray = (gray & 0x01) * 0xff;
+               sp = row + (size_t)((row_width - 1) >> 3);
+               dp = row + (size_t)row_width - 1;
+               shift = 7 - (int)((row_width + 7) & 0x07);
+               for (i = 0; i < row_width; i++)
                {
-                  gray = (gray & 0x01) * 0xff;
-                  sp = row + (png_size_t)((row_width - 1) >> 3);
-                  dp = row + (png_size_t)row_width - 1;
-                  shift = 7 - (int)((row_width + 7) & 0x07);
-                  for (i = 0; i < row_width; i++)
-                  {
-                     if ((*sp >> shift) & 0x01)
-                        *dp = 0xff;
-
-                     else
-                        *dp = 0;
-
-                     if (shift == 7)
-                     {
-                        shift = 0;
-                        sp--;
-                     }
-
-                     else
-                        shift++;
+                  if ((*sp >> shift) & 0x01)
+                     *dp = 0xff;
 
-                     dp--;
-                  }
-                  break;
-               }
+                  else
+                     *dp = 0;
 
-               case 2:
-               {
-                  gray = (gray & 0x03) * 0x55;
-                  sp = row + (png_size_t)((row_width - 1) >> 2);
-                  dp = row + (png_size_t)row_width - 1;
-                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
-                  for (i = 0; i < row_width; i++)
+                  if (shift == 7)
                   {
-                     value = (*sp >> shift) & 0x03;
-                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
-                        (value << 6));
-                     if (shift == 6)
-                     {
-                        shift = 0;
-                        sp--;
-                     }
-
-                     else
-                        shift += 2;
-
-                     dp--;
+                     shift = 0;
+                     sp--;
                   }
-                  break;
-               }
 
-               case 4:
-               {
-                  gray = (gray & 0x0f) * 0x11;
-                  sp = row + (png_size_t)((row_width - 1) >> 1);
-                  dp = row + (png_size_t)row_width - 1;
-                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
-                  for (i = 0; i < row_width; i++)
-                  {
-                     value = (*sp >> shift) & 0x0f;
-                     *dp = (png_byte)(value | (value << 4));
-                     if (shift == 4)
-                     {
-                        shift = 0;
-                        sp--;
-                     }
-
-                     else
-                        shift = 4;
+                  else
+                     shift++;
 
-                     dp--;
-                  }
-                  break;
+                  dp--;
                }
-
-               default:
-                  break;
+               break;
             }
 
-            row_info->bit_depth = 8;
-            row_info->pixel_depth = 8;
-            row_info->rowbytes = row_width;
-         }
-
-         if (trans_color != NULL)
-         {
-            if (row_info->bit_depth == 8)
+            case 2:
             {
-               gray = gray & 0xff;
-               sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 1) - 1;
-
+               gray = (gray & 0x03) * 0x55;
+               sp = row + (size_t)((row_width - 1) >> 2);
+               dp = row + (size_t)row_width - 1;
+               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
                for (i = 0; i < row_width; i++)
                {
-                  if ((*sp & 0xffU) == gray)
-                     *dp-- = 0;
+                  value = (*sp >> shift) & 0x03;
+                  *dp = (png_byte)(value | (value << 2) | (value << 4) |
+                     (value << 6));
+                  if (shift == 6)
+                  {
+                     shift = 0;
+                     sp--;
+                  }
 
                   else
-                     *dp-- = 0xff;
+                     shift += 2;
 
-                  *dp-- = *sp--;
+                  dp--;
                }
+               break;
             }
 
-            else if (row_info->bit_depth == 16)
+            case 4:
             {
-               unsigned int gray_high = (gray >> 8) & 0xff;
-               unsigned int gray_low = gray & 0xff;
-               sp = row + row_info->rowbytes - 1;
-               dp = row + (row_info->rowbytes << 1) - 1;
+               gray = (gray & 0x0f) * 0x11;
+               sp = row + (size_t)((row_width - 1) >> 1);
+               dp = row + (size_t)row_width - 1;
+               shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
                for (i = 0; i < row_width; i++)
                {
-                  if ((*(sp - 1) & 0xffU) == gray_high &&
-                      (*(sp) & 0xffU) == gray_low)
+                  value = (*sp >> shift) & 0x0f;
+                  *dp = (png_byte)(value | (value << 4));
+                  if (shift == 4)
                   {
-                     *dp-- = 0;
-                     *dp-- = 0;
+                     shift = 0;
+                     sp--;
                   }
 
                   else
-                  {
-                     *dp-- = 0xff;
-                     *dp-- = 0xff;
-                  }
+                     shift = 4;
 
-                  *dp-- = *sp--;
-                  *dp-- = *sp--;
+                  dp--;
                }
+               break;
             }
 
-            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
-            row_info->channels = 2;
-            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
-            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
-               row_width);
+            default:
+               break;
          }
+
+         row_info->bit_depth = 8;
+         row_info->pixel_depth = 8;
+         row_info->rowbytes = row_width;
       }
-      else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
-          trans_color != NULL)
+
+      if (trans_color != NULL)
       {
          if (row_info->bit_depth == 8)
          {
-            png_byte red = (png_byte)(trans_color->red & 0xff);
-            png_byte green = (png_byte)(trans_color->green & 0xff);
-            png_byte blue = (png_byte)(trans_color->blue & 0xff);
-            sp = row + (png_size_t)row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 2) - 1;
+            gray = gray & 0xff;
+            sp = row + (size_t)row_width - 1;
+            dp = row + ((size_t)row_width << 1) - 1;
+
             for (i = 0; i < row_width; i++)
             {
-               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+               if ((*sp & 0xffU) == gray)
                   *dp-- = 0;
 
                else
                   *dp-- = 0xff;
 
                *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
             }
          }
+
          else if (row_info->bit_depth == 16)
          {
-            png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
-            png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
-            png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
-            png_byte red_low = (png_byte)(trans_color->red & 0xff);
-            png_byte green_low = (png_byte)(trans_color->green & 0xff);
-            png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
+            unsigned int gray_high = (gray >> 8) & 0xff;
+            unsigned int gray_low = gray & 0xff;
             sp = row + row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 3) - 1;
+            dp = row + (row_info->rowbytes << 1) - 1;
             for (i = 0; i < row_width; i++)
             {
-               if (*(sp - 5) == red_high &&
-                   *(sp - 4) == red_low &&
-                   *(sp - 3) == green_high &&
-                   *(sp - 2) == green_low &&
-                   *(sp - 1) == blue_high &&
-                   *(sp    ) == blue_low)
+               if ((*(sp - 1) & 0xffU) == gray_high &&
+                   (*(sp) & 0xffU) == gray_low)
                {
                   *dp-- = 0;
                   *dp-- = 0;
@@ -4556,17 +4523,80 @@ png_do_expand(png_row_infop row_info, png_bytep row,
 
                *dp-- = *sp--;
                *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
-               *dp-- = *sp--;
             }
          }
-         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-         row_info->channels = 4;
-         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
-         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+
+         row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+         row_info->channels = 2;
+         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+             row_width);
+      }
+   }
+   else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+       trans_color != NULL)
+   {
+      if (row_info->bit_depth == 8)
+      {
+         png_byte red = (png_byte)(trans_color->red & 0xff);
+         png_byte green = (png_byte)(trans_color->green & 0xff);
+         png_byte blue = (png_byte)(trans_color->blue & 0xff);
+         sp = row + (size_t)row_info->rowbytes - 1;
+         dp = row + ((size_t)row_width << 2) - 1;
+         for (i = 0; i < row_width; i++)
+         {
+            if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+               *dp-- = 0;
+
+            else
+               *dp-- = 0xff;
+
+            *dp-- = *sp--;
+            *dp-- = *sp--;
+            *dp-- = *sp--;
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
+         png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
+         png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
+         png_byte red_low = (png_byte)(trans_color->red & 0xff);
+         png_byte green_low = (png_byte)(trans_color->green & 0xff);
+         png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
+         sp = row + row_info->rowbytes - 1;
+         dp = row + ((size_t)row_width << 3) - 1;
+         for (i = 0; i < row_width; i++)
+         {
+            if (*(sp - 5) == red_high &&
+                *(sp - 4) == red_low &&
+                *(sp - 3) == green_high &&
+                *(sp - 2) == green_low &&
+                *(sp - 1) == blue_high &&
+                *(sp    ) == blue_low)
+            {
+               *dp-- = 0;
+               *dp-- = 0;
+            }
+
+            else
+            {
+               *dp-- = 0xff;
+               *dp-- = 0xff;
+            }
+
+            *dp-- = *sp--;
+            *dp-- = *sp--;
+            *dp-- = *sp--;
+            *dp-- = *sp--;
+            *dp-- = *sp--;
+            *dp-- = *sp--;
+         }
       }
+      row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+      row_info->channels = 4;
+      row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
    }
 }
 #endif
@@ -4593,7 +4623,9 @@ png_do_expand_16(png_row_infop row_info, png_bytep row)
       png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
       png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
       while (dp > sp)
-         dp[-2] = dp[-1] = *--sp, dp -= 2;
+      {
+         dp[-2] = dp[-1] = *--sp; dp -= 2;
+      }
 
       row_info->rowbytes *= 2;
       row_info->bit_depth = 16;
@@ -4735,8 +4767,22 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
    {
       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
       {
-         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
-             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
+         if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8))
+         {
+            /* Allocate space for the decompressed full palette. */
+            if (png_ptr->riffled_palette == NULL)
+            {
+               png_ptr->riffled_palette = png_malloc(png_ptr, 256*4);
+               if (png_ptr->riffled_palette == NULL)
+                  png_error(png_ptr, "NULL row buffer");
+               /* Build the RGBA palette. */
+               png_riffle_palette_rgba(png_ptr, row_info);
+            }
+         }
+#endif
+         png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
+            png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
       }
 
       else
@@ -4747,8 +4793,7 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
                 &(png_ptr->trans_color));
 
          else
-            png_do_expand(row_info, png_ptr->row_buf + 1,
-                NULL);
+            png_do_expand(row_info, png_ptr->row_buf + 1, NULL);
       }
    }
 #endif
@@ -4759,7 +4804,7 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         0 /* at_start == false, because SWAP_ALPHA happens later */);
+          0 /* at_start == false, because SWAP_ALPHA happens later */);
 #endif
 
 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
@@ -4972,7 +5017,7 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
              (png_ptr,     /* png_ptr */
              row_info,     /* row_info: */
                 /*  png_uint_32 width;       width of row */
-                /*  png_size_t rowbytes;     number of bytes in row */
+                /*  size_t rowbytes;         number of bytes in row */
                 /*  png_byte color_type;     color type of pixels */
                 /*  png_byte bit_depth;      bit depth of samples */
                 /*  png_byte channels;       number of channels (1-4) */
index c9747fc..d5fa08c 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.6.20 [December 3, 2014]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -86,11 +86,11 @@ png_get_int_32)(png_const_bytep buf)
 {
    png_uint_32 uval = png_get_uint_32(buf);
    if ((uval & 0x80000000) == 0) /* non-negative */
-      return uval;
+      return (png_int_32)uval;
 
    uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
    if ((uval & 0x80000000) == 0) /* no overflow */
-       return -(png_int_32)uval;
+      return -(png_int_32)uval;
    /* The following has to be safe; this function only gets called on PNG data
     * and if we get here that data is invalid.  0 is the most safe value and
     * if not then an attacker would surely just generate a PNG with 0 instead.
@@ -102,7 +102,7 @@ png_get_int_32)(png_const_bytep buf)
 png_uint_16 (PNGAPI
 png_get_uint_16)(png_const_bytep buf)
 {
-   /* ANSI-C requires an int value to accomodate at least 16 bits so this
+   /* ANSI-C requires an int value to accommodate at least 16 bits so this
     * works and allows the compiler not to worry about possible narrowing
     * on 32-bit systems.  (Pre-ANSI systems did not make integers smaller
     * than 16 bits either.)
@@ -120,7 +120,7 @@ png_get_uint_16)(png_const_bytep buf)
 void /* PRIVATE */
 png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
 {
-   png_size_t num_checked, num_to_check;
+   size_t num_checked, num_to_check;
 
    /* Exit if the user application does not expect a signature. */
    if (png_ptr->sig_bytes >= 8)
@@ -181,6 +181,9 @@ png_read_chunk_header(png_structrp png_ptr)
    /* Check to see if chunk name is valid. */
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 
+   /* Check for too-large chunk length */
+   png_check_chunk_length(png_ptr, length);
+
 #ifdef PNG_IO_STATE_SUPPORTED
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
 #endif
@@ -311,6 +314,7 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
 
       if (buffer != NULL)
       {
+         memset(buffer, 0, new_size); /* just in case */
          png_ptr->read_buffer = buffer;
          png_ptr->read_buffer_size = new_size;
       }
@@ -370,11 +374,10 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
     */
    {
       int ret; /* zlib return code */
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
+      int window_bits = 0;
 
 # if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
-      int window_bits;
-
       if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
           PNG_OPTION_ON)
       {
@@ -384,13 +387,11 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
 
       else
       {
-         window_bits = 0;
          png_ptr->zstream_start = 1;
       }
-# else
-#   define window_bits 0
 # endif
-#endif
+
+#endif /* ZLIB_VERNUM >= 0x1240 */
 
       /* Set this for safety, just in case the previous owner left pointers to
        * memory allocations.
@@ -402,25 +403,32 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
 
       if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
       {
-#if PNG_ZLIB_VERNUM < 0x1240
-         ret = inflateReset(&png_ptr->zstream);
-#else
+#if ZLIB_VERNUM >= 0x1240
          ret = inflateReset2(&png_ptr->zstream, window_bits);
+#else
+         ret = inflateReset(&png_ptr->zstream);
 #endif
       }
 
       else
       {
-#if PNG_ZLIB_VERNUM < 0x1240
-         ret = inflateInit(&png_ptr->zstream);
-#else
+#if ZLIB_VERNUM >= 0x1240
          ret = inflateInit2(&png_ptr->zstream, window_bits);
+#else
+         ret = inflateInit(&png_ptr->zstream);
 #endif
 
          if (ret == Z_OK)
             png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
       }
 
+#if ZLIB_VERNUM >= 0x1290 && \
+   defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
+      if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
+         /* Turn off validation of the ADLER32 checksum in IDAT chunks */
+         ret = inflateValidate(&png_ptr->zstream, 0);
+#endif
+
       if (ret == Z_OK)
          png_ptr->zowner = owner;
 
@@ -435,7 +443,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
 #endif
 }
 
-#if PNG_ZLIB_VERNUM >= 0x1240
+#if ZLIB_VERNUM >= 0x1240
 /* Handle the start of the inflate stream if we called inflateInit2(strm,0);
  * in this case some zlib versions skip validation of the CINFO field and, in
  * certain circumstances, libpng may end up displaying an invalid image, in
@@ -461,6 +469,7 @@ png_zlib_inflate(png_structrp png_ptr, int flush)
 #endif /* Zlib >= 1.2.4 */
 
 #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED)
 /* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
  * allow the caller to do multiple calls if required.  If the 'finish' flag is
  * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
@@ -599,9 +608,9 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
  */
 static int
 png_decompress_chunk(png_structrp png_ptr,
-   png_uint_32 chunklength, png_uint_32 prefix_size,
-   png_alloc_size_t *newlength /* must be initialized to the maximum! */,
-   int terminate /*add a '\0' to the end of the uncompressed data*/)
+    png_uint_32 chunklength, png_uint_32 prefix_size,
+    png_alloc_size_t *newlength /* must be initialized to the maximum! */,
+    int terminate /*add a '\0' to the end of the uncompressed data*/)
 {
    /* TODO: implement different limits for different types of chunk.
     *
@@ -638,8 +647,8 @@ png_decompress_chunk(png_structrp png_ptr,
          png_uint_32 lzsize = chunklength - prefix_size;
 
          ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
-            /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
-            /* output: */ NULL, newlength);
+             /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
+             /* output: */ NULL, newlength);
 
          if (ret == Z_STREAM_END)
          {
@@ -659,15 +668,17 @@ png_decompress_chunk(png_structrp png_ptr,
                 */
                png_alloc_size_t new_size = *newlength;
                png_alloc_size_t buffer_size = prefix_size + new_size +
-                  (terminate != 0);
+                   (terminate != 0);
                png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
-                  buffer_size));
+                   buffer_size));
 
                if (text != NULL)
                {
+                  memset(text, 0, buffer_size);
+
                   ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
-                     png_ptr->read_buffer + prefix_size, &lzsize,
-                     text + prefix_size, newlength);
+                      png_ptr->read_buffer + prefix_size, &lzsize,
+                      text + prefix_size, newlength);
 
                   if (ret == Z_STREAM_END)
                   {
@@ -712,7 +723,7 @@ png_decompress_chunk(png_structrp png_ptr,
                    * the extra space may otherwise be used as a Trojan Horse.
                    */
                   if (ret == Z_STREAM_END &&
-                     chunklength - prefix_size != lzsize)
+                      chunklength - prefix_size != lzsize)
                      png_chunk_benign_error(png_ptr, "extra compressed data");
                }
 
@@ -728,9 +739,7 @@ png_decompress_chunk(png_structrp png_ptr,
             {
                /* inflateReset failed, store the error message */
                png_zstream_error(png_ptr, ret);
-
-               if (ret == Z_STREAM_END)
-                  ret = PNG_UNEXPECTED_ZLIB_RETURN;
+               ret = PNG_UNEXPECTED_ZLIB_RETURN;
             }
          }
 
@@ -754,6 +763,7 @@ png_decompress_chunk(png_structrp png_ptr,
       return Z_MEM_ERROR;
    }
 }
+#endif /* READ_zTXt || READ_iTXt */
 #endif /* READ_COMPRESSED_TEXT */
 
 #ifdef PNG_READ_iCCP_SUPPORTED
@@ -762,8 +772,8 @@ png_decompress_chunk(png_structrp png_ptr,
  */
 static int
 png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
-   png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
-   int finish)
+    png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
+    int finish)
 {
    if (png_ptr->zowner == png_ptr->chunk_name)
    {
@@ -802,8 +812,8 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
           * the available output is produced; this allows reading of truncated
           * streams.
           */
-         ret = PNG_INFLATE(png_ptr,
-            *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
+         ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ?
+             Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
       }
       while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
 
@@ -821,7 +831,7 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
       return Z_STREAM_ERROR;
    }
 }
-#endif
+#endif /* READ_iCCP */
 
 /* Read and check the IDHR chunk */
 
@@ -1009,7 +1019,7 @@ png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 #endif
    {
-      png_crc_finish(png_ptr, (int) length - num * 3);
+      png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3));
    }
 
 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
@@ -1292,7 +1302,7 @@ png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
    (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
-      1/*prefer cHRM values*/);
+       1/*prefer cHRM values*/);
    png_colorspace_sync(png_ptr, info_ptr);
 }
 #endif
@@ -1371,11 +1381,13 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
     * chunk is just ignored, so does not invalidate the color space.  An
     * alternative is to set the 'invalid' flags at the start of this routine
     * and only clear them in they were not set before and all the tests pass.
-    * The minimum 'deflate' stream is assumed to be just the 2 byte header and
-    * 4 byte checksum.  The keyword must be at least one character and there is
-    * a terminator (0) byte and the compression method.
     */
-   if (length < 9)
+
+   /* The keyword must be at least one character and there is a
+    * terminator (0) byte and the compression method byte, and the
+    * 'zlib' datastream is at least 11 bytes.
+    */
+   if (length < 14)
    {
       png_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "too short");
@@ -1407,6 +1419,16 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       png_crc_read(png_ptr, (png_bytep)keyword, read_length);
       length -= read_length;
 
+      /* The minimum 'zlib' stream is assumed to be just the 2 byte header,
+       * 5 bytes minimum 'deflate' stream, and the 4 byte checksum.
+       */
+      if (length < 11)
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "too short");
+         return;
+      }
+
       keyword_length = 0;
       while (keyword_length < 80 && keyword_length < read_length &&
          keyword[keyword_length] != 0)
@@ -1425,53 +1447,52 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
             if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
             {
-               Byte profile_header[132];
+               Byte profile_header[132]={0};
                Byte local_buffer[PNG_INFLATE_BUF_SIZE];
                png_alloc_size_t size = (sizeof profile_header);
 
                png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
                png_ptr->zstream.avail_in = read_length;
                (void)png_inflate_read(png_ptr, local_buffer,
-                  (sizeof local_buffer), &length, profile_header, &size,
-                  0/*finish: don't, because the output is too small*/);
+                   (sizeof local_buffer), &length, profile_header, &size,
+                   0/*finish: don't, because the output is too small*/);
 
                if (size == 0)
                {
                   /* We have the ICC profile header; do the basic header checks.
                    */
-                  const png_uint_32 profile_length =
-                     png_get_uint_32(profile_header);
+                  png_uint_32 profile_length = png_get_uint_32(profile_header);
 
                   if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
-                     keyword, profile_length) != 0)
+                      keyword, profile_length) != 0)
                   {
                      /* The length is apparently ok, so we can check the 132
                       * byte header.
                       */
                      if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
-                        keyword, profile_length, profile_header,
-                        png_ptr->color_type) != 0)
+                         keyword, profile_length, profile_header,
+                         png_ptr->color_type) != 0)
                      {
                         /* Now read the tag table; a variable size buffer is
                          * needed at this point, allocate one for the whole
                          * profile.  The header check has already validated
-                         * that none of these stuff will overflow.
+                         * that none of this stuff will overflow.
                          */
-                        const png_uint_32 tag_count = png_get_uint_32(
-                           profile_header+128);
+                        png_uint_32 tag_count =
+                           png_get_uint_32(profile_header + 128);
                         png_bytep profile = png_read_buffer(png_ptr,
-                           profile_length, 2/*silent*/);
+                            profile_length, 2/*silent*/);
 
                         if (profile != NULL)
                         {
                            memcpy(profile, profile_header,
-                              (sizeof profile_header));
+                               (sizeof profile_header));
 
                            size = 12 * tag_count;
 
                            (void)png_inflate_read(png_ptr, local_buffer,
-                              (sizeof local_buffer), &length,
-                              profile + (sizeof profile_header), &size, 0);
+                               (sizeof local_buffer), &length,
+                               profile + (sizeof profile_header), &size, 0);
 
                            /* Still expect a buffer error because we expect
                             * there to be some tag data!
@@ -1479,22 +1500,22 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                            if (size == 0)
                            {
                               if (png_icc_check_tag_table(png_ptr,
-                                 &png_ptr->colorspace, keyword, profile_length,
-                                 profile) != 0)
+                                  &png_ptr->colorspace, keyword, profile_length,
+                                  profile) != 0)
                               {
                                  /* The profile has been validated for basic
                                   * security issues, so read the whole thing in.
                                   */
                                  size = profile_length - (sizeof profile_header)
-                                    - 12 * tag_count;
+                                     - 12 * tag_count;
 
                                  (void)png_inflate_read(png_ptr, local_buffer,
-                                    (sizeof local_buffer), &length,
-                                    profile + (sizeof profile_header) +
-                                    12 * tag_count, &size, 1/*finish*/);
+                                     (sizeof local_buffer), &length,
+                                     profile + (sizeof profile_header) +
+                                     12 * tag_count, &size, 1/*finish*/);
 
                                  if (length > 0 && !(png_ptr->flags &
-                                       PNG_FLAG_BENIGN_ERRORS_WARN))
+                                     PNG_FLAG_BENIGN_ERRORS_WARN))
                                     errmsg = "extra compressed data";
 
                                  /* But otherwise allow extra data: */
@@ -1506,34 +1527,34 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                                         * keep going.
                                         */
                                        png_chunk_warning(png_ptr,
-                                          "extra compressed data");
+                                           "extra compressed data");
                                     }
 
                                     png_crc_finish(png_ptr, length);
                                     finished = 1;
 
-#                                   ifdef PNG_sRGB_SUPPORTED
+# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
                                     /* Check for a match against sRGB */
                                     png_icc_set_sRGB(png_ptr,
-                                       &png_ptr->colorspace, profile,
-                                       png_ptr->zstream.adler);
-#                                   endif
+                                        &png_ptr->colorspace, profile,
+                                        png_ptr->zstream.adler);
+# endif
 
                                     /* Steal the profile for info_ptr. */
                                     if (info_ptr != NULL)
                                     {
                                        png_free_data(png_ptr, info_ptr,
-                                          PNG_FREE_ICCP, 0);
+                                           PNG_FREE_ICCP, 0);
 
                                        info_ptr->iccp_name = png_voidcast(char*,
-                                          png_malloc_base(png_ptr,
-                                          keyword_length+1));
+                                           png_malloc_base(png_ptr,
+                                           keyword_length+1));
                                        if (info_ptr->iccp_name != NULL)
                                        {
                                           memcpy(info_ptr->iccp_name, keyword,
-                                             keyword_length+1);
+                                              keyword_length+1);
                                           info_ptr->iccp_proflen =
-                                             profile_length;
+                                              profile_length;
                                           info_ptr->iccp_profile = profile;
                                           png_ptr->read_buffer = NULL; /*steal*/
                                           info_ptr->free_me |= PNG_FREE_ICCP;
@@ -1562,19 +1583,11 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                                        return;
                                     }
                                  }
-
-                                 else if (size > 0)
-                                    errmsg = "truncated";
-
-#ifndef __COVERITY__
-                                 else
+                                 if (errmsg == NULL)
                                     errmsg = png_ptr->zstream.msg;
-#endif
                               }
-
                               /* else png_icc_check_tag_table output an error */
                            }
-
                            else /* profile truncated */
                               errmsg = png_ptr->zstream.msg;
                         }
@@ -1634,7 +1647,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    int entry_size, i;
    png_uint_32 skip = 0;
    png_uint_32 dl;
-   png_size_t max_dl;
+   size_t max_dl;
 
    png_debug(1, "in png_handle_sPLT");
 
@@ -1715,13 +1728,13 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    data_length = length - (png_uint_32)(entry_start - buffer);
 
    /* Integrity-check the data length */
-   if ((data_length % entry_size) != 0)
+   if ((data_length % (unsigned int)entry_size) != 0)
    {
       png_warning(png_ptr, "sPLT chunk has bad length");
       return;
    }
 
-   dl = (png_int_32)(data_length / entry_size);
+   dl = (png_uint_32)(data_length / (unsigned int)entry_size);
    max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
 
    if (dl > max_dl)
@@ -1730,10 +1743,10 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       return;
    }
 
-   new_palette.nentries = (png_int_32)(data_length / entry_size);
+   new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size);
 
-   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
-       png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)));
+   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
+       (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry)));
 
    if (new_palette.entries == NULL)
    {
@@ -1983,6 +1996,15 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */
    {
+      if (png_ptr->bit_depth <= 8)
+      {
+         if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth))
+         {
+            png_chunk_benign_error(png_ptr, "invalid gray level");
+            return;
+         }
+      }
+
       background.index = 0;
       background.red =
       background.green =
@@ -1992,6 +2014,15 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    else
    {
+      if (png_ptr->bit_depth <= 8)
+      {
+         if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0)
+         {
+            png_chunk_benign_error(png_ptr, "invalid color");
+            return;
+         }
+      }
+
       background.index = 0;
       background.red = png_get_uint_16(buf);
       background.green = png_get_uint_16(buf + 2);
@@ -2003,6 +2034,69 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 }
 #endif
 
+#ifdef PNG_READ_eXIf_SUPPORTED
+void /* PRIVATE */
+png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+   unsigned int i;
+
+   png_debug(1, "in png_handle_eXIf");
+
+   if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+      png_chunk_error(png_ptr, "missing IHDR");
+
+   if (length < 2)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "too short");
+      return;
+   }
+
+   else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "duplicate");
+      return;
+   }
+
+   info_ptr->free_me |= PNG_FREE_EXIF;
+
+   info_ptr->eXIf_buf = png_voidcast(png_bytep,
+             png_malloc_warn(png_ptr, length));
+
+   if (info_ptr->eXIf_buf == NULL)
+   {
+      png_crc_finish(png_ptr, length);
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
+   }
+
+   for (i = 0; i < length; i++)
+   {
+      png_byte buf[1];
+      png_crc_read(png_ptr, buf, 1);
+      info_ptr->eXIf_buf[i] = buf[0];
+      if (i == 1 && buf[0] != 'M' && buf[0] != 'I'
+                 && info_ptr->eXIf_buf[0] != buf[0])
+      {
+         png_crc_finish(png_ptr, length);
+         png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
+         png_free(png_ptr, info_ptr->eXIf_buf);
+         info_ptr->eXIf_buf = NULL;
+         return;
+      }
+   }
+
+   if (png_crc_finish(png_ptr, 0) != 0)
+      return;
+
+   png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
+
+   png_free(png_ptr, info_ptr->eXIf_buf);
+   info_ptr->eXIf_buf = NULL;
+}
+#endif
+
 #ifdef PNG_READ_hIST_SUPPORTED
 void /* PRIVATE */
 png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
@@ -2270,7 +2364,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    }
 
    png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
-      (png_charp)units, params);
+       (png_charp)units, params);
 
    png_free(png_ptr, params);
 }
@@ -2282,7 +2376,7 @@ void /* PRIVATE */
 png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 {
    png_bytep buffer;
-   png_size_t i;
+   size_t i;
    int state;
 
    png_debug(1, "in png_handle_sCAL");
@@ -2313,7 +2407,7 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    }
 
    png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
-      length + 1);
+       length + 1);
 
    buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
 
@@ -2352,7 +2446,7 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    else
    {
-      png_size_t heighti = i;
+      size_t heighti = i;
 
       state = 0;
       if (png_check_fp_number((png_const_charp)buffer, length,
@@ -2365,7 +2459,7 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       else
          /* This is the (only) success case. */
          png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
-            (png_charp)buffer+1, (png_charp)buffer+heighti);
+             (png_charp)buffer+1, (png_charp)buffer+heighti);
    }
 }
 #endif
@@ -2465,8 +2559,8 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 
    if (buffer == NULL)
    {
-     png_chunk_benign_error(png_ptr, "out of memory");
-     return;
+      png_chunk_benign_error(png_ptr, "out of memory");
+      return;
    }
 
    png_crc_read(png_ptr, buffer, length);
@@ -2531,6 +2625,9 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
       png_ptr->mode |= PNG_AFTER_IDAT;
 
+   /* Note, "length" is sufficient here; we won't be adding
+    * a null terminator later.
+    */
    buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
 
    if (buffer == NULL)
@@ -2573,27 +2670,32 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
        * and text chunks.
        */
       if (png_decompress_chunk(png_ptr, length, keyword_length+2,
-         &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+          &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
       {
          png_text text;
 
-         /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except
-          * for the extra compression type byte and the fact that it isn't
-          * necessarily '\0' terminated.
-          */
-         buffer = png_ptr->read_buffer;
-         buffer[uncompressed_length+(keyword_length+2)] = 0;
-
-         text.compression = PNG_TEXT_COMPRESSION_zTXt;
-         text.key = (png_charp)buffer;
-         text.text = (png_charp)(buffer + keyword_length+2);
-         text.text_length = uncompressed_length;
-         text.itxt_length = 0;
-         text.lang = NULL;
-         text.lang_key = NULL;
-
-         if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
-            errmsg = "insufficient memory";
+         if (png_ptr->read_buffer == NULL)
+           errmsg="Read failure in png_handle_zTXt";
+         else
+         {
+            /* It worked; png_ptr->read_buffer now looks like a tEXt chunk
+             * except for the extra compression type byte and the fact that
+             * it isn't necessarily '\0' terminated.
+             */
+            buffer = png_ptr->read_buffer;
+            buffer[uncompressed_length+(keyword_length+2)] = 0;
+
+            text.compression = PNG_TEXT_COMPRESSION_zTXt;
+            text.key = (png_charp)buffer;
+            text.text = (png_charp)(buffer + keyword_length+2);
+            text.text_length = uncompressed_length;
+            text.itxt_length = 0;
+            text.lang = NULL;
+            text.lang_key = NULL;
+
+            if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
+               errmsg = "insufficient memory";
+         }
       }
 
       else
@@ -2713,7 +2815,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
           * iCCP and text chunks.
           */
          if (png_decompress_chunk(png_ptr, length, prefix_length,
-            &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+             &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
             buffer = png_ptr->read_buffer;
 
          else
@@ -2782,7 +2884,7 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
    {
       PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
       /* The following is safe because of the PNG_SIZE_MAX init above */
-      png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;
+      png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/;
       /* 'mode' is a flag array, only the bottom four bits matter here */
       png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
 
@@ -2793,7 +2895,7 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
       {
          /* Do a 'warn' here - it is handled below. */
          png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
-            png_malloc_warn(png_ptr, length));
+             png_malloc_warn(png_ptr, length));
       }
    }
 
@@ -2818,7 +2920,7 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
 /* Handle an unknown, or known but disabled, chunk */
 void /* PRIVATE */
 png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
-   png_uint_32 length, int keep)
+    png_uint_32 length, int keep)
 {
    int handled = 0; /* the chunk was handled */
 
@@ -2856,7 +2958,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
       {
          /* Callback to user unknown chunk handler */
          int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
-            &png_ptr->unknown_chunk);
+             &png_ptr->unknown_chunk);
 
          /* ret is:
           * negative: An error occurred; png_chunk_error will be called.
@@ -2890,9 +2992,9 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
                {
                   png_chunk_warning(png_ptr, "Saving unknown chunk:");
                   png_app_warning(png_ptr,
-                     "forcing save of an unhandled chunk;"
-                     " please call png_set_keep_unknown_chunks");
-                     /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+                      "forcing save of an unhandled chunk;"
+                      " please call png_set_keep_unknown_chunks");
+                      /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
                }
 #              endif
                keep = PNG_HANDLE_CHUNK_IF_SAFE;
@@ -2969,7 +3071,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
          case 2:
             png_ptr->user_chunk_cache_max = 1;
             png_chunk_benign_error(png_ptr, "no space in chunk cache");
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
          case 1:
             /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
              * chunk being skipped, now there will be a hard error below.
@@ -2978,14 +3080,14 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
 
          default: /* not at limit */
             --(png_ptr->user_chunk_cache_max);
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
          case 0: /* no limit */
 #  endif /* USER_LIMITS */
             /* Here when the limit isn't reached or when limits are compiled
              * out; store the chunk.
              */
             png_set_unknown_chunks(png_ptr, info_ptr,
-               &png_ptr->unknown_chunk, 1);
+                &png_ptr->unknown_chunk, 1);
             handled = 1;
 #  ifdef PNG_USER_LIMITS_SUPPORTED
             break;
@@ -3029,20 +3131,61 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
  */
 
 void /* PRIVATE */
-png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
+png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name)
 {
    int i;
+   png_uint_32 cn=chunk_name;
 
    png_debug(1, "in png_check_chunk_name");
 
    for (i=1; i<=4; ++i)
    {
-      int c = chunk_name & 0xff;
+      int c = cn & 0xff;
 
       if (c < 65 || c > 122 || (c > 90 && c < 97))
          png_chunk_error(png_ptr, "invalid chunk type");
 
-      chunk_name >>= 8;
+      cn >>= 8;
+   }
+}
+
+void /* PRIVATE */
+png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length)
+{
+   png_alloc_size_t limit = PNG_UINT_31_MAX;
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_malloc_max > 0 &&
+       png_ptr->user_chunk_malloc_max < limit)
+      limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+   if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+      limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+   if (png_ptr->chunk_name == png_IDAT)
+   {
+      png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
+      size_t row_factor =
+         (size_t)png_ptr->width
+         * (size_t)png_ptr->channels
+         * (png_ptr->bit_depth > 8? 2: 1)
+         + 1
+         + (png_ptr->interlaced? 6: 0);
+      if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
+         idat_limit = PNG_UINT_31_MAX;
+      else
+         idat_limit = png_ptr->height * row_factor;
+      row_factor = row_factor > 32566? 32566 : row_factor;
+      idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */
+      idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX;
+      limit = limit < idat_limit? idat_limit : limit;
+   }
+
+   if (length > limit)
+   {
+      png_debug2(0," length = %lu, limit = %lu",
+         (unsigned long)length,(unsigned long)limit);
+      png_chunk_error(png_ptr, "chunk data is too large");
    }
 }
 
@@ -3097,7 +3240,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
 #     ifdef PNG_READ_PACKSWAP_SUPPORTED
       if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
          /* little-endian byte */
-         end_mask = 0xff << end_mask;
+         end_mask = (unsigned int)(0xff << end_mask);
 
       else /* big-endian byte */
 #     endif
@@ -3219,7 +3362,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
          /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
           * then pass:
           */
-         static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
+         static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
          {
             /* Little-endian byte masks for PACKSWAP */
             { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
@@ -3230,7 +3373,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
          /* display_mask has only three entries for the odd passes, so index by
           * pass>>1.
           */
-         static PNG_CONST png_uint_32 display_mask[2][3][3] =
+         static const png_uint_32 display_mask[2][3][3] =
          {
             /* Little-endian byte masks for PACKSWAP */
             { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
@@ -3371,7 +3514,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
                 */
                do
                {
-                  dp[0] = sp[0], dp[1] = sp[1];
+                  dp[0] = sp[0]; dp[1] = sp[1];
 
                   if (row_width <= bytes_to_jump)
                      return;
@@ -3392,7 +3535,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
                 */
                for (;;)
                {
-                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
+                  dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2];
 
                   if (row_width <= bytes_to_jump)
                      return;
@@ -3418,8 +3561,8 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
                   /* Everything is aligned for png_uint_16 copies, but try for
                    * png_uint_32 first.
                    */
-                  if (png_isaligned(dp, png_uint_32) != 0 &&
-                      png_isaligned(sp, png_uint_32) != 0 &&
+                  if (png_isaligned(dp, png_uint_32) &&
+                      png_isaligned(sp, png_uint_32) &&
                       bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
                       bytes_to_jump % (sizeof (png_uint_32)) == 0)
                   {
@@ -3539,11 +3682,11 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
 #ifdef PNG_READ_INTERLACING_SUPPORTED
 void /* PRIVATE */
 png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
-   png_uint_32 transformations /* Because these may affect the byte layout */)
+    png_uint_32 transformations /* Because these may affect the byte layout */)
 {
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    /* Offset to next interlace block */
-   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   static const unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
 
    png_debug(1, "in png_do_read_interlace");
    if (row != NULL && row_info != NULL)
@@ -3556,11 +3699,12 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
       {
          case 1:
          {
-            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
-            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
-            int jstop = png_pass_inc[pass];
+            png_bytep sp = row + (size_t)((row_info->width - 1) >> 3);
+            png_bytep dp = row + (size_t)((final_width - 1) >> 3);
+            unsigned int sshift, dshift;
+            unsigned int s_start, s_end;
+            int s_inc;
+            int jstop = (int)png_pass_inc[pass];
             png_byte v;
             png_uint_32 i;
             int j;
@@ -3568,8 +3712,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
 #ifdef PNG_READ_PACKSWAP_SUPPORTED
             if ((transformations & PNG_PACKSWAP) != 0)
             {
-                sshift = (int)((row_info->width + 7) & 0x07);
-                dshift = (int)((final_width + 7) & 0x07);
+                sshift = ((row_info->width + 7) & 0x07);
+                dshift = ((final_width + 7) & 0x07);
                 s_start = 7;
                 s_end = 0;
                 s_inc = -1;
@@ -3578,8 +3722,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
             else
 #endif
             {
-                sshift = 7 - (int)((row_info->width + 7) & 0x07);
-                dshift = 7 - (int)((final_width + 7) & 0x07);
+                sshift = 7 - ((row_info->width + 7) & 0x07);
+                dshift = 7 - ((final_width + 7) & 0x07);
                 s_start = 0;
                 s_end = 7;
                 s_inc = 1;
@@ -3591,7 +3735,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                for (j = 0; j < jstop; j++)
                {
                   unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
-                  tmp |= v << dshift;
+                  tmp |= (unsigned int)(v << dshift);
                   *dp = (png_byte)(tmp & 0xff);
 
                   if (dshift == s_end)
@@ -3601,7 +3745,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                   }
 
                   else
-                     dshift += s_inc;
+                     dshift = (unsigned int)((int)dshift + s_inc);
                }
 
                if (sshift == s_end)
@@ -3611,7 +3755,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                }
 
                else
-                  sshift += s_inc;
+                  sshift = (unsigned int)((int)sshift + s_inc);
             }
             break;
          }
@@ -3620,16 +3764,17 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
          {
             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
-            int jstop = png_pass_inc[pass];
+            unsigned int sshift, dshift;
+            unsigned int s_start, s_end;
+            int s_inc;
+            int jstop = (int)png_pass_inc[pass];
             png_uint_32 i;
 
 #ifdef PNG_READ_PACKSWAP_SUPPORTED
             if ((transformations & PNG_PACKSWAP) != 0)
             {
-               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
-               dshift = (int)(((final_width + 3) & 0x03) << 1);
+               sshift = (((row_info->width + 3) & 0x03) << 1);
+               dshift = (((final_width + 3) & 0x03) << 1);
                s_start = 6;
                s_end = 0;
                s_inc = -2;
@@ -3638,8 +3783,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
             else
 #endif
             {
-               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
-               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+               sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1);
+               dshift = ((3 - ((final_width + 3) & 0x03)) << 1);
                s_start = 0;
                s_end = 6;
                s_inc = 2;
@@ -3654,7 +3799,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                for (j = 0; j < jstop; j++)
                {
                   unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
-                  tmp |= v << dshift;
+                  tmp |= (unsigned int)(v << dshift);
                   *dp = (png_byte)(tmp & 0xff);
 
                   if (dshift == s_end)
@@ -3664,7 +3809,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                   }
 
                   else
-                     dshift += s_inc;
+                     dshift = (unsigned int)((int)dshift + s_inc);
                }
 
                if (sshift == s_end)
@@ -3674,25 +3819,26 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                }
 
                else
-                  sshift += s_inc;
+                  sshift = (unsigned int)((int)sshift + s_inc);
             }
             break;
          }
 
          case 4:
          {
-            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
-            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
-            int sshift, dshift;
-            int s_start, s_end, s_inc;
+            png_bytep sp = row + (size_t)((row_info->width - 1) >> 1);
+            png_bytep dp = row + (size_t)((final_width - 1) >> 1);
+            unsigned int sshift, dshift;
+            unsigned int s_start, s_end;
+            int s_inc;
             png_uint_32 i;
-            int jstop = png_pass_inc[pass];
+            int jstop = (int)png_pass_inc[pass];
 
 #ifdef PNG_READ_PACKSWAP_SUPPORTED
             if ((transformations & PNG_PACKSWAP) != 0)
             {
-               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
-               dshift = (int)(((final_width + 1) & 0x01) << 2);
+               sshift = (((row_info->width + 1) & 0x01) << 2);
+               dshift = (((final_width + 1) & 0x01) << 2);
                s_start = 4;
                s_end = 0;
                s_inc = -4;
@@ -3701,8 +3847,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
             else
 #endif
             {
-               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
-               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+               sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2);
+               dshift = ((1 - ((final_width + 1) & 0x01)) << 2);
                s_start = 0;
                s_end = 4;
                s_inc = 4;
@@ -3716,7 +3862,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                for (j = 0; j < jstop; j++)
                {
                   unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
-                  tmp |= v << dshift;
+                  tmp |= (unsigned int)(v << dshift);
                   *dp = (png_byte)(tmp & 0xff);
 
                   if (dshift == s_end)
@@ -3726,7 +3872,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                   }
 
                   else
-                     dshift += s_inc;
+                     dshift = (unsigned int)((int)dshift + s_inc);
                }
 
                if (sshift == s_end)
@@ -3736,21 +3882,21 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
                }
 
                else
-                  sshift += s_inc;
+                  sshift = (unsigned int)((int)sshift + s_inc);
             }
             break;
          }
 
          default:
          {
-            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+            size_t pixel_bytes = (row_info->pixel_depth >> 3);
 
-            png_bytep sp = row + (png_size_t)(row_info->width - 1)
+            png_bytep sp = row + (size_t)(row_info->width - 1)
                 * pixel_bytes;
 
-            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+            png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes;
 
-            int jstop = png_pass_inc[pass];
+            int jstop = (int)png_pass_inc[pass];
             png_uint_32 i;
 
             for (i = 0; i < row_info->width; i++)
@@ -3783,10 +3929,10 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
 
 static void
 png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
-   png_size_t i;
-   png_size_t istop = row_info->rowbytes;
+   size_t i;
+   size_t istop = row_info->rowbytes;
    unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
    png_bytep rp = row + bpp;
 
@@ -3801,10 +3947,10 @@ png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
 
 static void
 png_read_filter_row_up(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
-   png_size_t i;
-   png_size_t istop = row_info->rowbytes;
+   size_t i;
+   size_t istop = row_info->rowbytes;
    png_bytep rp = row;
    png_const_bytep pp = prev_row;
 
@@ -3817,13 +3963,13 @@ png_read_filter_row_up(png_row_infop row_info, png_bytep row,
 
 static void
 png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
-   png_size_t i;
+   size_t i;
    png_bytep rp = row;
    png_const_bytep pp = prev_row;
    unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
-   png_size_t istop = row_info->rowbytes - bpp;
+   size_t istop = row_info->rowbytes - bpp;
 
    for (i = 0; i < bpp; i++)
    {
@@ -3844,7 +3990,7 @@ png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
 
 static void
 png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
    png_bytep rp_end = row + row_info->rowbytes;
    int a, c;
@@ -3878,7 +4024,10 @@ png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
       /* Find the best predictor, the least of pa, pb, pc favoring the earlier
        * ones in the case of a tie.
        */
-      if (pb < pa) pa = pb, a = b;
+      if (pb < pa)
+      {
+         pa = pb; a = b;
+      }
       if (pc < pa) a = c;
 
       /* Calculate the current pixel in a, and move the previous row pixel to c
@@ -3892,9 +4041,9 @@ png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
 
 static void
 png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row)
+    png_const_bytep prev_row)
 {
-   int bpp = (row_info->pixel_depth + 7) >> 3;
+   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
    png_bytep rp_end = row + bpp;
 
    /* Process the first pixel in the row completely (this is the same as 'up'
@@ -3907,7 +4056,7 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
    }
 
    /* Remainder */
-   rp_end += row_info->rowbytes - bpp;
+   rp_end = rp_end + (row_info->rowbytes - bpp);
 
    while (row < rp_end)
    {
@@ -3930,7 +4079,10 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
       pc = (p + pc) < 0 ? -(p + pc) : p + pc;
 #endif
 
-      if (pb < pa) pa = pb, a = b;
+      if (pb < pa)
+      {
+         pa = pb; a = b;
+      }
       if (pc < pa) a = c;
 
       a += *row;
@@ -3977,7 +4129,7 @@ png_init_filter_functions(png_structrp pp)
 
 void /* PRIVATE */
 png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
-   png_const_bytep prev_row, int filter)
+    png_const_bytep prev_row, int filter)
 {
    /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
     * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
@@ -3995,7 +4147,7 @@ png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 void /* PRIVATE */
 png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
-   png_alloc_size_t avail_out)
+    png_alloc_size_t avail_out)
 {
    /* Loop reading IDATs and decompressing the result into output[avail_out] */
    png_ptr->zstream.next_out = output;
@@ -4176,16 +4328,16 @@ png_read_finish_row(png_structrp png_ptr)
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
 
    /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
 
    /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
 
    /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+   static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
 
    png_debug(1, "in png_read_finish_row");
    png_ptr->row_number++;
@@ -4241,19 +4393,19 @@ png_read_start_row(png_structrp png_ptr)
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
 
    /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
 
    /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
 
    /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+   static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
 
-   int max_pixel_depth;
-   png_size_t row_bytes;
+   unsigned int max_pixel_depth;
+   size_t row_bytes;
 
    png_debug(1, "in png_read_start_row");
 
@@ -4281,7 +4433,7 @@ png_read_start_row(png_structrp png_ptr)
       png_ptr->iwidth = png_ptr->width;
    }
 
-   max_pixel_depth = png_ptr->pixel_depth;
+   max_pixel_depth = (unsigned int)png_ptr->pixel_depth;
 
    /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of
     * calculations to calculate the final pixel depth, then
@@ -4416,7 +4568,7 @@ png_read_start_row(png_structrp png_ptr)
 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
    if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
    {
-      int user_pixel_depth = png_ptr->user_transform_depth *
+      unsigned int user_pixel_depth = png_ptr->user_transform_depth *
          png_ptr->user_transform_channels;
 
       if (user_pixel_depth > max_pixel_depth)
@@ -4438,7 +4590,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
     * for safety's sake
     */
    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
-       1 + ((max_pixel_depth + 7) >> 3);
+       1 + ((max_pixel_depth + 7) >> 3U);
 
 #ifdef PNG_MAX_MALLOC_64K
    if (row_bytes > (png_uint_32)65536L)
@@ -4447,42 +4599,42 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
 
    if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
    {
-     png_free(png_ptr, png_ptr->big_row_buf);
-     png_free(png_ptr, png_ptr->big_prev_row);
+      png_free(png_ptr, png_ptr->big_row_buf);
+      png_free(png_ptr, png_ptr->big_prev_row);
 
-     if (png_ptr->interlaced != 0)
-        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
-            row_bytes + 48);
+      if (png_ptr->interlaced != 0)
+         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+             row_bytes + 48);
 
-     else
-        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+      else
+         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
 
-     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+      png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
 
 #ifdef PNG_ALIGNED_MEMORY_SUPPORTED
-     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
-      * of padding before and after row_buf; treat prev_row similarly.
-      * NOTE: the alignment is to the start of the pixels, one beyond the start
-      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
-      * was incorrect; the filter byte was aligned, which had the exact
-      * opposite effect of that intended.
-      */
-     {
-        png_bytep temp = png_ptr->big_row_buf + 32;
-        int extra = (int)((temp - (png_bytep)0) & 0x0f);
-        png_ptr->row_buf = temp - extra - 1/*filter byte*/;
-
-        temp = png_ptr->big_prev_row + 32;
-        extra = (int)((temp - (png_bytep)0) & 0x0f);
-        png_ptr->prev_row = temp - extra - 1/*filter byte*/;
-     }
+      /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+       * of padding before and after row_buf; treat prev_row similarly.
+       * NOTE: the alignment is to the start of the pixels, one beyond the start
+       * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
+       * was incorrect; the filter byte was aligned, which had the exact
+       * opposite effect of that intended.
+       */
+      {
+         png_bytep temp = png_ptr->big_row_buf + 32;
+         int extra = (int)((temp - (png_bytep)0) & 0x0f);
+         png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+
+         temp = png_ptr->big_prev_row + 32;
+         extra = (int)((temp - (png_bytep)0) & 0x0f);
+         png_ptr->prev_row = temp - extra - 1/*filter byte*/;
+      }
 
 #else
-     /* Use 31 bytes of padding before and 17 bytes after row_buf. */
-     png_ptr->row_buf = png_ptr->big_row_buf + 31;
-     png_ptr->prev_row = png_ptr->big_prev_row + 31;
+      /* Use 31 bytes of padding before and 17 bytes after row_buf. */
+      png_ptr->row_buf = png_ptr->big_row_buf + 31;
+      png_ptr->prev_row = png_ptr->big_prev_row + 31;
 #endif
-     png_ptr->old_big_row_buf_size = row_bytes + 48;
+      png_ptr->old_big_row_buf_size = row_bytes + 48;
    }
 
 #ifdef PNG_MAX_MALLOC_64K
@@ -4507,7 +4659,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
     * does not, so free the read buffer now regardless; the sequential reader
     * reallocates it on demand.
     */
-   if (png_ptr->read_buffer != 0)
+   if (png_ptr->read_buffer != NULL)
    {
       png_bytep buffer = png_ptr->read_buffer;
 
index 4bd5ab3..ec75dbe 100644 (file)
--- a/pngset.c
+++ b/pngset.c
@@ -1,10 +1,10 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 1998-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -104,14 +104,14 @@ png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
     double green_x, double green_y, double blue_x, double blue_y)
 {
    png_set_cHRM_fixed(png_ptr, info_ptr,
-      png_fixed(png_ptr, white_x, "cHRM White X"),
-      png_fixed(png_ptr, white_y, "cHRM White Y"),
-      png_fixed(png_ptr, red_x, "cHRM Red X"),
-      png_fixed(png_ptr, red_y, "cHRM Red Y"),
-      png_fixed(png_ptr, green_x, "cHRM Green X"),
-      png_fixed(png_ptr, green_y, "cHRM Green Y"),
-      png_fixed(png_ptr, blue_x, "cHRM Blue X"),
-      png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
+       png_fixed(png_ptr, white_x, "cHRM White X"),
+       png_fixed(png_ptr, white_y, "cHRM White Y"),
+       png_fixed(png_ptr, red_x, "cHRM Red X"),
+       png_fixed(png_ptr, red_y, "cHRM Red Y"),
+       png_fixed(png_ptr, green_x, "cHRM Green X"),
+       png_fixed(png_ptr, green_y, "cHRM Green Y"),
+       png_fixed(png_ptr, blue_x, "cHRM Blue X"),
+       png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
 }
 
 void PNGAPI
@@ -120,20 +120,67 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
     double blue_X, double blue_Y, double blue_Z)
 {
    png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
-      png_fixed(png_ptr, red_X, "cHRM Red X"),
-      png_fixed(png_ptr, red_Y, "cHRM Red Y"),
-      png_fixed(png_ptr, red_Z, "cHRM Red Z"),
-      png_fixed(png_ptr, green_X, "cHRM Green X"),
-      png_fixed(png_ptr, green_Y, "cHRM Green Y"),
-      png_fixed(png_ptr, green_Z, "cHRM Green Z"),
-      png_fixed(png_ptr, blue_X, "cHRM Blue X"),
-      png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
-      png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
+       png_fixed(png_ptr, red_X, "cHRM Red X"),
+       png_fixed(png_ptr, red_Y, "cHRM Red Y"),
+       png_fixed(png_ptr, red_Z, "cHRM Red Z"),
+       png_fixed(png_ptr, green_X, "cHRM Green X"),
+       png_fixed(png_ptr, green_Y, "cHRM Green Y"),
+       png_fixed(png_ptr, green_Z, "cHRM Green Z"),
+       png_fixed(png_ptr, blue_X, "cHRM Blue X"),
+       png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
+       png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
 }
 #  endif /* FLOATING_POINT */
 
 #endif /* cHRM */
 
+#ifdef PNG_eXIf_SUPPORTED
+void PNGAPI
+png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_bytep eXIf_buf)
+{
+  png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
+  PNG_UNUSED(info_ptr)
+  PNG_UNUSED(eXIf_buf)
+}
+
+void PNGAPI
+png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_uint_32 num_exif, png_bytep eXIf_buf)
+{
+   int i;
+
+   png_debug1(1, "in %s storage function", "eXIf");
+
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   if (info_ptr->exif)
+   {
+      png_free(png_ptr, info_ptr->exif);
+      info_ptr->exif = NULL;
+   }
+
+   info_ptr->num_exif = num_exif;
+
+   info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
+       info_ptr->num_exif));
+
+   if (info_ptr->exif == NULL)
+   {
+      png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
+      return;
+   }
+
+   info_ptr->free_me |= PNG_FREE_EXIF;
+
+   for (i = 0; i < (int) info_ptr->num_exif; i++)
+      info_ptr->exif[i] = eXIf_buf[i];
+
+   info_ptr->valid |= PNG_INFO_eXIf;
+}
+#endif /* eXIf */
+
 #ifdef PNG_gAMA_SUPPORTED
 void PNGFAPI
 png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
@@ -266,7 +313,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
     png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
     int nparams, png_const_charp units, png_charpp params)
 {
-   png_size_t length;
+   size_t length;
    int i;
 
    png_debug1(1, "in %s storage function", "pCAL");
@@ -283,17 +330,29 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
 
    /* Check that the type matches the specification. */
    if (type < 0 || type > 3)
-      png_error(png_ptr, "Invalid pCAL equation type");
+   {
+      png_chunk_report(png_ptr, "Invalid pCAL equation type",
+            PNG_CHUNK_WRITE_ERROR);
+      return;
+   }
 
    if (nparams < 0 || nparams > 255)
-      png_error(png_ptr, "Invalid pCAL parameter count");
+   {
+      png_chunk_report(png_ptr, "Invalid pCAL parameter count",
+            PNG_CHUNK_WRITE_ERROR);
+      return;
+   }
 
    /* Validate params[nparams] */
    for (i=0; i<nparams; ++i)
    {
       if (params[i] == NULL ||
           !png_check_fp_string(params[i], strlen(params[i])))
-         png_error(png_ptr, "Invalid format for pCAL parameter");
+      {
+         png_chunk_report(png_ptr, "Invalid format for pCAL parameter",
+               PNG_CHUNK_WRITE_ERROR);
+         return;
+      }
    }
 
    info_ptr->pcal_purpose = png_voidcast(png_charp,
@@ -301,8 +360,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
 
    if (info_ptr->pcal_purpose == NULL)
    {
-      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
-
+      png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
+            PNG_CHUNK_WRITE_ERROR);
       return;
    }
 
@@ -316,10 +375,10 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
 
    length = strlen(units) + 1;
    png_debug1(3, "allocating units for info (%lu bytes)",
-     (unsigned long)length);
+       (unsigned long)length);
 
    info_ptr->pcal_units = png_voidcast(png_charp,
-      png_malloc_warn(png_ptr, length));
+       png_malloc_warn(png_ptr, length));
 
    if (info_ptr->pcal_units == NULL)
    {
@@ -331,7 +390,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
    memcpy(info_ptr->pcal_units, units, length);
 
    info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
-       (png_size_t)((nparams + 1) * (sizeof (png_charp)))));
+       (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
 
    if (info_ptr->pcal_params == NULL)
    {
@@ -340,7 +399,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
       return;
    }
 
-   memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));
+   memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
+       (sizeof (png_charp)));
 
    for (i = 0; i < nparams; i++)
    {
@@ -370,7 +430,7 @@ void PNGAPI
 png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
     int unit, png_const_charp swidth, png_const_charp sheight)
 {
-   png_size_t lengthw = 0, lengthh = 0;
+   size_t lengthw = 0, lengthh = 0;
 
    png_debug1(1, "in %s storage function", "sCAL");
 
@@ -398,7 +458,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
    png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
 
    info_ptr->scal_s_width = png_voidcast(png_charp,
-      png_malloc_warn(png_ptr, lengthw));
+       png_malloc_warn(png_ptr, lengthw));
 
    if (info_ptr->scal_s_width == NULL)
    {
@@ -414,7 +474,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
    png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
 
    info_ptr->scal_s_height = png_voidcast(png_charp,
-      png_malloc_warn(png_ptr, lengthh));
+       png_malloc_warn(png_ptr, lengthh));
 
    if (info_ptr->scal_s_height == NULL)
    {
@@ -453,9 +513,9 @@ png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
       char sheight[PNG_sCAL_MAX_DIGITS+1];
 
       png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
-         PNG_sCAL_PRECISION);
+          PNG_sCAL_PRECISION);
       png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
-         PNG_sCAL_PRECISION);
+          PNG_sCAL_PRECISION);
 
       png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
    }
@@ -563,7 +623,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
        PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
 
    if (num_palette > 0)
-      memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
+      memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
+          (sizeof (png_color)));
    info_ptr->palette = png_ptr->palette;
    info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
 
@@ -630,7 +691,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
 {
    png_charp new_iccp_name;
    png_bytep new_iccp_profile;
-   png_size_t length;
+   size_t length;
 
    png_debug1(1, "in %s storage function", "iCCP");
 
@@ -648,7 +709,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
     */
    {
       int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
-         proflen, profile, info_ptr->color_type);
+          proflen, profile, info_ptr->color_type);
 
       png_colorspace_sync_info(png_ptr, info_ptr);
 
@@ -673,7 +734,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
 
    memcpy(new_iccp_name, name, length);
    new_iccp_profile = png_voidcast(png_bytep,
-      png_malloc_warn(png_ptr, proflen));
+       png_malloc_warn(png_ptr, proflen));
 
    if (new_iccp_profile == NULL)
    {
@@ -748,14 +809,14 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
           * the overflow checks.
           */
          new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
-            info_ptr->text, old_num_text, max_text-old_num_text,
-            sizeof *new_text));
+             info_ptr->text, old_num_text, max_text-old_num_text,
+             sizeof *new_text));
       }
 
       if (new_text == NULL)
       {
          png_chunk_report(png_ptr, "too many text chunks",
-            PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
 
          return 1;
       }
@@ -783,7 +844,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
           text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
       {
          png_chunk_report(png_ptr, "text compression mode is out of range",
-            PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
          continue;
       }
 
@@ -815,7 +876,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
 #  else /* iTXt */
       {
          png_chunk_report(png_ptr, "iTXt chunk not supported",
-            PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
          continue;
       }
 #  endif
@@ -844,7 +905,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
       if (textp->key == NULL)
       {
          png_chunk_report(png_ptr, "text chunk: out of memory",
-               PNG_CHUNK_WRITE_ERROR);
+             PNG_CHUNK_WRITE_ERROR);
 
          return 1;
       }
@@ -952,12 +1013,14 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
 
        png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
 
-       /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
-       png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
-         png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
-
        if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
-          memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
+       {
+         /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+          info_ptr->trans_alpha = png_voidcast(png_bytep,
+              png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
+          memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
+       }
+       png_ptr->trans_alpha = info_ptr->trans_alpha;
    }
 
    if (trans_color != NULL)
@@ -974,7 +1037,7 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
              trans_color->green > sample_max ||
              trans_color->blue > sample_max)))
             png_warning(png_ptr,
-               "tRNS chunk has out-of-range samples for bit_depth");
+                "tRNS chunk has out-of-range samples for bit_depth");
       }
 #endif
 
@@ -1016,8 +1079,8 @@ png_set_sPLT(png_const_structrp png_ptr,
     * overflows.  Notice that the parameters are (int) and (size_t)
     */
    np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
-      info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
-      sizeof *np));
+       info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
+       sizeof *np));
 
    if (np == NULL)
    {
@@ -1035,7 +1098,7 @@ png_set_sPLT(png_const_structrp png_ptr,
 
    do
    {
-      png_size_t length;
+      size_t length;
 
       /* Skip invalid input entries */
       if (entries->name == NULL || entries->entries == NULL)
@@ -1078,7 +1141,7 @@ png_set_sPLT(png_const_structrp png_ptr,
        * checked it when doing the allocation.
        */
       memcpy(np->entries, entries->entries,
-         entries->nentries * sizeof (png_sPLT_entry));
+          (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
 
       /* Note that 'continue' skips the advance of the out pointer and out
        * count, so an invalid entry is not added.
@@ -1086,8 +1149,9 @@ png_set_sPLT(png_const_structrp png_ptr,
       info_ptr->valid |= PNG_INFO_sPLT;
       ++(info_ptr->splt_palettes_num);
       ++np;
+      ++entries;
    }
-   while (++entries, --nentries);
+   while (--nentries);
 
    if (nentries > 0)
       png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
@@ -1108,10 +1172,10 @@ check_location(png_const_structrp png_ptr, int location)
    {
       /* Write struct, so unknown chunks come from the app */
       png_app_warning(png_ptr,
-         "png_set_unknown_chunks now expects a valid location");
+          "png_set_unknown_chunks now expects a valid location");
       /* Use the old behavior */
       location = (png_byte)(png_ptr->mode &
-         (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
+          (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
    }
 
    /* This need not be an internal error - if the app calls
@@ -1134,7 +1198,7 @@ check_location(png_const_structrp png_ptr, int location)
 
 void PNGAPI
 png_set_unknown_chunks(png_const_structrp png_ptr,
-   png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
+    png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
 {
    png_unknown_chunkp np;
 
@@ -1173,13 +1237,13 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
     * appropriate to read or write.
     */
    np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
-         info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
-         sizeof *np));
+       info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
+       sizeof *np));
 
    if (np == NULL)
    {
       png_chunk_report(png_ptr, "too many unknown chunks",
-         PNG_CHUNK_WRITE_ERROR);
+          PNG_CHUNK_WRITE_ERROR);
 
       return;
    }
@@ -1208,12 +1272,12 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
       else
       {
          np->data = png_voidcast(png_bytep,
-            png_malloc_base(png_ptr, unknowns->size));
+             png_malloc_base(png_ptr, unknowns->size));
 
          if (np->data == NULL)
          {
             png_chunk_report(png_ptr, "unknown chunk: out of memory",
-               PNG_CHUNK_WRITE_ERROR);
+                PNG_CHUNK_WRITE_ERROR);
             /* But just skip storing the unknown chunk */
             continue;
          }
@@ -1247,7 +1311,7 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
       {
          png_app_error(png_ptr, "invalid unknown chunk location");
          /* Fake out the pre 1.6.0 behavior: */
-         if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */
+         if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
             location = PNG_AFTER_IDAT;
 
          else
@@ -1335,9 +1399,10 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
       /* Ignore all unknown chunks and all chunks recognized by
        * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
        */
-      static PNG_CONST png_byte chunks_to_ignore[] = {
+      static const png_byte chunks_to_ignore[] = {
          98,  75,  71,  68, '\0',  /* bKGD */
          99,  72,  82,  77, '\0',  /* cHRM */
+        101,  88,  73, 102, '\0',  /* eXIf */
         103,  65,  77,  65, '\0',  /* gAMA */
         104,  73,  83,  84, '\0',  /* hIST */
         105,  67,  67,  80, '\0',  /* iCCP */
@@ -1371,7 +1436,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
          return;
       }
 
-      num_chunks = num_chunks_in;
+      num_chunks = (unsigned int)num_chunks_in;
    }
 
    old_num_chunks = png_ptr->num_chunk_list;
@@ -1420,7 +1485,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
       for (i=0; i<num_chunks; ++i)
       {
          old_num_chunks = add_one_chunk(new_list, old_num_chunks,
-            chunk_list+5*i, keep);
+             chunk_list+5*i, keep);
       }
 
       /* Now remove any spurious 'default' entries. */
@@ -1498,62 +1563,62 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
 #endif
 
 void PNGAPI
-png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
+png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
 {
-    if (png_ptr == NULL)
-       return;
+   if (png_ptr == NULL)
+      return;
 
-    if (size == 0 || size > PNG_UINT_31_MAX)
-       png_error(png_ptr, "invalid compression buffer size");
+   if (size == 0 || size > PNG_UINT_31_MAX)
+      png_error(png_ptr, "invalid compression buffer size");
 
 #  ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
-      {
-         png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
-         return;
-      }
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+   {
+      png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
+      return;
+   }
 #  endif
 
 #  ifdef PNG_WRITE_SUPPORTED
-      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+   if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+   {
+      if (png_ptr->zowner != 0)
       {
-         if (png_ptr->zowner != 0)
-         {
-            png_warning(png_ptr,
-              "Compression buffer size cannot be changed because it is in use");
+         png_warning(png_ptr,
+             "Compression buffer size cannot be changed because it is in use");
 
-            return;
-         }
+         return;
+      }
 
 #ifndef __COVERITY__
-         /* Some compilers complain that this is always false.  However, it
-          * can be true when integer overflow happens.
-          */
-         if (size > ZLIB_IO_MAX)
-         {
-            png_warning(png_ptr,
-               "Compression buffer size limited to system maximum");
-            size = ZLIB_IO_MAX; /* must fit */
-         }
+      /* Some compilers complain that this is always false.  However, it
+       * can be true when integer overflow happens.
+       */
+      if (size > ZLIB_IO_MAX)
+      {
+         png_warning(png_ptr,
+             "Compression buffer size limited to system maximum");
+         size = ZLIB_IO_MAX; /* must fit */
+      }
 #endif
 
-         if (size < 6)
-         {
-            /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
-             * if this is permitted.
-             */
-            png_warning(png_ptr,
-               "Compression buffer size cannot be reduced below 6");
+      if (size < 6)
+      {
+         /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
+          * if this is permitted.
+          */
+         png_warning(png_ptr,
+             "Compression buffer size cannot be reduced below 6");
 
-            return;
-         }
+         return;
+      }
 
-         if (png_ptr->zbuffer_size != size)
-         {
-            png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
-            png_ptr->zbuffer_size = (uInt)size;
-         }
+      if (png_ptr->zbuffer_size != size)
+      {
+         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+         png_ptr->zbuffer_size = (uInt)size;
       }
+   }
 #  endif
 }
 
@@ -1561,7 +1626,7 @@ void PNGAPI
 png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
 {
    if (png_ptr != NULL && info_ptr != NULL)
-      info_ptr->valid &= ~mask;
+      info_ptr->valid &= (unsigned int)(~mask);
 }
 
 
@@ -1660,7 +1725,9 @@ png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
 png_uint_32 /* PRIVATE */
 png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
 {
+#ifdef PNG_WARNINGS_SUPPORTED
    png_const_charp orig_key = key;
+#endif
    png_uint_32 key_len = 0;
    int bad_character = 0;
    int space = 1;
@@ -1678,14 +1745,16 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
       png_byte ch = (png_byte)*key++;
 
       if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
-         *new_key++ = ch, ++key_len, space = 0;
+      {
+         *new_key++ = ch; ++key_len; space = 0;
+      }
 
       else if (space == 0)
       {
          /* A space or an invalid character when one wasn't seen immediately
           * before; output just a space.
           */
-         *new_key++ = 32, ++key_len, space = 1;
+         *new_key++ = 32; ++key_len; space = 1;
 
          /* If the character was not a space then it is invalid. */
          if (ch != 32)
@@ -1698,7 +1767,7 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
 
    if (key_len > 0 && space != 0) /* trailing space */
    {
-      --key_len, --new_key;
+      --key_len; --new_key;
       if (bad_character == 0)
          bad_character = 32;
    }
@@ -1723,7 +1792,9 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
 
       png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
    }
-#endif /* WARNINGS */
+#else /* !WARNINGS */
+   PNG_UNUSED(png_ptr)
+#endif /* !WARNINGS */
 
    return key_len;
 }
index c1f35ed..94a6d04 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngstruct.h - header file for PNG reference library
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -47,7 +47,7 @@
 /* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
  * can handle at once.  This type need be no larger than 16 bits (so maximum of
  * 65535), this define allows us to discover how big it is, but limited by the
- * maximuum for png_size_t.  The value can be overriden in a library build
+ * maximum for size_t.  The value can be overridden in a library build
  * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
  * lower value (e.g. 255 works).  A lower value may help memory usage (slightly)
  * and may even improve performance on some systems (and degrade it on others.)
@@ -214,7 +214,7 @@ struct png_struct_def
    png_uint_32 height;        /* height of image in pixels */
    png_uint_32 num_rows;      /* number of rows in current pass */
    png_uint_32 usr_width;     /* width of row at start of write */
-   png_size_t rowbytes;       /* size of row in bytes */
+   size_t rowbytes;           /* size of row in bytes */
    png_uint_32 iwidth;        /* width of current interlaced row in pixels */
    png_uint_32 row_number;    /* current row in interlace pass */
    png_uint_32 chunk_name;    /* PNG_CHUNK() id of current chunk */
@@ -228,11 +228,15 @@ struct png_struct_def
                                * big_row_buf; while writing it is separately
                                * allocated.
                                */
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   /* Buffer to accelerate palette transformations. */
+   png_bytep riffled_palette;
+#endif
 #ifdef PNG_WRITE_FILTER_SUPPORTED
    png_bytep try_row;    /* buffer to save trial row when filtering */
    png_bytep tst_row;    /* buffer to save best trial row when filtering */
 #endif
-   png_size_t info_rowbytes;  /* Added in 1.5.4: cache of updated row bytes */
+   size_t info_rowbytes;      /* Added in 1.5.4: cache of updated row bytes */
 
    png_uint_32 idat_size;     /* current IDAT size for read */
    png_uint_32 crc;           /* current chunk CRC value */
@@ -249,7 +253,7 @@ struct png_struct_def
    png_byte filter;           /* file filter type (always 0) */
    png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
    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 bit_depth;        /* bit depth of file */
    png_byte usr_bit_depth;    /* bit depth of users row: write only */
@@ -263,7 +267,7 @@ struct png_struct_def
                               /* pixel depth used for the row buffers */
    png_byte transformed_pixel_depth;
                               /* 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 */
 #endif /* Zlib >= 1.2.4 */
 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
@@ -307,7 +311,7 @@ struct png_struct_def
 #endif
 
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
-   png_color_8 shift;         /* shift for significant bit tranformation */
+   png_color_8 shift;         /* shift for significant bit transformation */
 #endif
 
 #if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
@@ -328,10 +332,10 @@ struct png_struct_def
    png_bytep current_buffer;         /* buffer for recently used data */
    png_uint_32 push_length;          /* size of current input chunk */
    png_uint_32 skip_length;          /* bytes to skip in input data */
-   png_size_t save_buffer_size;      /* amount of data now in save_buffer */
-   png_size_t save_buffer_max;       /* total size of save_buffer */
-   png_size_t buffer_size;           /* total amount of available input data */
-   png_size_t current_buffer_size;   /* amount of data now in current_buffer */
+   size_t save_buffer_size;          /* amount of data now in save_buffer */
+   size_t save_buffer_max;           /* total size of save_buffer */
+   size_t buffer_size;               /* total amount of available input data */
+   size_t current_buffer_size;       /* amount of data now in current_buffer */
    int process_mode;                 /* what push library is currently doing */
    int cur_palette;                  /* current push library palette index */
 
@@ -353,7 +357,7 @@ struct png_struct_def
 
 /* Options */
 #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
 
 #if PNG_LIBPNG_VER < 10700
@@ -451,7 +455,7 @@ struct png_struct_def
 #endif
 
 /* New member added in libpng-1.2.26 */
-  png_size_t old_big_row_buf_size;
+   size_t old_big_row_buf_size;
 
 #ifdef PNG_READ_SUPPORTED
 /* New member added in libpng-1.2.30 */
index 57724e0..f27e91e 100644 (file)
--- a/pngtest.c
+++ b/pngtest.c
@@ -1,10 +1,10 @@
 
 /* pngtest.c - a simple test program to test libpng
  *
- * Last changed in libpng 1.5.25 [December 3, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -130,13 +130,13 @@ static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
 static int
 tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t)
 {
-    png_const_charp str = png_convert_to_rfc1123(png_ptr, t);
+   png_const_charp str = png_convert_to_rfc1123(png_ptr, t);
 
-    if (str == NULL)
-        return 0;
+   if (str == NULL)
+       return 0;
 
-    strcpy(ts, str);
-    return 1;
+   strcpy(ts, str);
+   return 1;
 }
 #endif /* older libpng */
 #endif
@@ -144,6 +144,7 @@ tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t)
 static int verbose = 0;
 static int strict = 0;
 static int relaxed = 0;
+static int xfail = 0;
 static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
 static int error_count = 0; /* count calls to png_error */
 static int warning_count = 0; /* count calls to png_warning */
@@ -240,95 +241,95 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
     *  png_byte pixel_depth   bits per pixel (depth*channels)
     */
 
-    /* Counts the number of zero samples (or zero pixels if color_type is 3 */
+   /* Counts the number of zero samples (or zero pixels if color_type is 3 */
 
-    if (row_info->color_type == 0 || row_info->color_type == 3)
-    {
-       int pos = 0;
-       png_uint_32 n, nstop;
+   if (row_info->color_type == 0 || row_info->color_type == 3)
+   {
+      int pos = 0;
+      png_uint_32 n, nstop;
 
-       for (n = 0, nstop=row_info->width; n<nstop; n++)
-       {
-          if (row_info->bit_depth == 1)
-          {
-             if (((*dp << pos++ ) & 0x80) == 0)
-                zero_samples++;
+      for (n = 0, nstop=row_info->width; n<nstop; n++)
+      {
+         if (row_info->bit_depth == 1)
+         {
+            if (((*dp << pos++ ) & 0x80) == 0)
+               zero_samples++;
 
-             if (pos == 8)
-             {
-                pos = 0;
-                dp++;
-             }
-          }
+            if (pos == 8)
+            {
+               pos = 0;
+               dp++;
+            }
+         }
 
-          if (row_info->bit_depth == 2)
-          {
-             if (((*dp << (pos+=2)) & 0xc0) == 0)
-                zero_samples++;
+         if (row_info->bit_depth == 2)
+         {
+            if (((*dp << (pos+=2)) & 0xc0) == 0)
+               zero_samples++;
 
-             if (pos == 8)
-             {
-                pos = 0;
-                dp++;
-             }
-          }
+            if (pos == 8)
+            {
+               pos = 0;
+               dp++;
+            }
+         }
 
-          if (row_info->bit_depth == 4)
-          {
-             if (((*dp << (pos+=4)) & 0xf0) == 0)
-                zero_samples++;
+         if (row_info->bit_depth == 4)
+         {
+            if (((*dp << (pos+=4)) & 0xf0) == 0)
+               zero_samples++;
 
-             if (pos == 8)
-             {
-                pos = 0;
-                dp++;
-             }
-          }
+            if (pos == 8)
+            {
+               pos = 0;
+               dp++;
+            }
+         }
 
-          if (row_info->bit_depth == 8)
-             if (*dp++ == 0)
-                zero_samples++;
+         if (row_info->bit_depth == 8)
+            if (*dp++ == 0)
+               zero_samples++;
 
-          if (row_info->bit_depth == 16)
-          {
-             if ((*dp | *(dp+1)) == 0)
-                zero_samples++;
-             dp+=2;
-          }
-       }
-    }
-    else /* Other color types */
-    {
-       png_uint_32 n, nstop;
-       int channel;
-       int color_channels = row_info->channels;
-       if (row_info->color_type > 3)
-          color_channels--;
-
-       for (n = 0, nstop=row_info->width; n<nstop; n++)
-       {
-          for (channel = 0; channel < color_channels; channel++)
-          {
-             if (row_info->bit_depth == 8)
-                if (*dp++ == 0)
-                   zero_samples++;
+         if (row_info->bit_depth == 16)
+         {
+            if ((*dp | *(dp+1)) == 0)
+               zero_samples++;
+            dp+=2;
+         }
+      }
+   }
+   else /* Other color types */
+   {
+      png_uint_32 n, nstop;
+      int channel;
+      int color_channels = row_info->channels;
+      if (row_info->color_type > 3)
+         color_channels--;
 
-             if (row_info->bit_depth == 16)
-             {
-                if ((*dp | *(dp+1)) == 0)
-                   zero_samples++;
+      for (n = 0, nstop=row_info->width; n<nstop; n++)
+      {
+         for (channel = 0; channel < color_channels; channel++)
+         {
+            if (row_info->bit_depth == 8)
+               if (*dp++ == 0)
+                  zero_samples++;
 
-                dp+=2;
-             }
-          }
-          if (row_info->color_type > 3)
-          {
-             dp++;
-             if (row_info->bit_depth == 16)
-                dp++;
-          }
-       }
-    }
+            if (row_info->bit_depth == 16)
+            {
+               if ((*dp | *(dp+1)) == 0)
+                  zero_samples++;
+
+               dp+=2;
+            }
+         }
+         if (row_info->color_type > 3)
+         {
+            dp++;
+            if (row_info->bit_depth == 16)
+               dp++;
+         }
+      }
+   }
 }
 #endif /* WRITE_USER_TRANSFORM */
 
@@ -344,11 +345,11 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
 
 #ifdef PNG_IO_STATE_SUPPORTED
 void
-pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
-   png_uint_32 io_op);
+pngtest_check_io_state(png_structp png_ptr, size_t data_length,
+    png_uint_32 io_op);
 void
-pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
-   png_uint_32 io_op)
+pngtest_check_io_state(png_structp png_ptr, size_t data_length,
+    png_uint_32 io_op)
 {
    png_uint_32 io_state = png_get_io_state(png_ptr);
    int err = 0;
@@ -385,12 +386,12 @@ pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
 #endif
 
 static void PNGCBAPI
-pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+pngtest_read_data(png_structp png_ptr, png_bytep data, size_t length)
 {
-   png_size_t check = 0;
+   size_t check = 0;
    png_voidp io_ptr;
 
-   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+   /* fread() returns 0 on error, so it is OK to store this in a size_t
     * instead of an int, which is what fread() actually returns.
     */
    io_ptr = png_get_io_ptr(png_ptr);
@@ -424,9 +425,9 @@ pngtest_flush(png_structp png_ptr)
  * than changing the library.
  */
 static void PNGCBAPI
-pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+pngtest_write_data(png_structp png_ptr, png_bytep data, size_t length)
 {
-   png_size_t check;
+   size_t check;
 
    check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr));
 
@@ -448,13 +449,13 @@ pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  */
 typedef struct
 {
-   PNG_CONST char *file_name;
+   const char *file_name;
 }  pngtest_error_parameters;
 
 static void PNGCBAPI
 pngtest_warning(png_structp png_ptr, png_const_charp message)
 {
-   PNG_CONST char *name = "UNKNOWN (ERROR!)";
+   const char *name = "UNKNOWN (ERROR!)";
    pngtest_error_parameters *test =
       (pngtest_error_parameters*)png_get_error_ptr(png_ptr);
 
@@ -463,7 +464,7 @@ pngtest_warning(png_structp png_ptr, png_const_charp message)
    if (test != NULL && test->file_name != NULL)
       name = test->file_name;
 
-   fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
+   fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message);
 }
 
 /* This is the default error handling function.  Note that replacements for
@@ -532,7 +533,7 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
       memory_infop pinfo;
       png_set_mem_fn(png_ptr, NULL, NULL, NULL);
       pinfo = (memory_infop)png_malloc(png_ptr,
-         (sizeof *pinfo));
+          (sizeof *pinfo));
       pinfo->size = size;
       current_allocation += size;
       total_allocation += size;
@@ -562,7 +563,7 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
 
       if (verbose != 0)
          printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
-            pinfo->pointer);
+             pinfo->pointer);
 
       return (png_voidp)(pinfo->pointer);
    }
@@ -704,7 +705,7 @@ read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
     * The unknown chunk structure contains the chunk data:
     * png_byte name[5];
     * png_byte *data;
-    * png_size_t size;
+    * size_t size;
     *
     * Note that libpng has already taken care of the CRC handling.
     */
@@ -769,9 +770,9 @@ write_vpAg_chunk(png_structp write_ptr)
 
    if (verbose != 0)
       fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n",
-        (unsigned long)user_chunk_data.vpAg_width,
-        (unsigned long)user_chunk_data.vpAg_height,
-        user_chunk_data.vpAg_units);
+          (unsigned long)user_chunk_data.vpAg_width,
+          (unsigned long)user_chunk_data.vpAg_height,
+          user_chunk_data.vpAg_units);
 
    png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width);
    png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height);
@@ -812,7 +813,7 @@ write_chunks(png_structp write_ptr, int location)
 #ifdef PNG_TEXT_SUPPORTED
 static void
 pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
-   int num_text)
+    int num_text)
 {
    while (num_text > 0)
    {
@@ -849,7 +850,7 @@ pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
 
 /* Test one file */
 static int
-test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
+test_one_file(const char *inname, const char *outname)
 {
    static png_FILE_p fpin;
    static png_FILE_p fpout;  /* "static" prevents setjmp corruption */
@@ -894,26 +895,26 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    pngtest_debug("Allocating read and write structures");
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
    read_ptr =
-      png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
-      NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+       png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+       NULL, NULL, NULL, png_debug_malloc, png_debug_free);
 #else
    read_ptr =
-      png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 #endif
    png_set_error_fn(read_ptr, &error_parameters, pngtest_error,
-      pngtest_warning);
+       pngtest_warning);
 
 #ifdef PNG_WRITE_SUPPORTED
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
    write_ptr =
-      png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
-      NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+       png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+       NULL, NULL, NULL, png_debug_malloc, png_debug_free);
 #else
    write_ptr =
-      png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 #endif
    png_set_error_fn(write_ptr, &error_parameters, pngtest_error,
-      pngtest_warning);
+       pngtest_warning);
 #endif
    pngtest_debug("Allocating read_info, write_info and end_info structures");
    read_info_ptr = png_create_info_struct(read_ptr);
@@ -926,7 +927,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    init_callback_info(read_info_ptr);
    png_set_read_user_chunk_fn(read_ptr, &user_chunk_data,
-     read_user_chunk_callback);
+       read_user_chunk_callback);
 #endif
 
 #ifdef PNG_SETJMP_SUPPORTED
@@ -936,8 +937,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
       png_free(read_ptr, row_buf);
       row_buf = NULL;
+      if (verbose != 0)
+        fprintf(STDERR, "   destroy read structs\n");
       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
 #ifdef PNG_WRITE_SUPPORTED
+      if (verbose != 0)
+        fprintf(STDERR, "   destroy write structs\n");
       png_destroy_info_struct(write_ptr, &write_end_info_ptr);
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
 #endif
@@ -952,11 +957,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    if (setjmp(png_jmpbuf(write_ptr)))
    {
       fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
+      if (verbose != 0)
+        fprintf(STDERR, "   destroying read structs\n");
       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+      if (verbose != 0)
+        fprintf(STDERR, "   destroying write structs\n");
       png_destroy_info_struct(write_ptr, &write_end_info_ptr);
-#ifdef PNG_WRITE_SUPPORTED
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
-#endif
       FCLOSE(fpin);
       FCLOSE(fpout);
       return (1);
@@ -964,15 +971,16 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #endif
 #endif
 
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    if (strict != 0)
    {
       /* Treat png_benign_error() as errors on read */
       png_set_benign_errors(read_ptr, 0);
 
-#ifdef PNG_WRITE_SUPPORTED
+# ifdef PNG_WRITE_SUPPORTED
       /* Treat them as errors on write */
       png_set_benign_errors(write_ptr, 0);
-#endif
+# endif
 
       /* if strict is not set, then app warnings and errors are treated as
        * warnings in release builds, but not in unstable builds; this can be
@@ -985,10 +993,20 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       /* Allow application (pngtest) errors and warnings to pass */
       png_set_benign_errors(read_ptr, 1);
 
-#ifdef PNG_WRITE_SUPPORTED
-      png_set_benign_errors(write_ptr, 1);
+      /* Turn off CRC checking while reading */
+      png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
+
+#ifdef PNG_IGNORE_ADLER32
+      /* Turn off ADLER32 checking while reading */
+      png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
 #endif
+
+# ifdef PNG_WRITE_SUPPORTED
+      png_set_benign_errors(write_ptr, 1);
+# endif
+
    }
+#endif /* BENIGN_ERRORS */
 
    pngtest_debug("Initializing input and output streams");
 #ifdef PNG_STDIO_SUPPORTED
@@ -1001,9 +1019,9 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #  ifdef PNG_WRITE_SUPPORTED
    png_set_write_fn(write_ptr, (png_voidp)fpout,  pngtest_write_data,
 #    ifdef PNG_WRITE_FLUSH_SUPPORTED
-      pngtest_flush);
+       pngtest_flush);
 #    else
-      NULL);
+       NULL);
 #    endif
 #  endif
 #endif
@@ -1043,11 +1061,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
     */
 #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
    png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
-      NULL, 0);
+       NULL, 0);
 #endif
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
    png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
-      NULL, 0);
+       NULL, 0);
 #endif
 #endif
 
@@ -1071,7 +1089,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
           &color_type, &interlace_type, &compression_type, &filter_type) != 0)
       {
          png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
-            color_type, interlace_type, compression_type, filter_type);
+             color_type, interlace_type, compression_type, filter_type);
          /* num_passes may not be available below if interlace support is not
           * provided by libpng for both read and write.
           */
@@ -1098,13 +1116,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #ifdef PNG_cHRM_SUPPORTED
    {
       png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
-         blue_y;
+          blue_y;
 
       if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
-         &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+          &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       {
          png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
-            red_y, green_x, green_y, blue_x, blue_y);
+             red_y, green_x, green_y, blue_x, blue_y);
       }
    }
 #endif
@@ -1121,13 +1139,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 #ifdef PNG_cHRM_SUPPORTED
    {
       double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
-         blue_y;
+          blue_y;
 
       if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
-         &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+          &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
       {
          png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
-            red_y, green_x, green_y, blue_x, blue_y);
+             red_y, green_x, green_y, blue_x, blue_y);
       }
    }
 #endif
@@ -1149,10 +1167,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       int compression_type;
 
       if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
-                      &profile, &proflen) != 0)
+          &profile, &proflen) != 0)
       {
          png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
-                      profile, proflen);
+             profile, proflen);
       }
    }
 #endif
@@ -1181,6 +1199,22 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       }
    }
 #endif
+#ifdef PNG_READ_eXIf_SUPPORTED
+   {
+      png_bytep exif=NULL;
+      png_uint_32 exif_length;
+
+      if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0)
+      {
+         if (exif_length > 1)
+            fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
+               (unsigned long)exif_length);
+# ifdef PNG_WRITE_eXIf_SUPPORTED
+         png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif);
+# endif
+      }
+   }
+#endif
 #ifdef PNG_hIST_SUPPORTED
    {
       png_uint_16p hist;
@@ -1209,10 +1243,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       int type, nparams;
 
       if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
-         &nparams, &units, &params) != 0)
+          &nparams, &units, &params) != 0)
       {
          png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
-            nparams, units, params);
+             nparams, units, params);
       }
    }
 #endif
@@ -1242,7 +1276,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       double scal_width, scal_height;
 
       if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
-         &scal_height) != 0)
+          &scal_height) != 0)
       {
          png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
       }
@@ -1254,7 +1288,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       png_charp scal_width, scal_height;
 
       if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
-          &scal_height) != 0)
+           &scal_height) != 0)
       {
          png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
              scal_height);
@@ -1291,11 +1325,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          {
             int i;
 
-            printf("\n");
+            fprintf(STDERR,"\n");
             for (i=0; i<num_text; i++)
             {
-               printf("   Text compression[%d]=%d\n",
-                     i, text_ptr[i].compression);
+               fprintf(STDERR,"   Text compression[%d]=%d\n",
+                   i, text_ptr[i].compression);
             }
          }
 
@@ -1332,7 +1366,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       png_color_16p trans_color;
 
       if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
-         &trans_color) != 0)
+          &trans_color) != 0)
       {
          int sample_max = (1 << bit_depth);
          /* libpng doesn't reject a tRNS chunk with out-of-range samples */
@@ -1351,12 +1385,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       png_unknown_chunkp unknowns;
       int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
-         &unknowns);
+          &unknowns);
 
       if (num_unknowns != 0)
       {
          png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
-           num_unknowns);
+             num_unknowns);
 #if PNG_LIBPNG_VER < 10600
          /* Copy the locations from the read_info_ptr.  The automatically
           * generated locations in write_end_info_ptr are wrong prior to 1.6.0
@@ -1366,7 +1400,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
             int i;
             for (i = 0; i < num_unknowns; i++)
               png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
-                unknowns[i].location);
+                  unknowns[i].location);
          }
 #endif
       }
@@ -1386,12 +1420,21 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    png_write_info(write_ptr, write_info_ptr);
 
    write_chunks(write_ptr, before_IDAT); /* after PLTE */
+
+   png_write_info(write_ptr, write_end_info_ptr);
+
+   write_chunks(write_ptr, after_IDAT); /* after IDAT */
+
+#ifdef PNG_COMPRESSION_COMPAT
+   /* Test the 'compatibility' setting here, if it is available. */
+   png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT);
+#endif
 #endif
 
 #ifdef SINGLE_ROWBUF_ALLOC
    pngtest_debug("Allocating row buffer...");
    row_buf = (png_bytep)png_malloc(read_ptr,
-      png_get_rowbytes(read_ptr, read_info_ptr));
+       png_get_rowbytes(read_ptr, read_info_ptr));
 
    pngtest_debug1("\t0x%08lx", (unsigned long)row_buf);
 #endif /* SINGLE_ROWBUF_ALLOC */
@@ -1405,10 +1448,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
     */
    if (png_set_interlace_handling(read_ptr) != num_passes)
       png_error(write_ptr,
-            "png_set_interlace_handling(read): wrong pass count ");
+          "png_set_interlace_handling(read): wrong pass count ");
    if (png_set_interlace_handling(write_ptr) != num_passes)
       png_error(write_ptr,
-            "png_set_interlace_handling(write): wrong pass count ");
+          "png_set_interlace_handling(write): wrong pass count ");
 #else /* png_set_interlace_handling not called on either read or write */
 #  define calc_pass_height
 #endif /* not using libpng interlace handling */
@@ -1445,10 +1488,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
 
          row_buf = (png_bytep)png_malloc(read_ptr,
-            png_get_rowbytes(read_ptr, read_info_ptr));
+             png_get_rowbytes(read_ptr, read_info_ptr));
 
          pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
-            (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
+             (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
 
 #endif /* !SINGLE_ROWBUF_ALLOC */
          png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
@@ -1502,11 +1545,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          {
             int i;
 
-            printf("\n");
+            fprintf(STDERR,"\n");
             for (i=0; i<num_text; i++)
             {
-               printf("   Text compression[%d]=%d\n",
-                     i, text_ptr[i].compression);
+               fprintf(STDERR,"   Text compression[%d]=%d\n",
+                   i, text_ptr[i].compression);
             }
          }
 
@@ -1514,6 +1557,22 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       }
    }
 #endif
+#ifdef PNG_READ_eXIf_SUPPORTED
+   {
+      png_bytep exif=NULL;
+      png_uint_32 exif_length;
+
+      if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0)
+      {
+         if (exif_length > 1)
+            fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
+               (unsigned long)exif_length);
+# ifdef PNG_WRITE_eXIf_SUPPORTED
+         png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif);
+# endif
+      }
+   }
+#endif
 #ifdef PNG_tIME_SUPPORTED
    {
       png_timep mod_time;
@@ -1540,12 +1599,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    {
       png_unknown_chunkp unknowns;
       int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
-         &unknowns);
+          &unknowns);
 
       if (num_unknowns != 0)
       {
          png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
-           num_unknowns);
+             num_unknowns);
 #if PNG_LIBPNG_VER < 10600
          /* Copy the locations from the read_info_ptr.  The automatically
           * generated locations in write_end_info_ptr are wrong prior to 1.6.0
@@ -1555,7 +1614,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
             int i;
             for (i = 0; i < num_unknowns; i++)
               png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
-                unknowns[i].location);
+                  unknowns[i].location);
          }
 #endif
       }
@@ -1589,7 +1648,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       iwidth = png_get_image_width(write_ptr, write_info_ptr);
       iheight = png_get_image_height(write_ptr, write_info_ptr);
       fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
-         (unsigned long)iwidth, (unsigned long)iheight);
+          (unsigned long)iwidth, (unsigned long)iheight);
    }
 #endif
 
@@ -1622,7 +1681,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
        * above, but this is safe.
        */
       fprintf(STDERR, "\n  %s: %d libpng errors found (%d warnings)",
-         inname, error_count, warning_count);
+          inname, error_count, warning_count);
 
       if (strict != 0)
          return (1);
@@ -1633,14 +1692,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       else if (unsupported_chunks > 0)
       {
          fprintf(STDERR, "\n  %s: unsupported chunks (%d)%s",
-            inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
+             inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
       }
 #  endif
 
    else if (warning_count > 0)
    {
       fprintf(STDERR, "\n  %s: %d libpng warnings found",
-         inname, warning_count);
+          inname, warning_count);
 
       if (strict != 0)
          return (1);
@@ -1667,7 +1726,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       for (;;)
       {
          static int wrote_question = 0;
-         png_size_t num_in, num_out;
+         size_t num_in, num_out;
          char inbuf[256], outbuf[256];
 
          num_in = fread(inbuf, 1, sizeof inbuf, fpin);
@@ -1676,18 +1735,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          if (num_in != num_out)
          {
             fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
-                    inname, outname);
+                inname, outname);
 
             if (wrote_question == 0 && unsupported_chunks == 0)
             {
                fprintf(STDERR,
-         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
-                 inname, PNG_ZBUF_SIZE);
+                   "   Was %s written with the same maximum IDAT"
+                   " chunk size (%d bytes),",
+                   inname, PNG_ZBUF_SIZE);
                fprintf(STDERR,
-                 "\n   filtering heuristic (libpng default), compression");
+                   "\n   filtering heuristic (libpng default), compression");
                fprintf(STDERR,
-                 " level (zlib default),\n   and zlib version (%s)?\n\n",
-                 ZLIB_VERSION);
+                   " level (zlib default),\n   and zlib version (%s)?\n\n",
+                   ZLIB_VERSION);
                wrote_question = 1;
             }
 
@@ -1707,17 +1767,18 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          if (memcmp(inbuf, outbuf, num_in))
          {
             fprintf(STDERR, "\nFiles %s and %s are different\n", inname,
-               outname);
+                outname);
 
             if (wrote_question == 0 && unsupported_chunks == 0)
             {
                fprintf(STDERR,
-         "   Was %s written with the same maximum IDAT chunk size (%d bytes),",
+                   "   Was %s written with the same maximum"
+                   " IDAT chunk size (%d bytes),",
                     inname, PNG_ZBUF_SIZE);
                fprintf(STDERR,
-                 "\n   filtering heuristic (libpng default), compression");
+                   "\n   filtering heuristic (libpng default), compression");
                fprintf(STDERR,
-                 " level (zlib default),\n   and zlib version (%s)?\n\n",
+                   " level (zlib default),\n   and zlib version (%s)?\n\n",
                  ZLIB_VERSION);
                wrote_question = 1;
             }
@@ -1748,11 +1809,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 
 /* Input and output filenames */
 #ifdef RISCOS
-static PNG_CONST char *inname = "pngtest/png";
-static PNG_CONST char *outname = "pngout/png";
+static const char *inname = "pngtest/png";
+static const char *outname = "pngout/png";
 #else
-static PNG_CONST char *inname = "pngtest.png";
-static PNG_CONST char *outname = "pngout.png";
+static const char *inname = "pngtest.png";
+static const char *outname = "pngout.png";
 #endif
 
 int
@@ -1768,12 +1829,12 @@ main(int argc, char *argv[])
    fprintf(STDERR, "%s", png_get_copyright(NULL));
    /* Show the version of libpng used in building the library */
    fprintf(STDERR, " library (%lu):%s",
-      (unsigned long)png_access_version_number(),
-      png_get_header_version(NULL));
+       (unsigned long)png_access_version_number(),
+       png_get_header_version(NULL));
 
    /* Show the version of libpng used in building the application */
    fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
-      PNG_HEADER_VERSION_STRING);
+       PNG_HEADER_VERSION_STRING);
 
    /* Do some consistency checking on the memory allocation settings, I'm
     * not sure this matters, but it is nice to know, the first of these
@@ -1791,7 +1852,7 @@ main(int argc, char *argv[])
    if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
    {
       fprintf(STDERR,
-         "Warning: versions are different between png.h and png.c\n");
+          "Warning: versions are different between png.h and png.c\n");
       fprintf(STDERR, "  png.h version: %s\n", PNG_LIBPNG_VER_STRING);
       fprintf(STDERR, "  png.c version: %s\n\n", png_libpng_ver);
       ++ierror;
@@ -1827,6 +1888,7 @@ main(int argc, char *argv[])
          inname = argv[2];
          strict++;
          relaxed = 0;
+         multiple=1;
       }
 
       else if (strcmp(argv[1], "--relaxed") == 0)
@@ -1836,6 +1898,17 @@ main(int argc, char *argv[])
          inname = argv[2];
          strict = 0;
          relaxed++;
+         multiple=1;
+      }
+      else if (strcmp(argv[1], "--xfail") == 0)
+      {
+         status_dots_requested = 0;
+         verbose = 1;
+         inname = argv[2];
+         strict = 0;
+         xfail++;
+         relaxed++;
+         multiple=1;
       }
 
       else
@@ -1846,19 +1919,19 @@ main(int argc, char *argv[])
    }
 
    if (multiple == 0 && argc == 3 + verbose)
-     outname = argv[2 + verbose];
+      outname = argv[2 + verbose];
 
    if ((multiple == 0 && argc > 3 + verbose) ||
        (multiple != 0 && argc < 2))
    {
-     fprintf(STDERR,
-       "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
-        argv[0], argv[0]);
-     fprintf(STDERR,
-       "  reads/writes one PNG file (without -m) or multiple files (-m)\n");
-     fprintf(STDERR,
-       "  with -m %s is used as a temporary file\n", outname);
-     exit(1);
+      fprintf(STDERR,
+          "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+          argv[0], argv[0]);
+      fprintf(STDERR,
+          "  reads/writes one PNG file (without -m) or multiple files (-m)\n");
+      fprintf(STDERR,
+          "  with -m %s is used as a temporary file\n", outname);
+      exit(1);
    }
 
    if (multiple != 0)
@@ -1879,7 +1952,7 @@ main(int argc, char *argv[])
          {
 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
             fprintf(STDERR, "\n PASS (%lu zero samples)\n",
-               (unsigned long)zero_samples);
+                (unsigned long)zero_samples);
 #else
             fprintf(STDERR, " PASS\n");
 #endif
@@ -1893,26 +1966,31 @@ main(int argc, char *argv[])
 
          else
          {
-            fprintf(STDERR, " FAIL\n");
-            ierror += kerror;
+            if (xfail)
+              fprintf(STDERR, " XFAIL\n");
+            else
+            {
+              fprintf(STDERR, " FAIL\n");
+              ierror += kerror;
+            }
          }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
          if (allocation_now != current_allocation)
             fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
-               current_allocation - allocation_now);
+                current_allocation - allocation_now);
 
          if (current_allocation != 0)
          {
             memory_infop pinfo = pinformation;
 
             fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
-               current_allocation);
+                current_allocation);
 
             while (pinfo != NULL)
             {
                fprintf(STDERR, " %lu bytes at %p\n",
-                 (unsigned long)pinfo->size,
-                 pinfo->pointer);
+                   (unsigned long)pinfo->size,
+                   pinfo->pointer);
                pinfo = pinfo->next;
             }
          }
@@ -1920,13 +1998,13 @@ main(int argc, char *argv[])
       }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
          fprintf(STDERR, " Current memory allocation: %10d bytes\n",
-            current_allocation);
+             current_allocation);
          fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
-            maximum_allocation);
+             maximum_allocation);
          fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
-            total_allocation);
+             total_allocation);
          fprintf(STDERR, "     Number of allocations: %10d\n",
-            num_allocations);
+             num_allocations);
 #endif
    }
 
@@ -1961,7 +2039,7 @@ main(int argc, char *argv[])
             {
 #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
                 fprintf(STDERR, "\n PASS (%lu zero samples)\n",
-                   (unsigned long)zero_samples);
+                    (unsigned long)zero_samples);
 #else
                 fprintf(STDERR, " PASS\n");
 #endif
@@ -1982,25 +2060,30 @@ main(int argc, char *argv[])
 #endif
             }
 
-            fprintf(STDERR, " FAIL\n");
-            ierror += kerror;
+            if (xfail)
+              fprintf(STDERR, " XFAIL\n");
+            else
+            {
+              fprintf(STDERR, " FAIL\n");
+              ierror += kerror;
+            }
          }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
          if (allocation_now != current_allocation)
              fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
-               current_allocation - allocation_now);
+                 current_allocation - allocation_now);
 
          if (current_allocation != 0)
          {
              memory_infop pinfo = pinformation;
 
              fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
-                current_allocation);
+                 current_allocation);
 
              while (pinfo != NULL)
              {
                 fprintf(STDERR, " %lu bytes at %p\n",
-                   (unsigned long)pinfo->size, pinfo->pointer);
+                    (unsigned long)pinfo->size, pinfo->pointer);
                 pinfo = pinfo->next;
              }
           }
@@ -2008,13 +2091,13 @@ main(int argc, char *argv[])
        }
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
        fprintf(STDERR, " Current memory allocation: %10d bytes\n",
-          current_allocation);
+           current_allocation);
        fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
-          maximum_allocation);
+           maximum_allocation);
        fprintf(STDERR, " Total   memory allocation: %10d bytes\n",
-          total_allocation);
+           total_allocation);
        fprintf(STDERR, "     Number of allocations: %10d\n",
-            num_allocations);
+           num_allocations);
 #endif
    }
 
@@ -2023,13 +2106,13 @@ main(int argc, char *argv[])
    t_misc += (t_stop - t_start);
    t_start = t_stop;
    fprintf(STDERR, " CPU time used = %.3f seconds",
-      (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
+       (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
    fprintf(STDERR, " (decoding %.3f,\n",
-      t_decode/(float)CLOCKS_PER_SEC);
+       t_decode/(float)CLOCKS_PER_SEC);
    fprintf(STDERR, "        encoding %.3f ,",
-      t_encode/(float)CLOCKS_PER_SEC);
+       t_encode/(float)CLOCKS_PER_SEC);
    fprintf(STDERR, " other %.3f seconds)\n\n",
-      t_misc/(float)CLOCKS_PER_SEC);
+       t_misc/(float)CLOCKS_PER_SEC);
 #endif
 
    if (ierror == 0)
@@ -2041,19 +2124,19 @@ main(int argc, char *argv[])
    dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    fprintf(STDERR, " Default limits:\n");
    fprintf(STDERR, "  width_max  = %lu\n",
-      (unsigned long) png_get_user_width_max(dummy_ptr));
+       (unsigned long) png_get_user_width_max(dummy_ptr));
    fprintf(STDERR, "  height_max = %lu\n",
-      (unsigned long) png_get_user_height_max(dummy_ptr));
+       (unsigned long) png_get_user_height_max(dummy_ptr));
    if (png_get_chunk_cache_max(dummy_ptr) == 0)
       fprintf(STDERR, "  cache_max  = unlimited\n");
    else
       fprintf(STDERR, "  cache_max  = %lu\n",
-         (unsigned long) png_get_chunk_cache_max(dummy_ptr));
+          (unsigned long) png_get_chunk_cache_max(dummy_ptr));
    if (png_get_chunk_malloc_max(dummy_ptr) == 0)
       fprintf(STDERR, "  malloc_max = unlimited\n");
    else
       fprintf(STDERR, "  malloc_max = %lu\n",
-         (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
+          (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
    png_destroy_read_struct(&dummy_ptr, NULL, NULL);
 
    return (int)(ierror != 0);
@@ -2063,11 +2146,11 @@ int
 main(void)
 {
    fprintf(STDERR,
-      " test ignored because libpng was not built with read support\n");
+       " test ignored because libpng was not built with read support\n");
    /* And skip this test */
    return PNG_LIBPNG_VER < 10600 ? 0 : 77;
 }
 #endif
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_21 Your_png_h_is_not_version_1_6_21;
+typedef png_libpng_version_1_6_36 Your_png_h_is_not_version_1_6_36;
index cb3fef4..66df0c4 100644 (file)
Binary files a/pngtest.png and b/pngtest.png differ
index 7f8cc45..1100f46 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -172,13 +172,14 @@ png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
                    * size!
                    */
                   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;
                }
 
             default:
                png_app_error(png_ptr,
-                  "png_set_filler: inappropriate color type");
+                   "png_set_filler: inappropriate color type");
                return;
          }
 #     else
@@ -268,8 +269,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
    if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
    {
       png_bytep rp = row;
-      png_size_t i;
-      png_size_t istop = row_info->rowbytes;
+      size_t i;
+      size_t istop = row_info->rowbytes;
 
       for (i = 0; i < istop; i++)
       {
@@ -282,8 +283,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
       row_info->bit_depth == 8)
    {
       png_bytep rp = row;
-      png_size_t i;
-      png_size_t istop = row_info->rowbytes;
+      size_t i;
+      size_t istop = row_info->rowbytes;
 
       for (i = 0; i < istop; i += 2)
       {
@@ -297,8 +298,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
       row_info->bit_depth == 16)
    {
       png_bytep rp = row;
-      png_size_t i;
-      png_size_t istop = row_info->rowbytes;
+      size_t i;
+      size_t istop = row_info->rowbytes;
 
       for (i = 0; i < istop; i += 4)
       {
@@ -344,7 +345,7 @@ png_do_swap(png_row_infop row_info, png_bytep row)
 #endif
 
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-static PNG_CONST png_byte onebppswaptable[256] = {
+static const png_byte onebppswaptable[256] = {
    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
@@ -379,7 +380,7 @@ static PNG_CONST png_byte onebppswaptable[256] = {
    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
 };
 
-static PNG_CONST png_byte twobppswaptable[256] = {
+static const png_byte twobppswaptable[256] = {
    0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
    0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
    0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
@@ -414,7 +415,7 @@ static PNG_CONST png_byte twobppswaptable[256] = {
    0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
 };
 
-static PNG_CONST png_byte fourbppswaptable[256] = {
+static const png_byte fourbppswaptable[256] = {
    0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
    0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
    0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
@@ -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 */
             ++sp;
          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 */
          while (sp < ep)
-            *dp++ = *sp, sp += 2;
+         {
+            *dp++ = *sp; sp += 2;
+         }
 
          row_info->pixel_depth = 8;
       }
@@ -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 */
             sp += 2;
          else          /* Skip initial channel and, for sp, the filler */
-            sp += 4, dp += 2;
+         {
+            sp += 4; dp += 2;
+         }
 
          while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+         {
+            *dp++ = *sp++; *dp++ = *sp; sp += 3;
+         }
 
          row_info->pixel_depth = 16;
       }
@@ -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 */
             ++sp;
          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. */
          while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
+         {
+            *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
+         }
 
          row_info->pixel_depth = 24;
       }
@@ -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 */
             sp += 2;
          else          /* Skip initial channels and, for sp, the filler */
-            sp += 8, dp += 6;
+         {
+            sp += 8; dp += 6;
+         }
 
          while (sp < ep)
          {
             /* Copy 6 bytes, skip 2 */
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+            *dp++ = *sp++; *dp++ = *sp++;
+            *dp++ = *sp++; *dp++ = *sp++;
+            *dp++ = *sp++; *dp++ = *sp; sp += 3;
          }
 
          row_info->pixel_depth = 48;
@@ -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 */
 
    /* Fix the rowbytes value. */
-   row_info->rowbytes = dp-row;
+   row_info->rowbytes = (size_t)(dp-row);
 }
 #endif
 
@@ -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
        * forms produced on either GCC or MSVC.
        */
-      int padding = (-row_info->pixel_depth * row_info->width) & 7;
-      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
+      int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
+      png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
 
       switch (row_info->bit_depth)
       {
@@ -797,7 +812,7 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp
       (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
    {
       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;
    }
 #endif
index 586c03b..10e919d 100644 (file)
--- a/pngwio.c
+++ b/pngwio.c
@@ -1,10 +1,10 @@
 
 /* pngwio.c - functions for data output
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  */
 
 void /* PRIVATE */
-png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
+png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length)
 {
    /* NOTE: write_data_fn must not change the buffer! */
    if (png_ptr->write_data_fn != NULL )
       (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
-         length);
+          length);
 
    else
       png_error(png_ptr, "Call to NULL write function");
@@ -48,9 +48,9 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
  * than changing the library.
  */
 void PNGCBAPI
-png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+png_default_write_data(png_structp png_ptr, png_bytep data, size_t length)
 {
-   png_size_t check;
+   size_t check;
 
    if (png_ptr == NULL)
       return;
index f843796..160c877 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * Last changed in libpng 1.6.19 [November 12, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -12,9 +12,9 @@
  */
 
 #include "pngpriv.h"
-#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
 #  include <errno.h>
-#endif
+#endif /* SIMPLIFIED_WRITE_STDIO */
 
 #ifdef PNG_WRITE_SUPPORTED
 
@@ -22,7 +22,7 @@
 /* Write out all the unknown chunks for the current given location */
 static void
 write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
-   unsigned int where)
+    unsigned int where)
 {
    if (info_ptr->unknown_chunks_num != 0)
    {
@@ -148,11 +148,11 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
 #    ifdef PNG_WRITE_sRGB_SUPPORTED
                if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
                   png_app_warning(png_ptr,
-                     "profile matches sRGB but writing iCCP instead");
+                      "profile matches sRGB but writing iCCP instead");
 #     endif
 
             png_write_iCCP(png_ptr, info_ptr->iccp_name,
-               info_ptr->iccp_profile);
+                info_ptr->iccp_profile);
          }
 #     ifdef PNG_WRITE_sRGB_SUPPORTED
          else
@@ -237,6 +237,11 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
       png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
 #endif
 
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
+      png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
+#endif
+
 #ifdef PNG_WRITE_hIST_SUPPORTED
    if ((info_ptr->valid & PNG_INFO_hIST) != 0)
       png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
@@ -383,7 +388,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
       for (i = 0; i < info_ptr->num_text; i++)
       {
          png_debug2(2, "Writing trailer text chunk %d, type %d", i,
-            info_ptr->text[i].compression);
+             info_ptr->text[i].compression);
          /* An internationalized chunk? */
          if (info_ptr->text[i].compression > 0)
          {
@@ -432,6 +437,12 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
          }
       }
 #endif
+
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+   if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
+      png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
+#endif
+
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
       write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
 #endif
@@ -458,7 +469,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
 
 #ifdef PNG_CONVERT_tIME_SUPPORTED
 void PNGAPI
-png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
+png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime)
 {
    png_debug(1, "in png_convert_from_struct_tm");
 
@@ -666,9 +677,9 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
 
          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
          {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 s0   = (png_uint_32)(*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
             png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
             png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
             *(rp    ) = (png_byte)(red >> 8);
@@ -693,7 +704,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
       return;
 
    png_debug2(1, "in png_write_row (row %u, pass %d)",
-      png_ptr->row_number, png_ptr->pass);
+       png_ptr->row_number, png_ptr->pass);
 
    /* Initialize transformations and other stuff if first time */
    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
@@ -901,7 +912,7 @@ png_set_flush(png_structrp png_ptr, int nrows)
    if (png_ptr == NULL)
       return;
 
-   png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+   png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows);
 }
 
 /* Flush the current output buffers now */
@@ -937,6 +948,10 @@ png_write_destroy(png_structrp png_ptr)
    png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
    png_free(png_ptr, png_ptr->row_buf);
    png_ptr->row_buf = NULL;
+#ifdef PNG_READ_EXPANDED_SUPPORTED
+   png_free(png_ptr, png_ptr->riffled_palette);
+   png_ptr->riffled_palette = NULL;
+#endif
 #ifdef PNG_WRITE_FILTER_SUPPORTED
    png_free(png_ptr, png_ptr->prev_row);
    png_free(png_ptr, png_ptr->try_row);
@@ -1007,8 +1022,8 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
          case 5:
          case 6:
          case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
-            /* FALL THROUGH */
 #endif /* WRITE_FILTER */
+            /* FALLTHROUGH */
          case PNG_FILTER_VALUE_NONE:
             png_ptr->do_filter = PNG_FILTER_NONE; break;
 
@@ -1069,7 +1084,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
              * is not available so the filter can't be used.  Just warn here.
              */
             png_app_warning(png_ptr,
-               "png_set_filter: UP/AVG/PAETH cannot be added after start");
+                "png_set_filter: UP/AVG/PAETH cannot be added after start");
             filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
          }
 
@@ -1095,13 +1110,13 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
 
          if (png_ptr->try_row == NULL)
             png_ptr->try_row = png_voidcast(png_bytep,
-               png_malloc(png_ptr, buf_size));
+                png_malloc(png_ptr, buf_size));
 
          if (num_filters > 1)
          {
             if (png_ptr->tst_row == NULL)
                png_ptr->tst_row = png_voidcast(png_bytep,
-                  png_malloc(png_ptr, buf_size));
+                   png_malloc(png_ptr, buf_size));
          }
       }
       png_ptr->do_filter = (png_byte)filters;
@@ -1452,7 +1467,6 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
 
 
 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
-# ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
 /* Initialize the write structure - general purpose utility. */
 static int
 png_image_write_init(png_imagep image)
@@ -1504,6 +1518,10 @@ typedef struct
    png_const_voidp first_row;
    ptrdiff_t       row_bytes;
    png_voidp       local_row;
+   /* Byte count for memory writing */
+   png_bytep        memory;
+   png_alloc_size_t memory_bytes; /* not used for STDIO */
+   png_alloc_size_t output_bytes; /* running total */
 } png_image_write_control;
 
 /* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
@@ -1522,7 +1540,8 @@ png_write_image_16bit(png_voidp argument)
        display->first_row);
    png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
    png_uint_16p row_end;
-   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+   unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
+       3 : 1;
    int aindex = 0;
    png_uint_32 y = image->height;
 
@@ -1536,9 +1555,9 @@ png_write_image_16bit(png_voidp argument)
          ++output_row;
       }
          else
-            aindex = channels;
+            aindex = (int)channels;
 #     else
-         aindex = channels;
+         aindex = (int)channels;
 #     endif
    }
 
@@ -1551,14 +1570,14 @@ png_write_image_16bit(png_voidp argument)
     */
    row_end = output_row + image->width * (channels+1);
 
-   while (y-- > 0)
+   for (; y > 0; --y)
    {
       png_const_uint_16p in_ptr = input_row;
       png_uint_16p out_ptr = output_row;
 
       while (out_ptr < row_end)
       {
-         const png_uint_16 alpha = in_ptr[aindex];
+         png_uint_16 alpha = in_ptr[aindex];
          png_uint_32 reciprocal = 0;
          int c;
 
@@ -1572,7 +1591,7 @@ png_write_image_16bit(png_voidp argument)
          if (alpha > 0 && alpha < 65535)
             reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
 
-         c = channels;
+         c = (int)channels;
          do /* always at least one channel */
          {
             png_uint_16 component = *in_ptr++;
@@ -1607,7 +1626,7 @@ png_write_image_16bit(png_voidp argument)
       }
 
       png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
-      input_row += display->row_bytes/(sizeof (png_uint_16));
+      input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
    }
 
    return 1;
@@ -1621,11 +1640,11 @@ png_write_image_16bit(png_voidp argument)
  * calculation can be done to 15 bits of accuracy; however, the output needs to
  * be scaled in the range 0..255*65535, so include that scaling here.
  */
-#   define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
+#   define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+((alpha)>>1))/(alpha))
 
 static png_byte
 png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
-   png_uint_32 reciprocal/*from the above macro*/)
+    png_uint_32 reciprocal/*from the above macro*/)
 {
    /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
     * is represented as some other value there is more likely to be a
@@ -1680,7 +1699,8 @@ png_write_image_8bit(png_voidp argument)
        display->first_row);
    png_bytep output_row = png_voidcast(png_bytep, display->local_row);
    png_uint_32 y = image->height;
-   const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+   unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
+       3 : 1;
 
    if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
    {
@@ -1697,12 +1717,12 @@ png_write_image_8bit(png_voidp argument)
 
       else
 #   endif
-      aindex = channels;
+      aindex = (int)channels;
 
       /* Use row_end in place of a loop counter: */
       row_end = output_row + image->width * (channels+1);
 
-      while (y-- > 0)
+      for (; y > 0; --y)
       {
          png_const_uint_16p in_ptr = input_row;
          png_bytep out_ptr = output_row;
@@ -1720,7 +1740,7 @@ png_write_image_8bit(png_voidp argument)
             if (alphabyte > 0 && alphabyte < 255)
                reciprocal = UNP_RECIPROCAL(alpha);
 
-            c = channels;
+            c = (int)channels;
             do /* always at least one channel */
                *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
             while (--c > 0);
@@ -1732,7 +1752,7 @@ png_write_image_8bit(png_voidp argument)
 
          png_write_row(png_ptr, png_voidcast(png_const_bytep,
              display->local_row));
-         input_row += display->row_bytes/(sizeof (png_uint_16));
+         input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
       } /* while y */
    }
 
@@ -1743,7 +1763,7 @@ png_write_image_8bit(png_voidp argument)
        */
       png_bytep row_end = output_row + image->width * channels;
 
-      while (y-- > 0)
+      for (; y > 0; --y)
       {
          png_const_uint_16p in_ptr = input_row;
          png_bytep out_ptr = output_row;
@@ -1757,7 +1777,7 @@ png_write_image_8bit(png_voidp argument)
          }
 
          png_write_row(png_ptr, output_row);
-         input_row += display->row_bytes/(sizeof (png_uint_16));
+         input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
       }
    }
 
@@ -1767,25 +1787,25 @@ png_write_image_8bit(png_voidp argument)
 static void
 png_image_set_PLTE(png_image_write_control *display)
 {
-   const png_imagep image = display->image;
+   png_imagep image = display->image;
    const void *cmap = display->colormap;
-   const int entries = image->colormap_entries > 256 ? 256 :
+   int entries = image->colormap_entries > 256 ? 256 :
        (int)image->colormap_entries;
 
    /* NOTE: the caller must check for cmap != NULL and entries != 0 */
-   const png_uint_32 format = image->format;
-   const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
+   png_uint_32 format = image->format;
+   unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
 
 #   if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
       defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
-      const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+      int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
           (format & PNG_FORMAT_FLAG_ALPHA) != 0;
 #   else
 #     define afirst 0
 #   endif
 
 #   ifdef PNG_FORMAT_BGR_SUPPORTED
-      const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+      int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
 #   else
 #     define bgr 0
 #   endif
@@ -1806,7 +1826,7 @@ png_image_set_PLTE(png_image_write_control *display)
       {
          png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
 
-         entry += i * channels;
+         entry += (unsigned int)i * channels;
 
          if ((channels & 1) != 0) /* no alpha */
          {
@@ -1845,16 +1865,16 @@ png_image_set_PLTE(png_image_write_control *display)
             if (channels >= 3) /* RGB */
             {
                palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
-                  alpha, reciprocal);
+                   alpha, reciprocal);
                palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
-                  reciprocal);
+                   reciprocal);
                palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
-                  reciprocal);
+                   reciprocal);
             }
 
             else /* gray */
                palette[i].blue = palette[i].red = palette[i].green =
-                  png_unpremultiply(entry[afirst], alpha, reciprocal);
+                   png_unpremultiply(entry[afirst], alpha, reciprocal);
          }
       }
 
@@ -1862,7 +1882,7 @@ png_image_set_PLTE(png_image_write_control *display)
       {
          png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
 
-         entry += i * channels;
+         entry += (unsigned int)i * channels;
 
          switch (channels)
          {
@@ -1870,7 +1890,7 @@ png_image_set_PLTE(png_image_write_control *display)
                tRNS[i] = entry[afirst ? 0 : 3];
                if (tRNS[i] < 255)
                   num_trans = i+1;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
             case 3:
                palette[i].blue = entry[afirst + (2 ^ bgr)];
                palette[i].green = entry[afirst + 1];
@@ -1881,7 +1901,7 @@ png_image_set_PLTE(png_image_write_control *display)
                tRNS[i] = entry[1 ^ afirst];
                if (tRNS[i] < 255)
                   num_trans = i+1;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
             case 1:
                palette[i].blue = palette[i].red = palette[i].green =
                   entry[afirst];
@@ -1901,20 +1921,20 @@ png_image_set_PLTE(png_image_write_control *display)
 #   endif
 
    png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
-      entries);
+       entries);
 
    if (num_trans > 0)
       png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
-         num_trans, NULL);
+          num_trans, NULL);
 
-   image->colormap_entries = entries;
+   image->colormap_entries = (png_uint_32)entries;
 }
 
 static int
 png_image_write_main(png_voidp argument)
 {
    png_image_write_control *display = png_voidcast(png_image_write_control*,
-      argument);
+       argument);
    png_imagep image = display->image;
    png_structrp png_ptr = image->opaque->png_ptr;
    png_inforp info_ptr = image->opaque->info_ptr;
@@ -1924,16 +1944,50 @@ png_image_write_main(png_voidp argument)
    int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
    int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
    int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
-   int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
+   int write_16bit = linear && (display->convert_to_8bit == 0);
 
 #   ifdef PNG_BENIGN_ERRORS_SUPPORTED
       /* Make sure we error out on any bad situation */
       png_set_benign_errors(png_ptr, 0/*error*/);
 #   endif
 
-   /* Default the 'row_stride' parameter if required. */
-   if (display->row_stride == 0)
-      display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+   /* Default the 'row_stride' parameter if required, also check the row stride
+    * and total image size to ensure that they are within the system limits.
+    */
+   {
+      unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
+
+      if (image->width <= 0x7fffffffU/channels) /* no overflow */
+      {
+         png_uint_32 check;
+         png_uint_32 png_row_stride = image->width * channels;
+
+         if (display->row_stride == 0)
+            display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
+
+         if (display->row_stride < 0)
+            check = (png_uint_32)(-display->row_stride);
+
+         else
+            check = (png_uint_32)display->row_stride;
+
+         if (check >= png_row_stride)
+         {
+            /* Now check for overflow of the image buffer calculation; this
+             * limits the whole image size to 32 bits for API compatibility with
+             * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+             */
+            if (image->height > 0xffffffffU/png_row_stride)
+               png_error(image->opaque->png_ptr, "memory image too large");
+         }
+
+         else
+            png_error(image->opaque->png_ptr, "supplied row stride too small");
+      }
+
+      else
+         png_error(image->opaque->png_ptr, "image row stride too large");
+   }
 
    /* Set the required transforms then write the rows in the correct order. */
    if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
@@ -1943,24 +1997,24 @@ png_image_write_main(png_voidp argument)
          png_uint_32 entries = image->colormap_entries;
 
          png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
-            entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
-            PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
-            PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+             entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
+             PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
          png_image_set_PLTE(display);
       }
 
       else
          png_error(image->opaque->png_ptr,
-            "no color-map for color-mapped image");
+             "no color-map for color-mapped image");
    }
 
    else
       png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
-         write_16bit ? 16 : 8,
-         ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
-         ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
-         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+          write_16bit ? 16 : 8,
+          ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
+          ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
+          PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
    /* Counter-intuitively the data transformations must be called *after*
     * png_write_info, not before as in the read code, but the 'set' functions
@@ -1975,11 +2029,11 @@ png_image_write_main(png_voidp argument)
 
       if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
          png_set_cHRM_fixed(png_ptr, info_ptr,
-            /* color      x       y */
-            /* white */ 31270, 32900,
-            /* red   */ 64000, 33000,
-            /* green */ 30000, 60000,
-            /* blue  */ 15000,  6000
+             /* color      x       y */
+             /* white */ 31270, 32900,
+             /* red   */ 64000, 33000,
+             /* green */ 30000, 60000,
+             /* blue  */ 15000,  6000
          );
    }
 
@@ -2002,7 +2056,7 @@ png_image_write_main(png_voidp argument)
     */
    if (write_16bit != 0)
    {
-      PNG_CONST png_uint_16 le = 0x0001;
+      png_uint_16 le = 0x0001;
 
       if ((*(png_const_bytep) & le) != 0)
          png_set_swap(png_ptr);
@@ -2073,7 +2127,7 @@ png_image_write_main(png_voidp argument)
        (colormap == 0 && display->convert_to_8bit != 0))
    {
       png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
-         png_get_rowbytes(png_ptr, info_ptr)));
+          png_get_rowbytes(png_ptr, info_ptr)));
       int result;
 
       display->local_row = row;
@@ -2099,7 +2153,7 @@ png_image_write_main(png_voidp argument)
       ptrdiff_t row_bytes = display->row_bytes;
       png_uint_32 y = image->height;
 
-      while (y-- > 0)
+      for (; y > 0; --y)
       {
          png_write_row(png_ptr, row);
          row += row_bytes;
@@ -2110,14 +2164,129 @@ png_image_write_main(png_voidp argument)
    return 1;
 }
 
+
+static void (PNGCBAPI
+image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size)
+{
+   png_image_write_control *display = png_voidcast(png_image_write_control*,
+       png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
+   png_alloc_size_t ob = display->output_bytes;
+
+   /* Check for overflow; this should never happen: */
+   if (size <= ((png_alloc_size_t)-1) - ob)
+   {
+      /* I don't think libpng ever does this, but just in case: */
+      if (size > 0)
+      {
+         if (display->memory_bytes >= ob+size) /* writing */
+            memcpy(display->memory+ob, data, size);
+
+         /* Always update the size: */
+         display->output_bytes = ob+size;
+      }
+   }
+
+   else
+      png_error(png_ptr, "png_image_write_to_memory: PNG too big");
+}
+
+static void (PNGCBAPI
+image_memory_flush)(png_structp png_ptr)
+{
+   PNG_UNUSED(png_ptr)
+}
+
+static int
+png_image_write_memory(png_voidp argument)
+{
+   png_image_write_control *display = png_voidcast(png_image_write_control*,
+       argument);
+
+   /* The rest of the memory-specific init and write_main in an error protected
+    * environment.  This case needs to use callbacks for the write operations
+    * since libpng has no built in support for writing to memory.
+    */
+   png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
+       image_memory_write, image_memory_flush);
+
+   return png_image_write_main(display);
+}
+
+int PNGAPI
+png_image_write_to_memory(png_imagep image, void *memory,
+    png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
+    const void *buffer, png_int_32 row_stride, const void *colormap)
+{
+   /* Write the image to the given buffer, or count the bytes if it is NULL */
+   if (image != NULL && image->version == PNG_IMAGE_VERSION)
+   {
+      if (memory_bytes != NULL && buffer != NULL)
+      {
+         /* This is to give the caller an easier error detection in the NULL
+          * case and guard against uninitialized variable problems:
+          */
+         if (memory == NULL)
+            *memory_bytes = 0;
+
+         if (png_image_write_init(image) != 0)
+         {
+            png_image_write_control display;
+            int result;
+
+            memset(&display, 0, (sizeof display));
+            display.image = image;
+            display.buffer = buffer;
+            display.row_stride = row_stride;
+            display.colormap = colormap;
+            display.convert_to_8bit = convert_to_8bit;
+            display.memory = png_voidcast(png_bytep, memory);
+            display.memory_bytes = *memory_bytes;
+            display.output_bytes = 0;
+
+            result = png_safe_execute(image, png_image_write_memory, &display);
+            png_image_free(image);
+
+            /* write_memory returns true even if we ran out of buffer. */
+            if (result)
+            {
+               /* On out-of-buffer this function returns '0' but still updates
+                * memory_bytes:
+                */
+               if (memory != NULL && display.output_bytes > *memory_bytes)
+                  result = 0;
+
+               *memory_bytes = display.output_bytes;
+            }
+
+            return result;
+         }
+
+         else
+            return 0;
+      }
+
+      else
+         return png_image_error(image,
+             "png_image_write_to_memory: invalid argument");
+   }
+
+   else if (image != NULL)
+      return png_image_error(image,
+          "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
+
+   else
+      return 0;
+}
+
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
 int PNGAPI
 png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
-   const void *buffer, png_int_32 row_stride, const void *colormap)
+    const void *buffer, png_int_32 row_stride, const void *colormap)
 {
    /* Write the image to the given (FILE*). */
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
-      if (file != NULL)
+      if (file != NULL && buffer != NULL)
       {
          if (png_image_write_init(image) != 0)
          {
@@ -2148,12 +2317,12 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
 
       else
          return png_image_error(image,
-            "png_image_write_to_stdio: invalid argument");
+             "png_image_write_to_stdio: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
+          "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
 
    else
       return 0;
@@ -2161,20 +2330,20 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
 
 int PNGAPI
 png_image_write_to_file(png_imagep image, const char *file_name,
-   int convert_to_8bit, const void *buffer, png_int_32 row_stride,
-   const void *colormap)
+    int convert_to_8bit, const void *buffer, png_int_32 row_stride,
+    const void *colormap)
 {
    /* Write the image to the named file. */
    if (image != NULL && image->version == PNG_IMAGE_VERSION)
    {
-      if (file_name != NULL)
+      if (file_name != NULL && buffer != NULL)
       {
          FILE *fp = fopen(file_name, "wb");
 
          if (fp != NULL)
          {
             if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
-               row_stride, colormap) != 0)
+                row_stride, colormap) != 0)
             {
                int error; /* from fflush/fclose */
 
@@ -2215,16 +2384,16 @@ png_image_write_to_file(png_imagep image, const char *file_name,
 
       else
          return png_image_error(image,
-            "png_image_write_to_file: invalid argument");
+             "png_image_write_to_file: invalid argument");
    }
 
    else if (image != NULL)
       return png_image_error(image,
-         "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
+          "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
 
    else
       return 0;
 }
-# endif /* STDIO */
+#endif /* SIMPLIFIED_WRITE_STDIO */
 #endif /* SIMPLIFIED_WRITE */
 #endif /* WRITE */
index 038a2ef..49a13c1 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * Last changed in libpng 1.6.18 [July 23, 2015]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -177,7 +177,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
    if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
    {
       int shift_start[4], shift_dec[4];
-      int channels = 0;
+      unsigned int channels = 0;
 
       if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
       {
@@ -212,9 +212,9 @@ png_do_shift(png_row_infop row_info, png_bytep row,
       if (row_info->bit_depth < 8)
       {
          png_bytep bp = row;
-         png_size_t i;
+         size_t i;
          unsigned int mask;
-         png_size_t row_bytes = row_info->rowbytes;
+         size_t row_bytes = row_info->rowbytes;
 
          if (bit_depth->gray == 1 && row_info->bit_depth == 2)
             mask = 0x55;
@@ -254,8 +254,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
 
          for (i = 0; i < istop; i++, bp++)
          {
-
-            const unsigned int c = i%channels;
+            unsigned int c = i%channels;
             int j;
             unsigned int v, out;
 
@@ -283,7 +282,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
 
          for (bp = row, i = 0; i < istop; i++)
          {
-            const unsigned int c = i%channels;
+            unsigned int c = i%channels;
             int j;
             unsigned int value, v;
 
@@ -514,7 +513,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
              (png_ptr,  /* png_ptr */
              row_info,  /* row_info: */
                 /*  png_uint_32 width;       width of row */
-                /*  png_size_t rowbytes;     number of bytes in row */
+                /*  size_t rowbytes;         number of bytes in row */
                 /*  png_byte color_type;     color type of pixels */
                 /*  png_byte bit_depth;      bit depth of samples */
                 /*  png_byte channels;       number of channels (1-4) */
@@ -525,7 +524,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
 #ifdef PNG_WRITE_FILLER_SUPPORTED
    if ((png_ptr->transformations & PNG_FILLER) != 0)
       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
 
 #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
@@ -549,7 +548,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
 #ifdef PNG_WRITE_SHIFT_SUPPORTED
    if ((png_ptr->transformations & PNG_SHIFT) != 0)
       png_do_shift(row_info, png_ptr->row_buf + 1,
-          &(png_ptr->shift));
+           &(png_ptr->shift));
 #endif
 
 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
index 8cf4c2b..16345e4 100644 (file)
@@ -1,10 +1,10 @@
 
 /* pngwutil.c - utilities to write a PNG file
  *
- * Last changed in libpng 1.6.21 [January 15, 2016]
- * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
- * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
- * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
+ * Copyright (c) 1996-1997 Andreas Dilger
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
 void PNGAPI
 png_save_uint_32(png_bytep buf, png_uint_32 i)
 {
-   buf[0] = (png_byte)(i >> 24);
-   buf[1] = (png_byte)(i >> 16);
-   buf[2] = (png_byte)(i >> 8);
-   buf[3] = (png_byte)(i     );
+   buf[0] = (png_byte)((i >> 24) & 0xffU);
+   buf[1] = (png_byte)((i >> 16) & 0xffU);
+   buf[2] = (png_byte)((i >>  8) & 0xffU);
+   buf[3] = (png_byte)( i        & 0xffU);
 }
 
 /* Place a 16-bit number into a buffer in PNG byte order.
@@ -36,8 +36,8 @@ png_save_uint_32(png_bytep buf, png_uint_32 i)
 void PNGAPI
 png_save_uint_16(png_bytep buf, unsigned int i)
 {
-   buf[0] = (png_byte)(i >> 8);
-   buf[1] = (png_byte)(i     );
+   buf[0] = (png_byte)((i >> 8) & 0xffU);
+   buf[1] = (png_byte)( i       & 0xffU);
 }
 #endif
 
@@ -59,7 +59,7 @@ png_write_sig(png_structrp png_ptr)
 
    /* Write the rest of the 8 byte signature */
    png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
-      (png_size_t)(8 - png_ptr->sig_bytes));
+       (size_t)(8 - png_ptr->sig_bytes));
 
    if (png_ptr->sig_bytes < 3)
       png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
@@ -124,8 +124,7 @@ png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
  * given to png_write_chunk_header().
  */
 void PNGAPI
-png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
-    png_size_t length)
+png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length)
 {
    /* Write the data, and run the CRC over it */
    if (png_ptr == NULL)
@@ -160,7 +159,7 @@ png_write_chunk_end(png_structrp png_ptr)
    /* Write the crc in a single operation */
    png_save_uint_32(buf, png_ptr->crc);
 
-   png_write_data(png_ptr, buf, (png_size_t)4);
+   png_write_data(png_ptr, buf, 4);
 }
 
 /* Write a PNG chunk all at once.  The type is an array of ASCII characters
@@ -174,7 +173,7 @@ png_write_chunk_end(png_structrp png_ptr)
  */
 static void
 png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
-   png_const_bytep data, png_size_t length)
+    png_const_bytep data, size_t length)
 {
    if (png_ptr == NULL)
       return;
@@ -191,10 +190,10 @@ png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
 /* This is the API that calls the internal function above. */
 void PNGAPI
 png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
-   png_const_bytep data, png_size_t length)
+    png_const_bytep data, size_t length)
 {
    png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
-      length);
+       length);
 }
 
 /* This is used below to find the size of an image to pass to png_deflate_claim,
@@ -291,7 +290,7 @@ optimize_cmf(png_bytep data, png_alloc_size_t data_size)
 /* Initialize the compressor for the appropriate type of compression. */
 static int
 png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
-   png_alloc_size_t data_size)
+    png_alloc_size_t data_size)
 {
    if (png_ptr->zowner != 0)
    {
@@ -408,7 +407,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
       png_ptr->zstream.avail_out = 0;
 
       /* Now initialize if required, setting the new parameters, otherwise just
-       * to a simple reset to the previous parameters.
+       * do a simple reset to the previous parameters.
        */
       if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
          ret = deflateReset(&png_ptr->zstream);
@@ -416,7 +415,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
       else
       {
          ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
-            memLevel, strategy);
+             memLevel, strategy);
 
          if (ret == Z_OK)
             png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
@@ -477,7 +476,7 @@ typedef struct
 
 static void
 png_text_compress_init(compression_state *comp, png_const_bytep input,
-   png_alloc_size_t input_len)
+    png_alloc_size_t input_len)
 {
    comp->input = input;
    comp->input_len = input_len;
@@ -487,7 +486,7 @@ png_text_compress_init(compression_state *comp, png_const_bytep input,
 /* Compress the data in the compression state input */
 static int
 png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
-   compression_state *comp, png_uint_32 prefix_len)
+    compression_state *comp, png_uint_32 prefix_len)
 {
    int ret;
 
@@ -579,7 +578,7 @@ png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
 
          /* Compress the data */
          ret = deflate(&png_ptr->zstream,
-            input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
+             input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
 
          /* Claw back input data that was not consumed (because avail_in is
           * reset above every time round the loop).
@@ -675,6 +674,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
     int interlace_type)
 {
    png_byte buf[13]; /* Buffer to store the IHDR info */
+   int is_invalid_depth;
 
    png_debug(1, "in png_write_IHDR");
 
@@ -700,11 +700,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
          break;
 
       case PNG_COLOR_TYPE_RGB:
+         is_invalid_depth = (bit_depth != 8);
 #ifdef PNG_WRITE_16BIT_SUPPORTED
-         if (bit_depth != 8 && bit_depth != 16)
-#else
-         if (bit_depth != 8)
+         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
 #endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for RGB image");
 
          png_ptr->channels = 3;
@@ -726,18 +726,22 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
          break;
 
       case PNG_COLOR_TYPE_GRAY_ALPHA:
-         if (bit_depth != 8 && bit_depth != 16)
+         is_invalid_depth = (bit_depth != 8);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
+#endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
 
          png_ptr->channels = 2;
          break;
 
       case PNG_COLOR_TYPE_RGB_ALPHA:
+         is_invalid_depth = (bit_depth != 8);
 #ifdef PNG_WRITE_16BIT_SUPPORTED
-         if (bit_depth != 8 && bit_depth != 16)
-#else
-         if (bit_depth != 8)
+         is_invalid_depth = (is_invalid_depth && bit_depth != 16);
 #endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for RGBA image");
 
          png_ptr->channels = 4;
@@ -815,7 +819,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
    buf[12] = (png_byte)interlace_type;
 
    /* Write the chunk */
-   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
+   png_write_complete_chunk(png_ptr, png_IHDR, buf, 13);
 
    if ((png_ptr->do_filter) == PNG_NO_FILTERS)
    {
@@ -884,7 +888,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
       buf[0] = pal_ptr->red;
       buf[1] = pal_ptr->green;
       buf[2] = pal_ptr->blue;
-      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+      png_write_chunk_data(png_ptr, buf, 3);
    }
 
 #else
@@ -898,7 +902,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
       buf[0] = pal_ptr[i].red;
       buf[1] = pal_ptr[i].green;
       buf[2] = pal_ptr[i].blue;
-      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+      png_write_chunk_data(png_ptr, buf, 3);
    }
 
 #endif
@@ -925,7 +929,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
  */
 void /* PRIVATE */
 png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
-   png_alloc_size_t input_len, int flush)
+    png_alloc_size_t input_len, int flush)
 {
    if (png_ptr->zowner != png_IDAT)
    {
@@ -937,7 +941,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
       if (png_ptr->zbuffer_list == NULL)
       {
          png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
-            png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+             png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
          png_ptr->zbuffer_list->next = NULL;
       }
 
@@ -998,7 +1002,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
                optimize_cmf(data, png_image_size(png_ptr));
 #endif
 
-         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+         if (size > 0)
+            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
          png_ptr->mode |= PNG_HAVE_IDAT;
 
          png_ptr->zstream.next_out = data;
@@ -1044,7 +1049,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
             optimize_cmf(data, png_image_size(png_ptr));
 #endif
 
-         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+         if (size > 0)
+            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
          png_ptr->zstream.avail_out = 0;
          png_ptr->zstream.next_out = NULL;
          png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@@ -1068,7 +1074,7 @@ png_write_IEND(png_structrp png_ptr)
 {
    png_debug(1, "in png_write_IEND");
 
-   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
+   png_write_complete_chunk(png_ptr, png_IEND, NULL, 0);
    png_ptr->mode |= PNG_HAVE_IEND;
 }
 
@@ -1083,7 +1089,7 @@ png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
 
    /* file_gamma is saved in 1/100,000ths */
    png_save_uint_32(buf, (png_uint_32)file_gamma);
-   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
+   png_write_complete_chunk(png_ptr, png_gAMA, buf, 4);
 }
 #endif
 
@@ -1101,7 +1107,7 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent)
           "Invalid sRGB rendering intent specified");
 
    buf[0]=(png_byte)srgb_intent;
-   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
+   png_write_complete_chunk(png_ptr, png_sRGB, buf, 1);
 }
 #endif
 
@@ -1175,8 +1181,8 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
    png_uint_32 name_len;
    png_byte new_name[80];
    png_byte entrybuf[10];
-   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
-   png_size_t palette_size = entry_size * spalette->nentries;
+   size_t entry_size = (spalette->depth == 8 ? 6 : 10);
+   size_t palette_size = entry_size * (size_t)spalette->nentries;
    png_sPLT_entryp ep;
 #ifndef PNG_POINTER_INDEXING_SUPPORTED
    int i;
@@ -1193,10 +1199,9 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
    png_write_chunk_header(png_ptr, png_sPLT,
        (png_uint_32)(name_len + 2 + palette_size));
 
-   png_write_chunk_data(png_ptr, (png_bytep)new_name,
-       (png_size_t)(name_len + 1));
+   png_write_chunk_data(png_ptr, (png_bytep)new_name, (size_t)(name_len + 1));
 
-   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
+   png_write_chunk_data(png_ptr, &spalette->depth, 1);
 
    /* Loop through each palette entry, writing appropriately */
 #ifdef PNG_POINTER_INDEXING_SUPPORTED
@@ -1258,7 +1263,7 @@ void /* PRIVATE */
 png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
 {
    png_byte buf[4];
-   png_size_t size;
+   size_t size;
 
    png_debug(1, "in png_write_sBIT");
 
@@ -1358,7 +1363,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
 
       /* Write the chunk out as it is */
       png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
-         (png_size_t)num_trans);
+          (size_t)num_trans);
    }
 
    else if (color_type == PNG_COLOR_TYPE_GRAY)
@@ -1373,7 +1378,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
       }
 
       png_save_uint_16(buf, tran->gray);
-      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
+      png_write_complete_chunk(png_ptr, png_tRNS, buf, 2);
    }
 
    else if (color_type == PNG_COLOR_TYPE_RGB)
@@ -1389,11 +1394,11 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
 #endif
       {
          png_app_warning(png_ptr,
-           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+             "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
          return;
       }
 
-      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
+      png_write_complete_chunk(png_ptr, png_tRNS, buf, 6);
    }
 
    else
@@ -1426,7 +1431,7 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
       }
 
       buf[0] = back->index;
-      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
+      png_write_complete_chunk(png_ptr, png_bKGD, buf, 1);
    }
 
    else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
@@ -1441,12 +1446,13 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
 #endif
       {
          png_warning(png_ptr,
-             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+             "Ignoring attempt to write 16-bit bKGD chunk "
+             "when bit_depth is 8");
 
          return;
       }
 
-      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
+      png_write_complete_chunk(png_ptr, png_bKGD, buf, 6);
    }
 
    else
@@ -1460,8 +1466,30 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
       }
 
       png_save_uint_16(buf, back->gray);
-      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
+      png_write_complete_chunk(png_ptr, png_bKGD, buf, 2);
+   }
+}
+#endif
+
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+/* Write the Exif data */
+void /* PRIVATE */
+png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif)
+{
+   int i;
+   png_byte buf[1];
+
+   png_debug(1, "in png_write_eXIf");
+
+   png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif));
+
+   for (i = 0; i < num_exif; i++)
+   {
+      buf[0] = exif[i];
+      png_write_chunk_data(png_ptr, buf, 1);
    }
+
+   png_write_chunk_end(png_ptr);
 }
 #endif
 
@@ -1489,7 +1517,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
    for (i = 0; i < num_hist; i++)
    {
       png_save_uint_16(buf, hist[i]);
-      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+      png_write_chunk_data(png_ptr, buf, 2);
    }
 
    png_write_chunk_end(png_ptr);
@@ -1500,7 +1528,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
 /* Write a tEXt chunk */
 void /* PRIVATE */
 png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
-    png_size_t text_len)
+    size_t text_len)
 {
    png_uint_32 key_len;
    png_byte new_key[80];
@@ -1571,7 +1599,7 @@ png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
 
    /* Compute the compressed data; do it now for the length */
    png_text_compress_init(&comp, (png_const_bytep)text,
-      text == NULL ? 0 : strlen(text));
+       text == NULL ? 0 : strlen(text));
 
    if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
       png_error(png_ptr, png_ptr->zstream.msg);
@@ -1597,7 +1625,7 @@ png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
     png_const_charp lang, png_const_charp lang_key, png_const_charp text)
 {
    png_uint_32 key_len, prefix_len;
-   png_size_t lang_len, lang_key_len;
+   size_t lang_len, lang_key_len;
    png_byte new_key[82];
    compression_state comp;
 
@@ -1707,7 +1735,7 @@ png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
    png_save_int_32(buf + 4, y_offset);
    buf[8] = (png_byte)unit_type;
 
-   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+   png_write_complete_chunk(png_ptr, png_oFFs, buf, 9);
 }
 #endif
 #ifdef PNG_WRITE_pCAL_SUPPORTED
@@ -1718,7 +1746,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
     png_charpp params)
 {
    png_uint_32 purpose_len;
-   png_size_t units_len, total_len;
+   size_t units_len, total_len;
    png_size_tp params_len;
    png_byte buf[10];
    png_byte new_purpose[80];
@@ -1742,7 +1770,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
    total_len = purpose_len + units_len + 10;
 
    params_len = (png_size_tp)png_malloc(png_ptr,
-       (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
+       (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t))));
 
    /* Find the length of each parameter, making sure we don't count the
     * null terminator for the last parameter.
@@ -1762,8 +1790,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
    png_save_int_32(buf + 4, X1);
    buf[8] = (png_byte)type;
    buf[9] = (png_byte)nparams;
-   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
-   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
+   png_write_chunk_data(png_ptr, buf, 10);
+   png_write_chunk_data(png_ptr, (png_const_bytep)units, (size_t)units_len);
 
    for (i = 0; i < nparams; i++)
    {
@@ -1782,7 +1810,7 @@ png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
     png_const_charp height)
 {
    png_byte buf[64];
-   png_size_t wlen, hlen, total_len;
+   size_t wlen, hlen, total_len;
 
    png_debug(1, "in png_write_sCAL_s");
 
@@ -1823,7 +1851,7 @@ png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
    png_save_uint_32(buf + 4, y_pixels_per_unit);
    buf[8] = (png_byte)unit_type;
 
-   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+   png_write_complete_chunk(png_ptr, png_pHYs, buf, 9);
 }
 #endif
 
@@ -1853,7 +1881,7 @@ png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
    buf[5] = mod_time->minute;
    buf[6] = mod_time->second;
 
-   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+   png_write_complete_chunk(png_ptr, png_tIME, buf, 7);
 }
 #endif
 
@@ -1865,16 +1893,16 @@ png_write_start_row(png_structrp png_ptr)
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
 
    /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
 
    /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
 
    /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+   static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
 #endif
 
    png_alloc_size_t buf_size;
@@ -1941,7 +1969,7 @@ png_write_start_row(png_structrp png_ptr)
     */
    if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
       png_ptr->prev_row = png_voidcast(png_bytep,
-         png_calloc(png_ptr, buf_size));
+          png_calloc(png_ptr, buf_size));
 #endif /* WRITE_FILTER */
 
 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
@@ -1980,16 +2008,16 @@ png_write_finish_row(png_structrp png_ptr)
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
 
    /* Offset to next interlace block */
-   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
 
    /* Start of interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
 
    /* Offset to next interlace block in the y direction */
-   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+   static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
 #endif
 
    png_debug(1, "in png_write_finish_row");
@@ -2043,8 +2071,8 @@ png_write_finish_row(png_structrp png_ptr)
       {
          if (png_ptr->prev_row != NULL)
             memset(png_ptr->prev_row, 0,
-                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
-                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
+                PNG_ROWBYTES(png_ptr->usr_channels *
+                png_ptr->usr_bit_depth, png_ptr->width) + 1);
 
          return;
       }
@@ -2070,10 +2098,10 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
-   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
 
    /* Offset to next interlace block */
-   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
 
    png_debug(1, "in png_do_write_interlace");
 
@@ -2100,7 +2128,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
             for (i = png_pass_start[pass]; i < row_width;
                i += png_pass_inc[pass])
             {
-               sp = row + (png_size_t)(i >> 3);
+               sp = row + (size_t)(i >> 3);
                value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
                d |= (value << shift);
 
@@ -2138,7 +2166,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
             for (i = png_pass_start[pass]; i < row_width;
                i += png_pass_inc[pass])
             {
-               sp = row + (png_size_t)(i >> 2);
+               sp = row + (size_t)(i >> 2);
                value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
                d |= (value << shift);
 
@@ -2174,7 +2202,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
             for (i = png_pass_start[pass]; i < row_width;
                 i += png_pass_inc[pass])
             {
-               sp = row + (png_size_t)(i >> 1);
+               sp = row + (size_t)(i >> 1);
                value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
                d |= (value << shift);
 
@@ -2200,7 +2228,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
             png_bytep dp;
             png_uint_32 i;
             png_uint_32 row_width = row_info->width;
-            png_size_t pixel_bytes;
+            size_t pixel_bytes;
 
             /* Start at the beginning */
             dp = row;
@@ -2213,7 +2241,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
                i += png_pass_inc[pass])
             {
                /* Find out where the original pixel is */
-               sp = row + (png_size_t)i * pixel_bytes;
+               sp = row + (size_t)i * pixel_bytes;
 
                /* Move the pixel */
                if (dp != sp)
@@ -2244,17 +2272,17 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
  */
 static void /* PRIVATE */
 png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
-   png_size_t row_bytes);
+    size_t row_bytes);
 
 #ifdef PNG_WRITE_FILTER_SUPPORTED
-static png_size_t /* PRIVATE */
-png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
-    const png_size_t row_bytes, const png_size_t lmins)
+static size_t /* PRIVATE */
+png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp,
+    size_t row_bytes, size_t lmins)
 {
    png_bytep rp, dp, lp;
-   png_size_t i;
-   png_size_t sum = 0;
-   int v;
+   size_t i;
+   size_t sum = 0;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
 
@@ -2262,14 +2290,22 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
         i++, rp++, dp++)
    {
       v = *dp = *rp;
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
    }
 
    for (lp = png_ptr->row_buf + 1; i < row_bytes;
       i++, rp++, lp++, dp++)
    {
       v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2278,14 +2314,35 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
    return (sum);
 }
 
-static png_size_t /* PRIVATE */
-png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
-    const png_size_t lmins)
+static void /* PRIVATE */
+png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp,
+    size_t row_bytes)
+{
+   png_bytep rp, dp, lp;
+   size_t i;
+
+   png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
+
+   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
+        i++, rp++, dp++)
+   {
+      *dp = *rp;
+   }
+
+   for (lp = png_ptr->row_buf + 1; i < row_bytes;
+      i++, rp++, lp++, dp++)
+   {
+      *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+   }
+}
+
+static size_t /* PRIVATE */
+png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins)
 {
    png_bytep rp, dp, pp;
-   png_size_t i;
-   png_size_t sum = 0;
-   int v;
+   size_t i;
+   size_t sum = 0;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
 
@@ -2294,7 +2351,11 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
        i++, rp++, pp++, dp++)
    {
       v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2302,24 +2363,43 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
 
    return (sum);
 }
+static void /* PRIVATE */
+png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes)
+{
+   png_bytep rp, dp, pp;
+   size_t i;
+
+   png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
 
-static png_size_t /* PRIVATE */
-png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
-      const png_size_t row_bytes, const png_size_t lmins)
+   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+       pp = png_ptr->prev_row + 1; i < row_bytes;
+       i++, rp++, pp++, dp++)
+   {
+      *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+   }
+}
+
+static size_t /* PRIVATE */
+png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp,
+    size_t row_bytes, size_t lmins)
 {
    png_bytep rp, dp, pp, lp;
    png_uint_32 i;
-   png_size_t sum = 0;
-   int v;
+   size_t sum = 0;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
 
    for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
-        pp = png_ptr->prev_row + 1; i < bpp; i++)
+       pp = png_ptr->prev_row + 1; i < bpp; i++)
    {
       v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
    }
 
    for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
@@ -2327,7 +2407,11 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
       v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
           & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2335,15 +2419,36 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
 
    return (sum);
 }
+static void /* PRIVATE */
+png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp,
+    size_t row_bytes)
+{
+   png_bytep rp, dp, pp, lp;
+   png_uint_32 i;
+
+   png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
+
+   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+       pp = png_ptr->prev_row + 1; i < bpp; i++)
+   {
+      *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+   }
+
+   for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
+   {
+      *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+          & 0xff);
+   }
+}
 
-static png_size_t /* PRIVATE */
-png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
-    const png_size_t row_bytes, const png_size_t lmins)
+static size_t /* PRIVATE */
+png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp,
+    size_t row_bytes, size_t lmins)
 {
    png_bytep rp, dp, pp, cp, lp;
-   png_size_t i;
-   png_size_t sum = 0;
-   int v;
+   size_t i;
+   size_t sum = 0;
+   unsigned int v;
 
    png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
 
@@ -2352,7 +2457,11 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
    {
       v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
    }
 
    for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
@@ -2381,7 +2490,11 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
 
       v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
 
+#ifdef PNG_USE_ABS
+      sum += 128 - abs((int)v - 128);
+#else
       sum += (v < 128) ? v : 256 - v;
+#endif
 
       if (sum > lmins)  /* We are already worse, don't continue. */
         break;
@@ -2389,6 +2502,48 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
 
    return (sum);
 }
+static void /* PRIVATE */
+png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp,
+    size_t row_bytes)
+{
+   png_bytep rp, dp, pp, cp, lp;
+   size_t i;
+
+   png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
+
+   for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+       pp = png_ptr->prev_row + 1; i < bpp; i++)
+   {
+      *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+   }
+
+   for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
+        i++)
+   {
+      int a, b, c, pa, pb, pc, p;
+
+      b = *pp++;
+      c = *cp++;
+      a = *lp++;
+
+      p = b - c;
+      pc = a - c;
+
+#ifdef PNG_USE_ABS
+      pa = abs(p);
+      pb = abs(pc);
+      pc = abs(p + pc);
+#else
+      pa = p < 0 ? -p : p;
+      pb = pc < 0 ? -pc : pc;
+      pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+      p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+      *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+   }
+}
 #endif /* WRITE_FILTER */
 
 void /* PRIVATE */
@@ -2397,12 +2552,12 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
 #ifndef PNG_WRITE_FILTER_SUPPORTED
    png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
 #else
-   png_byte filter_to_do = png_ptr->do_filter;
+   unsigned int filter_to_do = png_ptr->do_filter;
    png_bytep row_buf;
    png_bytep best_row;
    png_uint_32 bpp;
-   png_size_t mins;
-   png_size_t row_bytes = row_info->rowbytes;
+   size_t mins;
+   size_t row_bytes = row_info->rowbytes;
 
    png_debug(1, "in png_write_find_filter");
 
@@ -2443,32 +2598,33 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
     */
    best_row = png_ptr->row_buf;
 
-
-   if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE)
+   if (PNG_SIZE_MAX/128 <= row_bytes)
    {
+      /* Overflow can occur in the calculation, just select the lowest set
+       * filter.
+       */
+      filter_to_do &= 0U-filter_to_do;
+   }
+   else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
+         filter_to_do != PNG_FILTER_NONE)
+   {
+      /* Overflow not possible and multiple filters in the list, including the
+       * 'none' filter.
+       */
       png_bytep rp;
-      png_size_t sum = 0;
-      png_size_t i;
-      int v;
+      size_t sum = 0;
+      size_t i;
+      unsigned int v;
 
-      if (PNG_SIZE_MAX/128 <= row_bytes)
-      {
-         for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
-         {
-            /* Check for overflow */
-            if (sum > PNG_SIZE_MAX/128 - 256)
-               break;
-
-            v = *rp;
-            sum += (v < 128) ? v : 256 - v;
-         }
-      }
-      else /* Overflow is not possible */
       {
          for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
          {
             v = *rp;
+#ifdef PNG_USE_ABS
+            sum += 128 - abs((int)v - 128);
+#else
             sum += (v < 128) ? v : 256 - v;
+#endif
          }
       }
 
@@ -2479,14 +2635,14 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
    if (filter_to_do == PNG_FILTER_SUB)
    /* It's the only filter so no testing is needed */
    {
-      (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);
+      png_setup_sub_row_only(png_ptr, bpp, row_bytes);
       best_row = png_ptr->try_row;
    }
 
    else if ((filter_to_do & PNG_FILTER_SUB) != 0)
    {
-      png_size_t sum;
-      png_size_t lmins = mins;
+      size_t sum;
+      size_t lmins = mins;
 
       sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
 
@@ -2505,14 +2661,14 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
    /* Up filter */
    if (filter_to_do == PNG_FILTER_UP)
    {
-      (void) png_setup_up_row(png_ptr, row_bytes, mins);
+      png_setup_up_row_only(png_ptr, row_bytes);
       best_row = png_ptr->try_row;
    }
 
    else if ((filter_to_do & PNG_FILTER_UP) != 0)
    {
-      png_size_t sum;
-      png_size_t lmins = mins;
+      size_t sum;
+      size_t lmins = mins;
 
       sum = png_setup_up_row(png_ptr, row_bytes, lmins);
 
@@ -2531,14 +2687,14 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
    /* Avg filter */
    if (filter_to_do == PNG_FILTER_AVG)
    {
-      (void) png_setup_avg_row(png_ptr, bpp, row_bytes, mins);
+      png_setup_avg_row_only(png_ptr, bpp, row_bytes);
       best_row = png_ptr->try_row;
    }
 
    else if ((filter_to_do & PNG_FILTER_AVG) != 0)
    {
-      png_size_t sum;
-      png_size_t lmins = mins;
+      size_t sum;
+      size_t lmins = mins;
 
       sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
 
@@ -2555,16 +2711,16 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
    }
 
    /* Paeth filter */
-   if ((filter_to_do == PNG_FILTER_PAETH) != 0)
+   if (filter_to_do == PNG_FILTER_PAETH)
    {
-      (void) png_setup_paeth_row(png_ptr, bpp, row_bytes, mins);
+      png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
       best_row = png_ptr->try_row;
    }
 
    else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
    {
-      png_size_t sum;
-      png_size_t lmins = mins;
+      size_t sum;
+      size_t lmins = mins;
 
       sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
 
@@ -2589,7 +2745,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
 /* Do the actual writing of a previously filtered row. */
 static void
 png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
-   png_size_t full_row_length/*includes filter byte*/)
+    size_t full_row_length/*includes filter byte*/)
 {
    png_debug(1, "in png_write_filtered_row");
 
diff --git a/powerpc/filter_vsx_intrinsics.c b/powerpc/filter_vsx_intrinsics.c
new file mode 100644 (file)
index 0000000..01cf880
--- /dev/null
@@ -0,0 +1,768 @@
+/* filter_vsx_intrinsics.c - PowerPC optimised filter functions
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2017 Glenn Randers-Pehrson
+ * Written by Vadim Barkov, 2017.
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* This code requires -maltivec and -mvsx on the command line: */
+#if PNG_POWERPC_VSX_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
+
+#include <altivec.h>
+
+#if PNG_POWERPC_VSX_OPT > 0
+
+#ifndef __VSX__
+#  error "This code requires VSX support (POWER7 and later). Please provide -mvsx compiler flag."
+#endif
+
+#define vec_ld_unaligned(vec,data) vec = vec_vsx_ld(0,data)
+#define vec_st_unaligned(vec,data) vec_vsx_st(vec,0,data)
+
+
+/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
+ * They're positioned like this:
+ *    prev:  c b
+ *    row:   a d
+ * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
+ * whichever of a, b, or c is closest to p=a+b-c.
+ * ( this is taken from ../intel/filter_sse2_intrinsics.c )
+ */
+
+#define vsx_declare_common_vars(row_info,row,prev_row,offset) \
+   png_byte i;\
+   png_bytep rp = row + offset;\
+   png_const_bytep pp = prev_row;\
+   size_t unaligned_top = 16 - (((size_t)rp % 16));\
+   size_t istop;\
+   if(unaligned_top == 16)\
+      unaligned_top = 0;\
+   istop = row_info->rowbytes;\
+   if((unaligned_top < istop))\
+      istop -= unaligned_top;\
+   else{\
+      unaligned_top = istop;\
+      istop = 0;\
+   }
+
+void png_read_filter_row_up_vsx(png_row_infop row_info, png_bytep row,
+                                png_const_bytep prev_row)
+{
+   vector unsigned char rp_vec;
+   vector unsigned char pp_vec;
+   vsx_declare_common_vars(row_info,row,prev_row,0)
+
+   /* Altivec operations require 16-byte aligned data
+    * but input can be unaligned. So we calculate
+    * unaligned part as usual.
+    */
+   for (i = 0; i < unaligned_top; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+      rp++;
+   }
+
+   /* Using SIMD while we can */
+   while( istop >= 16 )
+   {
+      rp_vec = vec_ld(0,rp);
+      vec_ld_unaligned(pp_vec,pp);
+
+      rp_vec = vec_add(rp_vec,pp_vec);
+
+      vec_st(rp_vec,0,rp);
+
+      pp += 16;
+      rp += 16;
+      istop -= 16;
+   }
+
+   if(istop > 0)
+   {
+      /* If byte count of row is not divisible by 16
+       * we will process remaining part as usual
+       */
+      for (i = 0; i < istop; i++)
+      {
+         *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+         rp++;
+      }
+}
+
+}
+
+static const vector unsigned char VSX_LEFTSHIFTED1_4 = {16,16,16,16, 0, 1, 2, 3,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED2_4 = {16,16,16,16,16,16,16,16, 4, 5, 6, 7,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 8, 9,10,11};
+
+static const vector unsigned char VSX_LEFTSHIFTED1_3 = {16,16,16, 0, 1, 2,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED2_3 = {16,16,16,16,16,16, 3, 4, 5,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 6, 7, 8,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 9,10,11,16};
+
+static const vector unsigned char VSX_NOT_SHIFTED1_4 = {16,16,16,16, 4, 5, 6, 7,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED2_4 = {16,16,16,16,16,16,16,16, 8, 9,10,11,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,15};
+
+static const vector unsigned char VSX_NOT_SHIFTED1_3 = {16,16,16, 3, 4, 5,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED2_3 = {16,16,16,16,16,16, 6, 7, 8,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 9,10,11,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,16};
+
+static const vector unsigned char VSX_CHAR_ZERO = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+#ifdef __LITTLE_ENDIAN__
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = { 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = { 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {12,16,13,16,14,16,15,16,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 0, 2, 4, 6,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 0, 2, 4, 6,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4, 6};
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = { 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = { 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = { 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {12,16,13,16,14,16,16,16,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 0, 2, 4,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 0, 2, 4,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 0, 2, 4,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4,16};
+
+#elif defined(__BIG_ENDIAN__)
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = {16, 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = {16, 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {16,12,16,13,16,14,16,15,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 1, 3, 5, 7,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 1, 3, 5, 7,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5, 7};
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = {16, 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = {16, 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = {16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {16,12,16,13,16,14,16,16,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 1, 3, 5,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 1, 3, 5,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 1, 3, 5,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5,16};
+
+#endif
+
+#define vsx_char_to_short(vec,offset,bpp) (vector unsigned short)vec_perm((vec),VSX_CHAR_ZERO,VSX_CHAR_TO_SHORT##offset##_##bpp)
+#define vsx_short_to_char(vec,offset,bpp) vec_perm(((vector unsigned char)(vec)),VSX_CHAR_ZERO,VSX_SHORT_TO_CHAR##offset##_##bpp)
+
+#ifdef PNG_USE_ABS
+#  define vsx_abs(number) abs(number)
+#else
+#  define vsx_abs(number) (number > 0) ? (number) : -(number)
+#endif
+
+void png_read_filter_row_sub4_vsx(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+   png_byte bpp = 4;
+
+   vector unsigned char rp_vec;
+   vector unsigned char part_vec;
+
+   vsx_declare_common_vars(row_info,row,prev_row,bpp)
+
+   PNG_UNUSED(pp)
+
+   /* Altivec operations require 16-byte aligned data
+    * but input can be unaligned. So we calculate
+    * unaligned part as usual.
+    */
+   for (i = 0; i < unaligned_top; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+      rp++;
+   }
+
+   /* Using SIMD while we can */
+   while( istop >= 16 )
+   {
+      for(i=0;i < bpp ; i++)
+      {
+         *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+         rp++;
+      }
+      rp -= bpp;
+
+      rp_vec = vec_ld(0,rp);
+      part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
+      rp_vec = vec_add(rp_vec,part_vec);
+
+      part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
+      rp_vec = vec_add(rp_vec,part_vec);
+
+      part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
+      rp_vec = vec_add(rp_vec,part_vec);
+
+      vec_st(rp_vec,0,rp);
+
+      rp += 16;
+      istop -= 16;
+   }
+
+   if(istop > 0)
+      for (i = 0; i < istop % 16; i++)
+      {
+         *rp = (png_byte)(((int)(*rp) + (int)(*(rp - bpp))) & 0xff);
+         rp++;
+      }
+
+}
+
+void png_read_filter_row_sub3_vsx(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+   png_byte bpp = 3;
+
+   vector unsigned char rp_vec;
+   vector unsigned char part_vec;
+
+   vsx_declare_common_vars(row_info,row,prev_row,bpp)
+
+   PNG_UNUSED(pp)
+
+   /* Altivec operations require 16-byte aligned data
+    * but input can be unaligned. So we calculate
+    * unaligned part as usual.
+    */
+   for (i = 0; i < unaligned_top; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+      rp++;
+   }
+
+   /* Using SIMD while we can */
+   while( istop >= 16 )
+   {
+      for(i=0;i < bpp ; i++)
+      {
+         *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+         rp++;
+      }
+      rp -= bpp;
+
+      rp_vec = vec_ld(0,rp);
+      part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
+      rp_vec = vec_add(rp_vec,part_vec);
+
+      part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
+      rp_vec = vec_add(rp_vec,part_vec);
+
+      part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
+      rp_vec = vec_add(rp_vec,part_vec);
+
+      part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
+      rp_vec = vec_add(rp_vec,part_vec);
+
+      vec_st(rp_vec,0,rp);
+      rp += 15;
+      istop -= 16;
+
+      /* Since 16 % bpp = 16 % 3 = 1, last element of array must
+       * be proceeded manually
+       */
+      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+      rp++;
+   }
+
+   if(istop > 0)
+      for (i = 0; i < istop % 16; i++)
+      {
+         *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+         rp++;
+      }
+}
+
+void png_read_filter_row_avg4_vsx(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+   png_byte bpp = 4;
+
+   vector unsigned char rp_vec;
+   vector unsigned char pp_vec;
+   vector unsigned char pp_part_vec;
+   vector unsigned char rp_part_vec;
+   vector unsigned char avg_vec;
+
+   vsx_declare_common_vars(row_info,row,prev_row,bpp)
+   rp -= bpp;
+   if(istop >= bpp)
+      istop -= bpp;
+
+   for (i = 0; i < bpp; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) +
+         ((int)(*pp++) / 2 )) & 0xff);
+
+      rp++;
+   }
+
+   /* Altivec operations require 16-byte aligned data
+    * but input can be unaligned. So we calculate
+    * unaligned part as usual.
+    */
+   for (i = 0; i < unaligned_top; i++)
+   {
+      *rp = (png_byte)(((int)(*rp) +
+         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+      rp++;
+   }
+
+   /* Using SIMD while we can */
+   while( istop >= 16 )
+   {
+      for(i=0;i < bpp ; i++)
+      {
+         *rp = (png_byte)(((int)(*rp) +
+            (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+         rp++;
+      }
+      rp -= bpp;
+      pp -= bpp;
+
+      vec_ld_unaligned(pp_vec,pp);
+      rp_vec = vec_ld(0,rp);
+
+      rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
+      pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_4);
+      avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+      avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+      rp_vec = vec_add(rp_vec,avg_vec);
+
+      rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
+      pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_4);
+      avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+      avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+      rp_vec = vec_add(rp_vec,avg_vec);
+
+      rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
+      pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_4);
+      avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+      avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+      rp_vec = vec_add(rp_vec,avg_vec);
+
+      vec_st(rp_vec,0,rp);
+
+      rp += 16;
+      pp += 16;
+      istop -= 16;
+   }
+
+   if(istop  > 0)
+      for (i = 0; i < istop % 16; i++)
+      {
+         *rp = (png_byte)(((int)(*rp) +
+            (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+         rp++;
+      }
+}
+
+void png_read_filter_row_avg3_vsx(png_row_infop row_info, png_bytep row,
+                                  png_const_bytep prev_row)
+{
+  png_byte bpp = 3;
+
+  vector unsigned char rp_vec;
+  vector unsigned char pp_vec;
+  vector unsigned char pp_part_vec;
+  vector unsigned char rp_part_vec;
+  vector unsigned char avg_vec;
+
+  vsx_declare_common_vars(row_info,row,prev_row,bpp)
+  rp -= bpp;
+  if(istop >= bpp)
+     istop -= bpp;
+
+  for (i = 0; i < bpp; i++)
+  {
+     *rp = (png_byte)(((int)(*rp) +
+        ((int)(*pp++) / 2 )) & 0xff);
+
+     rp++;
+  }
+
+  /* Altivec operations require 16-byte aligned data
+   * but input can be unaligned. So we calculate
+   * unaligned part as usual.
+   */
+  for (i = 0; i < unaligned_top; i++)
+  {
+     *rp = (png_byte)(((int)(*rp) +
+        (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+     rp++;
+  }
+
+  /* Using SIMD while we can */
+  while( istop >= 16 )
+  {
+     for(i=0;i < bpp ; i++)
+     {
+        *rp = (png_byte)(((int)(*rp) +
+           (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+        rp++;
+     }
+     rp -= bpp;
+     pp -= bpp;
+
+     vec_ld_unaligned(pp_vec,pp);
+     rp_vec = vec_ld(0,rp);
+
+     rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
+     pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_3);
+     avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+     avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+     rp_vec = vec_add(rp_vec,avg_vec);
+
+     rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
+     pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_3);
+     avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+     avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+     rp_vec = vec_add(rp_vec,avg_vec);
+
+     rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
+     pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_3);
+     avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+     avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+     rp_vec = vec_add(rp_vec,avg_vec);
+
+     rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
+     pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED4_3);
+     avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+     avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+     rp_vec = vec_add(rp_vec,avg_vec);
+
+     vec_st(rp_vec,0,rp);
+
+     rp += 15;
+     pp += 15;
+     istop -= 16;
+
+     /* Since 16 % bpp = 16 % 3 = 1, last element of array must
+      * be proceeded manually
+      */
+     *rp = (png_byte)(((int)(*rp) +
+        (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+     rp++;
+  }
+
+  if(istop  > 0)
+     for (i = 0; i < istop % 16; i++)
+     {
+        *rp = (png_byte)(((int)(*rp) +
+           (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+        rp++;
+     }
+}
+
+/* Bytewise c ? t : e. */
+#define if_then_else(c,t,e) vec_sel(e,t,c)
+
+#define vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) {\
+      c = *(pp - bpp);\
+      a = *(rp - bpp);\
+      b = *pp++;\
+      p = b - c;\
+      pc = a - c;\
+      pa = vsx_abs(p);\
+      pb = vsx_abs(pc);\
+      pc = vsx_abs(p + pc);\
+      if (pb < pa) pa = pb, a = b;\
+      if (pc < pa) a = c;\
+      a += *rp;\
+      *rp++ = (png_byte)a;\
+      }
+
+void png_read_filter_row_paeth4_vsx(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+   png_byte bpp = 4;
+
+   int a, b, c, pa, pb, pc, p;
+   vector unsigned char rp_vec;
+   vector unsigned char pp_vec;
+   vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
+   vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
+
+   vsx_declare_common_vars(row_info,row,prev_row,bpp)
+   rp -= bpp;
+   if(istop >= bpp)
+      istop -= bpp;
+
+   /* Process the first pixel in the row completely (this is the same as 'up'
+    * because there is only one candidate predictor for the first row).
+    */
+   for(i = 0; i < bpp ; i++)
+   {
+      *rp = (png_byte)( *rp + *pp);
+      rp++;
+      pp++;
+   }
+
+   for(i = 0; i < unaligned_top ; i++)
+   {
+      vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+   }
+
+   while( istop >= 16)
+   {
+      for(i = 0; i < bpp ; i++)
+      {
+         vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+      }
+
+      rp -= bpp;
+      pp -= bpp;
+      rp_vec = vec_ld(0,rp);
+      vec_ld_unaligned(pp_vec,pp);
+
+      a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
+      b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_4),1,4);
+      c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
+      pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+      pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+      pc_vec = vec_add(pa_vec,pb_vec);
+      pa_vec = vec_abs(pa_vec);
+      pb_vec = vec_abs(pb_vec);
+      pc_vec = vec_abs(pc_vec);
+      smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+      nearest_vec =  if_then_else(
+            vec_cmpeq(pa_vec,smallest_vec),
+            a_vec,
+            if_then_else(
+              vec_cmpeq(pb_vec,smallest_vec),
+              b_vec,
+              c_vec
+              )
+            );
+      rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,4)));
+
+      a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
+      b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_4),2,4);
+      c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
+      pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+      pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+      pc_vec = vec_add(pa_vec,pb_vec);
+      pa_vec = vec_abs(pa_vec);
+      pb_vec = vec_abs(pb_vec);
+      pc_vec = vec_abs(pc_vec);
+      smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+      nearest_vec =  if_then_else(
+            vec_cmpeq(pa_vec,smallest_vec),
+            a_vec,
+            if_then_else(
+              vec_cmpeq(pb_vec,smallest_vec),
+              b_vec,
+              c_vec
+              )
+            );
+      rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,4)));
+
+      a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
+      b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_4),3,4);
+      c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
+      pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+      pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+      pc_vec = vec_add(pa_vec,pb_vec);
+      pa_vec = vec_abs(pa_vec);
+      pb_vec = vec_abs(pb_vec);
+      pc_vec = vec_abs(pc_vec);
+      smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+      nearest_vec =  if_then_else(
+            vec_cmpeq(pa_vec,smallest_vec),
+            a_vec,
+            if_then_else(
+              vec_cmpeq(pb_vec,smallest_vec),
+              b_vec,
+              c_vec
+              )
+            );
+      rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,4)));
+
+      vec_st(rp_vec,0,rp);
+
+      rp += 16;
+      pp += 16;
+      istop -= 16;
+   }
+
+   if(istop > 0)
+      for (i = 0; i < istop % 16; i++)
+      {
+         vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+      }
+}
+
+void png_read_filter_row_paeth3_vsx(png_row_infop row_info, png_bytep row,
+   png_const_bytep prev_row)
+{
+  png_byte bpp = 3;
+
+  int a, b, c, pa, pb, pc, p;
+  vector unsigned char rp_vec;
+  vector unsigned char pp_vec;
+  vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
+  vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
+
+  vsx_declare_common_vars(row_info,row,prev_row,bpp)
+  rp -= bpp;
+  if(istop >= bpp)
+     istop -= bpp;
+
+  /* Process the first pixel in the row completely (this is the same as 'up'
+   * because there is only one candidate predictor for the first row).
+   */
+  for(i = 0; i < bpp ; i++)
+  {
+     *rp = (png_byte)( *rp + *pp);
+     rp++;
+     pp++;
+  }
+
+  for(i = 0; i < unaligned_top ; i++)
+  {
+     vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+  }
+
+  while( istop >= 16)
+  {
+     for(i = 0; i < bpp ; i++)
+     {
+        vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+     }
+
+     rp -= bpp;
+     pp -= bpp;
+     rp_vec = vec_ld(0,rp);
+     vec_ld_unaligned(pp_vec,pp);
+
+     a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
+     b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_3),1,3);
+     c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
+     pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+     pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+     pc_vec = vec_add(pa_vec,pb_vec);
+     pa_vec = vec_abs(pa_vec);
+     pb_vec = vec_abs(pb_vec);
+     pc_vec = vec_abs(pc_vec);
+     smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+     nearest_vec =  if_then_else(
+           vec_cmpeq(pa_vec,smallest_vec),
+           a_vec,
+           if_then_else(
+             vec_cmpeq(pb_vec,smallest_vec),
+             b_vec,
+             c_vec
+             )
+           );
+     rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,3)));
+
+     a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
+     b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_3),2,3);
+     c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
+     pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+     pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+     pc_vec = vec_add(pa_vec,pb_vec);
+     pa_vec = vec_abs(pa_vec);
+     pb_vec = vec_abs(pb_vec);
+     pc_vec = vec_abs(pc_vec);
+     smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+     nearest_vec =  if_then_else(
+           vec_cmpeq(pa_vec,smallest_vec),
+           a_vec,
+           if_then_else(
+             vec_cmpeq(pb_vec,smallest_vec),
+             b_vec,
+             c_vec
+             )
+           );
+     rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,3)));
+
+     a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
+     b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_3),3,3);
+     c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
+     pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+     pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+     pc_vec = vec_add(pa_vec,pb_vec);
+     pa_vec = vec_abs(pa_vec);
+     pb_vec = vec_abs(pb_vec);
+     pc_vec = vec_abs(pc_vec);
+     smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+     nearest_vec =  if_then_else(
+           vec_cmpeq(pa_vec,smallest_vec),
+           a_vec,
+           if_then_else(
+             vec_cmpeq(pb_vec,smallest_vec),
+             b_vec,
+             c_vec
+             )
+           );
+     rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,3)));
+
+     a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
+     b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED4_3),4,3);
+     c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
+     pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+     pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+     pc_vec = vec_add(pa_vec,pb_vec);
+     pa_vec = vec_abs(pa_vec);
+     pb_vec = vec_abs(pb_vec);
+     pc_vec = vec_abs(pc_vec);
+     smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+     nearest_vec =  if_then_else(
+           vec_cmpeq(pa_vec,smallest_vec),
+           a_vec,
+           if_then_else(
+             vec_cmpeq(pb_vec,smallest_vec),
+             b_vec,
+             c_vec
+             )
+           );
+     rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,4,3)));
+
+     vec_st(rp_vec,0,rp);
+
+     rp += 15;
+     pp += 15;
+     istop -= 16;
+
+     /* Since 16 % bpp = 16 % 3 = 1, last element of array must
+      * be proceeded manually
+      */
+     vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+  }
+
+  if(istop > 0)
+     for (i = 0; i < istop % 16; i++)
+     {
+        vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+     }
+}
+
+#endif /* PNG_POWERPC_VSX_OPT > 0 */
+#endif /* PNG_POWERPC_VSX_IMPLEMENTATION == 1 (intrinsics) */
+#endif /* READ */
diff --git a/powerpc/powerpc_init.c b/powerpc/powerpc_init.c
new file mode 100644 (file)
index 0000000..54426c5
--- /dev/null
@@ -0,0 +1,126 @@
+
+/* powerpc_init.c - POWERPC optimised filter functions
+ *
+ * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2017 Glenn Randers-Pehrson
+ * Written by Vadim Barkov, 2017.
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
+ * called.
+ */
+#define _POSIX_SOURCE 1
+
+#include <stdio.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+#if PNG_POWERPC_VSX_OPT > 0
+#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED /* Do run-time checks */
+/* WARNING: it is strongly recommended that you do not build libpng with
+ * run-time checks for CPU features if at all possible.  In the case of the PowerPC
+ * VSX instructions there is no processor-specific way of detecting the
+ * presence of the required support, therefore run-time detection is extremely
+ * OS specific.
+ *
+ * You may set the macro PNG_POWERPC_VSX_FILE to the file name of file containing
+ * a fragment of C source code which defines the png_have_vsx function.  There
+ * are a number of implementations in contrib/powerpc-vsx, but the only one that
+ * has partial support is contrib/powerpc-vsx/linux.c - a generic Linux
+ * implementation which reads /proc/cpufino.
+ */
+#ifndef PNG_POWERPC_VSX_FILE
+#  ifdef __linux__
+#     define  PNG_POWERPC_VSX_FILE "contrib/powerpc-vsx/linux_aux.c"
+#  endif
+#endif
+
+#ifdef PNG_POWERPC_VSX_FILE
+
+#include <signal.h> /* for sig_atomic_t */
+static int png_have_vsx(png_structp png_ptr);
+#include PNG_POWERPC_VSX_FILE
+
+#else  /* PNG_POWERPC_VSX_FILE */
+#  error "PNG_POWERPC_VSX_FILE undefined: no support for run-time POWERPC VSX checks"
+#endif /* PNG_POWERPC_VSX_FILE */
+#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
+
+void
+png_init_filter_functions_vsx(png_structp pp, unsigned int bpp)
+{
+   /* The switch statement is compiled in for POWERPC_VSX_API, the call to
+    * png_have_vsx is compiled in for POWERPC_VSX_CHECK. If both are defined
+    * the check is only performed if the API has not set the PowerPC option on
+    * or off explicitly. In this case the check controls what happens.
+    */
+
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+   switch ((pp->options >> PNG_POWERPC_VSX) & 3)
+   {
+      case PNG_OPTION_UNSET:
+         /* Allow the run-time check to execute if it has been enabled -
+          * thus both API and CHECK can be turned on.  If it isn't supported
+          * this case will fall through to the 'default' below, which just
+          * returns.
+          */
+#endif /* PNG_POWERPC_VSX_API_SUPPORTED */
+#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED
+         {
+            static volatile sig_atomic_t no_vsx = -1; /* not checked */
+
+            if (no_vsx < 0)
+               no_vsx = !png_have_vsx(pp);
+
+            if (no_vsx)
+               return;
+         }
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+         break;
+#endif
+#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
+
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+      default: /* OFF or INVALID */
+         return;
+
+      case PNG_OPTION_ON:
+         /* Option turned on */
+         break;
+   }
+#endif
+
+   /* IMPORTANT: any new internal functions used here must be declared using
+    * PNG_INTERNAL_FUNCTION in ../pngpriv.h.  This is required so that the
+    * 'prefix' option to configure works:
+    *
+    *    ./configure --with-libpng-prefix=foobar_
+    *
+    * Verify you have got this right by running the above command, doing a build
+    * and examining pngprefix.h; it must contain a #define for every external
+    * function you add.  (Notice that this happens automatically for the
+    * initialization function.)
+    */
+   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_vsx;
+
+   if (bpp == 3)
+   {
+      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_vsx;
+      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_vsx;
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_vsx;
+   }
+
+   else if (bpp == 4)
+   {
+      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_vsx;
+      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_vsx;
+      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_vsx;
+   }
+}
+#endif /* PNG_POWERPC_VSX_OPT > 0 */
+#endif /* READ */
index 054a3fc..11f1aa7 100644 (file)
@@ -117,7 +117,7 @@ $#   3) Delete this file (config.inf).
 <<\r
  @$(COPY) << pngconfig.dfa\r
 $# pngconfig.dfa: this file contains configuration options for libpng.\r
-$# If emtpy the standard configuration will be built.  For this file to be\r
+$# If empty the standard configuration will be built.  For this file to be\r
 $# used a working version of the program 'awk' is required and the program\r
 $# must be identified in the 'before' rule of the project.\r
 $#\r
@@ -126,7 +126,7 @@ $# to work, download Brian Kernighan's awk (Brian Kernighan is the author of
 $# awk.)  You can find source code and a built executable (called awk95.exe)\r
 $# here:\r
 $#\r
-$#     http://www.cs.princeton.edu/~bwk/btl.mirror/\r
+$#     https://www.cs.princeton.edu/~bwk/btl.mirror/\r
 $#\r
 $# The executable works just fine.\r
 $#\r
@@ -144,7 +144,7 @@ $# dependency on pnglibconf.h correctly.
 $#\r
 $# If awk isn't set then this file is bypassed.  If you just want the standard\r
 $# configuration it is automatically produced from the distributed version\r
-$# (scripts\pnglibconf.h.prebuilt) by editting PNG_API_RULE to 2 (to force use\r
+$# (scripts\pnglibconf.h.prebuilt) by editing PNG_API_RULE to 2 (to force use\r
 $# of the OpenWatcom library calling convention.)\r
 $#\r
 <<\r
index 34565e4..4e1c8fa 100644 (file)
@@ -12,7 +12,7 @@ Assumptions:
 * The libpng source files are in ..\..
 * The zlib source files are in ..\..\..\zlib
 * The zlib project file is in . /* Warning: This is until the zlib project
-  files get intergrated into the next zlib release. The final zlib project
+  files get integrated into the next zlib release. The final zlib project
   directory will then be ..\..\..\zlib\projects\visualc71. */
 
 To use:
index 642a42b..e28ec95 100644 (file)
@@ -1,76 +1,77 @@
+Instructions for building libpng using Microsoft Visual Studio
+==============================================================
 
-VisualStudio instructions
-
-libpng version 1.6.21 - January 15, 2016
-
+Copyright (c) 2018 Cosmin Truta
 Copyright (c) 2010,2013,2015 Glenn Randers-Pehrson
 
 This code is released under the libpng license.
-For conditions of distribution and use, see the disclaimer
-and license in png.h
+For conditions of distribution and use, see the disclaimer and license
+in png.h
 
-This directory  contains support for building libpng under MicroSoft
-VisualStudio 2010.  It may also work under later versions of VisualStudio.
-You should be familiar with VisualStudio before using this directory.
+This directory contains a solution for building libpng under Microsoft
+Visual Studio 2010.  It may also work under later versions of Visual
+Studio.  You should be familiar with Visual Studio before using this
+solution.
 
 Initial preparations
-====================
-You must enter some information in zlib.props before attempting to build
-with this 'solution'.  Please read and edit zlib.props first.  You will
-probably not be familiar with the contents of zlib.props - do not worry,
-it is mostly harmless.
+--------------------
+You must enter some information in zlib.props before attempting to
+build with this 'solution'.  Please read and edit zlib.props first.
+You will probably not be familiar with the contents of zlib.props -
+do not worry, it is mostly harmless.
 
 This is all you need to do to build the 'release' and 'release library'
 configurations.
 
 Debugging
-=========
+---------
 The release configurations default to /Ox optimization.  Full debugging
-information is produced (in the .pdb), but if you encounter a problem the
-optimization may make it difficult to debug.  Simply rebuild with a lower
-optimization level (e.g. /Od.)
+information is produced (in the .pdb), but if you encounter a problem
+the optimization may make it difficult to debug.  Simply rebuild with a
+lower optimization level (e.g. /Od.)
 
 Linking your application
-========================
-Normally you should link against the 'release' configuration.  This builds a
-DLL for libpng with the default runtime options used by Visual Studio 2010.
-In particular the runtime library is the "MultiThreaded DLL" version.
-If you use Visual Studio defaults to build your application you will have no
-problems.
-
-If you don't use the Visual Studio defaults your application must still be
-built with the default runtime option (/MD).  If, for some reason, it is not
-then your application will crash inside libpng16.dll as soon as libpng
-tries to read from a file handle you pass in.
-
-If you do not want to use the DLL, for example for a very small application,
-the 'release library' configuration may be more appropriate.  This is built
-with a non-standard runtime library - the "MultiThreaded" version.  When you
-build your application it must be compiled with this option (/MT), otherwise
-it will not build (if you are lucky) or crash (if you are not.) See the
-WARNING file that is distributed along with this readme.txt.
+------------------------
+Normally you should link against the 'release' configuration.  This
+builds a DLL for libpng with the default runtime options used by Visual
+Studio.  In particular the runtime library is the "MultiThreaded DLL"
+version.  If you use Visual Studio defaults to build your application,
+you should have no problems.
+
+If you don't use the Visual Studio defaults your application must still
+be built with the default runtime option (/MD).  If, for some reason,
+it is not then your application will crash inside libpng16.dll as soon
+as libpng tries to read from a file handle you pass in.
+
+If you do not want to use the DLL, and prefer static linking instead,
+you may choose the 'release library' configuration.  This is built with
+a non-standard runtime library - the "MultiThreaded" version.  When you
+build your application, it must be compiled with this option (/MT),
+otherwise it will not build (if you are lucky) or it will crash (if you
+are not.) See the WARNING file that is distributed with this README.
 
 Stop reading here
-=================
+-----------------
 You have enough information to build a working application.
 
 Debug versions have limited support
-===================================
-This solution includes limited support for debug versions of libpng.  You
-do not need these unless your own solution itself uses debug builds (it is
-far more effective to debug on the release builds, there is no point building
-a special debug build unless you have heap corruption problems that you can't
-track down.)
+-----------------------------------
+This solution includes limited support for debug versions of libpng.
+You do not need these unless your own solution itself uses debug builds
+(it is far more effective to debug on the release builds, there is no
+point building a special debug build unless you have heap corruption
+problems that you can't track down.)
 
-The debug build of libpng is minimally supported.  Support for debug builds of
-zlib is also minimal.  You really don't want to do this.
+The debug build of libpng is minimally supported.  Support for debug
+builds of zlib is also minimal.  Please keep this in mind, if you want
+to use it.
 
 WARNING
-=======
-Libpng 1.6.x does not use the default run-time library when building static
-library builds of libpng; instead of the shared DLL runtime it uses a static
-runtime.  If you need to change this make sure to change the setting on all the
-relevant projects:
+-------
+Libpng 1.6.x does not use the default run-time library when building
+static library builds of libpng; instead of the shared DLL runtime, it
+uses a static runtime.  If you need to change this, make sure to change
+the setting on all the relevant projects:
 
     libpng
     zlib
@@ -82,14 +83,5 @@ The runtime library settings for each build are as follows:
     DLL         /MD            /MDd
     Library     /MT            /MTd
 
-NOTICE that libpng 1.5.x erroneously used /MD for Debug DLL builds; if you used
-the debug builds in your app and you changed your app to use /MD you will need
-to change it back to /MDd for libpng 1.6.0 and later.
-
-The Visual Studio 2010 defaults for a Win32 DLL or Static Library project are
-as follows:
-
-                     Release     Debug
-    DLL               /MD         /MDd
-    Static Library    /MD         /MDd
-
+Also, be sure to build libpng, zlib, and your project, all for the same
+platform (e.g., 32-bit or 64-bit).
index de7fc3c..9bfb718 100644 (file)
@@ -84,7 +84,7 @@
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -97,9 +97,9 @@
       <BrowseInformation>true</BrowseInformation>
       <CompileAs>CompileAsC</CompileAs>
       <StringPooling>true</StringPooling>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <Optimization>Disabled</Optimization>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
     </ClCompile>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
     <ClCompile>
       <PrecompiledHeader>Use</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <BrowseInformation>true</BrowseInformation>
       <CompileAs>CompileAsC</CompileAs>
       <StringPooling>true</StringPooling>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
     </ClCompile>
     <Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>Use</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <CompileAs>CompileAsC</CompileAs>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <Optimization>Full</Optimization>
     </ClCompile>
     <Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>Use</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <CompileAs>CompileAsC</CompileAs>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <Optimization>Full</Optimization>
       <WholeProgramOptimization>true</WholeProgramOptimization>
     </ClCompile>
index e2a232c..efcc440 100644 (file)
@@ -30,7 +30,7 @@
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <Optimization>MaxSpeed</Optimization>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
index 0d2980d..21810e3 100644 (file)
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
index bf9266f..f1df07d 100644 (file)
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
index a30cc7a..409d662 100644 (file)
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
index 07cf241..c117d29 100644 (file)
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <MinimalRebuild>false</MinimalRebuild>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>false</FunctionLevelLinking>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;PNG_USE_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
     <ClCompile>
-      <WarningLevel>Level4</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ZLibSrcDir);..\..\..\scripts;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996;4127</DisableSpecificWarnings>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings)</DisableSpecificWarnings>
       <CompileAsManaged>false</CompileAsManaged>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <StringPooling>true</StringPooling>
       <MinimalRebuild>false</MinimalRebuild>
       <BrowseInformation>true</BrowseInformation>
index f06f8a0..8786279 100644 (file)
@@ -2,16 +2,15 @@
 <!--
  * zlib.props - location of zlib source
  *
- * libpng version 1.6.21 - January 15, 2016
- *
+ * Copyright (c) 2018 Cosmin Truta
  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
 
- * You must edit this file to record the location of the zlib
- * source code.
+ * You may need to edit this file in order to update the location
+ * of the zlib source code.
  -->
 
 <Project ToolsVersion="4.0"
@@ -32,7 +31,7 @@
         versions do not match.  The zlib version used in this build is recorded
         below:
      -->
-    <ZLibSrcDir>..\..\..\..\zlib-1.2.8</ZLibSrcDir>
+    <ZLibSrcDir>..\..\..\..\zlib</ZLibSrcDir>
 
     <!-- The following line allows compilation for an ARM target with Visual
          Studio 2012.  Notice that this is not supported by the Visual Studio
          test it:
      -->
     <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
+
+    <!-- The following lines provide a global (solution level) control of the
+         warnings issued by the compiler, these are used in the individual
+         project files (*/*.vcxproj) with, for zlib, some extra disables.
+
+         Different versions of Visual Studio may require different settings,
+         these settings work with Visual Studio 2013.  Just set
+         TreatWarningAsError to false to check the build without failing on
+         errors.
+     -->
+   <WarningLevel>EnableAllWarnings</WarningLevel>
+   <TreatWarningAsError>true</TreatWarningAsError>
+   <DisableSpecificWarnings>4255;4668;4710;4711;4746;4820;4996</DisableSpecificWarnings>
   </PropertyGroup>
 </Project>
index 6e5b94a..0df16db 100644 (file)
     <ClCompile>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <WarningLevel>TurnOffAllWarnings</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <BrowseInformation>true</BrowseInformation>
       <FunctionLevelLinking>true</FunctionLevelLinking>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings);4127;4131;4242;4244</DisableSpecificWarnings>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
     </ClCompile>
     <Link>
       <TargetMachine>MachineX86</TargetMachine>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <WarningLevel>TurnOffAllWarnings</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Disabled</Optimization>
       <BrowseInformation>true</BrowseInformation>
       <FunctionLevelLinking>true</FunctionLevelLinking>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings);4127;4131;4242;4244</DisableSpecificWarnings>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
     </ClCompile>
     <Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
     <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <BufferSecurityCheck>false</BufferSecurityCheck>
       <BrowseInformation>true</BrowseInformation>
       <FunctionLevelLinking>true</FunctionLevelLinking>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings);4127;4131;4242;4244</DisableSpecificWarnings>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
+      <WarningLevel>$(WarningLevel)</WarningLevel>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <Optimization>Full</Optimization>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <BufferSecurityCheck>false</BufferSecurityCheck>
       <BrowseInformation>true</BrowseInformation>
       <FunctionLevelLinking>true</FunctionLevelLinking>
-      <TreatWarningAsError>true</TreatWarningAsError>
+      <DisableSpecificWarnings>$(DisableSpecificWarnings);4127;4131;4242;4244</DisableSpecificWarnings>
+      <TreatWarningAsError>$(TreatWarningAsError)</TreatWarningAsError>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;Z_SOLO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <Link>
index 25951aa..3d911ef 100644 (file)
@@ -1,22 +1,20 @@
 
-Makefiles for  libpng version 1.6.21 - January 15, 2016
+Makefiles for libpng
 
-pnglibconf.h.prebuilt       =>  Stores configuration settings
+pnglibconf.h.prebuilt  =>  Configuration settings
  makefile.linux    =>  Linux/ELF makefile
-                       (gcc, creates libpng16.so.16.1.6.21)
+                       (gcc, creates shared libpng16.so.16.1.6.*)
+ makefile.linux-opt=>  Linux/ELF makefile with hardware optimizations on
+                       (gcc, creates shared libpng16.so.16.1.6.*)
  makefile.gcc      =>  Generic makefile (gcc, creates static libpng.a)
- makefile.knr      =>  Archaic UNIX Makefile that converts files with
-                       ansi2knr (Requires ansi2knr.c from
-                       ftp://ftp.cs.wisc.edu/ghost)
  makefile.acorn    =>  Acorn makefile
  makefile.aix      =>  AIX/gcc makefile
  makefile.amiga    =>  Amiga makefile
  makefile.atari    =>  Atari makefile
  makefile.bc32     =>  32-bit Borland C++ (all modules compiled in C mode)
- makefile.beos     =>  beos makefile
- makefile.bor      =>  Borland makefile (uses bcc)
+ makefile.beos     =>  BeOS makefile
  makefile.cegcc    =>  minge32ce for Windows CE makefile
- makefile.darwin   =>  Darwin makefile, can use on MacosX
+ makefile.darwin   =>  Darwin makefile, for macOS (formerly Mac OS X)
  makefile.dec      =>  DEC Alpha UNIX makefile
  makefile.dj2      =>  DJGPP 2 makefile
  makefile.freebsd  =>  FreeBSD makefile
@@ -27,23 +25,20 @@ pnglibconf.h.prebuilt       =>  Stores configuration settings
  makefile.ibmc     =>  IBM C/C++ version 3.x for Win32 and OS/2 (static)
  makefile.intel    =>  Intel C/C++ version 4.0 and later
  makefile.mips     =>  MIPS makefile
- makefile.msc      =>  Microsoft C makefile
- makefile.netbsd   =>  NetBSD/cc makefile, makes libpng.so.
+ makefile.netbsd   =>  NetBSD/cc makefile, makes shared libpng.so
  makefile.openbsd  =>  OpenBSD makefile
- makefile.os2      =>  OS/2 Makefile (gcc and emx, requires libpng.def)
- makefile.sco      =>  For SCO OSr5  ELF and Unixware 7 with Native cc
- makefile.sggcc    =>  Silicon Graphics (gcc,
-                       creates libpng16.so.16.1.6.21)
+ makefile.sco      =>  SCO OSr5 ELF and Unixware 7 with Native cc
+ makefile.sggcc    =>  Silicon Graphics makefile
+                       (gcc, creates shared libpng16.so.16.1.6.*)
  makefile.sgi      =>  Silicon Graphics IRIX makefile (cc, creates static lib)
- makefile.solaris  =>  Solaris 2.X makefile (gcc,
-                       creates libpng16.so.16.1.6.21)
- makefile.so9      =>  Solaris 9 makefile (gcc,
-                       creates libpng16.so.16.1.6.21)
+ makefile.solaris  =>  Solaris 2.X makefile
+                       (gcc, creates shared libpng16.so.16.1.6.*)
+ makefile.so9      =>  Solaris 9 makefile
+                       (gcc, creates shared libpng16.so.16.1.6.*)
  makefile.std      =>  Generic UNIX makefile (cc, creates static libpng.a)
  makefile.sunos    =>  Sun makefile
  makefile.32sunu   =>  Sun Ultra 32-bit makefile
  makefile.64sunu   =>  Sun Ultra 64-bit makefile
- makefile.tc3      =>  Turbo C 3.0 makefile
  makefile.vcwin32  =>  makefile for Microsoft Visual C++ 4.0 and later
  makevms.com       =>  VMS build script
  smakefile.ppc     =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
@@ -55,20 +50,20 @@ Other supporting scripts:
  libpng-config-body.in => used by several makefiles to create libpng-config
  libpng-config-head.in => used by several makefiles to create libpng-config
  libpng.pc.in      =>  Used by several makefiles to create libpng.pc
- pngwin.rc         =>  Used by the visualc71 project.
+ pngwin.rc         =>  Used by the visualc71 project
  pngwin.def        =>  Used by makefile.os2
  pngwin.dfn        =>  Used to maintain pngwin.def
  SCOPTIONS.ppc     =>  Used with smakefile.ppc
 
- checksym.awk       =>  Used for maintaining pnglibconf.h
- def.dfn            =>  Used for maintaining pnglibconf.h
- options.awk        =>  Used for maintaining pnglibconf.h
- pnglibconf.dfa     =>  Used for maintaining pnglibconf.h
- pnglibconf.mak     =>  Used for maintaining pnglibconf.h
- sym.dfn            =>  Used for symbol versioning
- symbols.def        =>  Used for symbol versioning
- symbols.dfn        =>  Used for symbol versioning
- vers.dfn           =>  Used for symbol versioning
+ checksym.awk      =>  Used for maintaining pnglibconf.h
+ def.dfn           =>  Used for maintaining pnglibconf.h
+ options.awk       =>  Used for maintaining pnglibconf.h
+ pnglibconf.dfa    =>  Used for maintaining pnglibconf.h
+ pnglibconf.mak    =>  Used for maintaining pnglibconf.h
+ sym.dfn           =>  Used for symbol versioning
+ symbols.def       =>  Used for symbol versioning
+ symbols.dfn       =>  Used for symbol versioning
+ vers.dfn          =>  Used for symbol versioning
 
  libtool.m4        =>  Used by autoconf tools
  ltoptions.m4      =>  Used by autoconf tools
diff --git a/scripts/def.c b/scripts/def.c
deleted file mode 100644 (file)
index d7e21a1..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* def.c - define format of libpng.def
- *
- * Last changed in libpng version 1.6.16 [December 22, 2014]
- * Copyright (c) 2011-2014 Glenn Randers-Pehrson
- *
- * This code is released under the libpng license.
- * For conditions of distribution and use, see the disclaimer
- * and license in png.h
- */
-
-/* Write the export file header: */
-PNG_DFN ";--------------------------------------------------------------"
-PNG_DFN "; LIBPNG module definition file for OS/2"
-PNG_DFN ";--------------------------------------------------------------"
-PNG_DFN ""
-PNG_DFN "; If you give the library an explicit name one or other files"
-PNG_DFN "; may need modifying to support the new name on one or more"
-PNG_DFN "; systems."
-PNG_DFN "LIBRARY"
-PNG_DFN "OS2 DESCRIPTION "PNG image compression library""
-PNG_DFN "OS2 CODE PRELOAD MOVEABLE DISCARDABLE"
-PNG_DFN ""
-PNG_DFN "EXPORTS"
-PNG_DFN ";Version 1.6.21"
-
-#define PNG_EXPORTA(ordinal, type, name, args, attributes)\
-        PNG_DFN "@" SYMBOL_PREFIX "@@" name "@"
-
-#include "../png.h"
index 463c425..a3aefbf 100644 (file)
@@ -16,10 +16,10 @@ OBJS = png.obj, pngset.obj, pngget.obj, pngrutil.obj, pngtrans.obj,\
 CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
 
 all : pngtest.exe libpng.olb
-               @ write sys$output " pngtest available"
+       @ write sys$output " pngtest available"
 
 libpng.olb : libpng.olb($(OBJS))
-       @ write sys$output " Libpng available"
+       @ write sys$output " libpng available"
 
 
 pngtest.exe : pngtest.obj libpng.olb
diff --git a/scripts/genchk.cmake.in b/scripts/genchk.cmake.in
new file mode 100644 (file)
index 0000000..ab3b9d7
--- /dev/null
@@ -0,0 +1,37 @@
+# genchk.cmake.in
+# Generate .chk from .out with awk (generic), based upon the automake logic.
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Variables substituted from CMakeLists.txt
+set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
+set(AWK "@AWK@")
+
+get_filename_component(INPUTEXT "${INPUT}" EXT)
+get_filename_component(OUTPUTEXT "${OUTPUT}" EXT)
+get_filename_component(INPUTBASE "${INPUT}" NAME_WE)
+get_filename_component(OUTPUTBASE "${OUTPUT}" NAME_WE)
+get_filename_component(INPUTDIR "${INPUT}" PATH)
+get_filename_component(OUTPUTDIR "${OUTPUT}" PATH)
+
+if("${INPUTEXT}" STREQUAL ".out" AND "${OUTPUTEXT}" STREQUAL ".chk")
+  # Generate .chk from .out with awk (generic)
+  file(REMOVE "${OUTPUT}" "${OUTPUTDIR}/${OUTPUTBASE}.new")
+  execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/checksym.awk"
+                          "${SRCDIR}/scripts/${INPUTBASE}.def"
+                          "of=${OUTPUTDIR}/${OUTPUTBASE}.new"
+                          "${INPUT}"
+                  RESULT_VARIABLE AWK_FAIL)
+  if(AWK_FAIL)
+    message(FATAL_ERROR "Failed to generate ${OUTPUTDIR}/${OUTPUTBASE}.new")
+  endif()
+  file(RENAME "${OUTPUTDIR}/${OUTPUTBASE}.new" "${OUTPUT}")
+else()
+  message(FATAL_ERROR "Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}")
+endif()
diff --git a/scripts/genout.cmake.in b/scripts/genout.cmake.in
new file mode 100644 (file)
index 0000000..01f12de
--- /dev/null
@@ -0,0 +1,93 @@
+# genout.cmake.in
+# Generate .out from .c with awk (generic), based upon the automake logic.
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Variables substituted from CMakeLists.txt
+set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@")
+set(BINDIR "@CMAKE_CURRENT_BINARY_DIR@")
+
+set(AWK "@AWK@")
+set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
+set(CMAKE_C_FLAGS @CMAKE_C_FLAGS@)
+set(INCDIR "@CMAKE_CURRENT_BINARY_DIR@")
+set(PNG_PREFIX "@PNG_PREFIX@")
+set(PNGLIB_MAJOR "@PNGLIB_MAJOR@")
+set(PNGLIB_MINOR "@PNGLIB_MINOR@")
+set(PNGLIB_VERSION "@PNGLIB_VERSION@")
+set(ZLIBINCDIR "@ZLIB_INCLUDE_DIR@")
+
+set(PLATFORM_C_FLAGS)
+if(APPLE)
+  set(CMAKE_OSX_ARCHITECTURES "@CMAKE_OSX_ARCHITECTURES@")
+  set(CMAKE_OSX_SYSROOT "@CMAKE_OSX_SYSROOT@")
+  if(CMAKE_OSX_ARCHITECTURES)
+    set(PLATFORM_C_FLAGS ${PLATFORM_C_FLAGS} -arch ${CMAKE_OSX_ARCHITECTURES})
+  endif()
+  if(CMAKE_OSX_SYSROOT)
+    set(PLATFORM_C_FLAGS ${PLATFORM_C_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT})
+  endif()
+endif()
+
+get_filename_component(INPUTEXT "${INPUT}" EXT)
+get_filename_component(OUTPUTEXT "${OUTPUT}" EXT)
+get_filename_component(INPUTBASE "${INPUT}" NAME_WE)
+get_filename_component(OUTPUTBASE "${OUTPUT}" NAME_WE)
+get_filename_component(INPUTDIR "${INPUT}" PATH)
+get_filename_component(OUTPUTDIR "${OUTPUT}" PATH)
+
+if ("${INPUTEXT}" STREQUAL ".c" AND "${OUTPUTEXT}" STREQUAL ".out")
+  get_filename_component(GENDIR "${OUTPUT}" PATH)
+  file(MAKE_DIRECTORY "${GENDIR}")
+
+  file(REMOVE "${OUTPUT}.tf1" "${OUTPUT}.tf2")
+
+  set(INCLUDES "-I${INCDIR}")
+  if(ZLIBINCDIR)
+    foreach(dir ${ZLIBINCDIR})
+      list(APPEND INCLUDES "-I${dir}")
+    endforeach()
+  endif()
+
+  if(PNG_PREFIX)
+    set(PNG_PREFIX_DEF "-DPNG_PREFIX=${PNG_PREFIX}")
+  endif()
+
+  execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E"
+                          ${CMAKE_C_FLAGS}
+                          ${PLATFORM_C_FLAGS}
+                          "-I${SRCDIR}"
+                          "-I${BINDIR}"
+                          ${INCLUDES}
+                          "-DPNGLIB_LIBNAME=PNG${PNGLIB_MAJOR}${PNGLIB_MINOR}_0"
+                          "-DPNGLIB_VERSION=${PNGLIB_VERSION}"
+                          "-DSYMBOL_PREFIX=${SYMBOL_PREFIX}"
+                          "-DPNG_NO_USE_READ_MACROS"
+                          "-DPNG_BUILDING_SYMBOL_TABLE"
+                          ${PNG_PREFIX_DEF}
+                          "${INPUT}"
+                  OUTPUT_FILE "${OUTPUT}.tf1"
+                  WORKING_DIRECTORY "${BINDIR}"
+                  RESULT_VARIABLE CPP_FAIL)
+  if(CPP_FAIL)
+    message(FATAL_ERROR "Failed to generate ${OUTPUT}.tf1")
+  endif()
+
+  execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/dfn.awk"
+                          "out=${OUTPUT}.tf2" "${OUTPUT}.tf1"
+                  WORKING_DIRECTORY "${BINDIR}"
+                  RESULT_VARIABLE AWK_FAIL)
+  if(AWK_FAIL)
+    message(FATAL_ERROR "Failed to generate ${OUTPUT}.tf2")
+  endif()
+
+  file(REMOVE "${OUTPUT}.tf1")
+  file(RENAME "${OUTPUT}.tf2" "${OUTPUT}")
+else()
+  message(FATAL_ERROR "Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}")
+endif()
diff --git a/scripts/gensrc.cmake.in b/scripts/gensrc.cmake.in
new file mode 100644 (file)
index 0000000..f28a622
--- /dev/null
@@ -0,0 +1,138 @@
+# gensrc.cmake.in
+# Generate source files with awk, based upon the automake logic.
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Variables substituted from CMakeLists.txt
+set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@")
+set(BINDIR "@CMAKE_CURRENT_BINARY_DIR@")
+
+set(AWK "@AWK@")
+set(DFA_XTRA "@DFA_XTRA@")
+set(PNG_PREFIX "@PNG_PREFIX@")
+set(PNGLIB_VERSION "@PNGLIB_VERSION@")
+
+if("${OUTPUT}" STREQUAL "scripts/pnglibconf.c")
+  # Generate scripts/pnglibconf.c
+
+  file(REMOVE "${BINDIR}/pnglibconf.tf6" "${BINDIR}/pnglibconf.tf7")
+
+  execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "com ${PNGLIB_VERSION} STANDARD API DEFINITION"
+                  COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+                          "out=pnglibconf.tf6" "logunsupported=1" "version=search"
+                          "${SRCDIR}/pngconf.h" "-"
+                          "${SRCDIR}/scripts/pnglibconf.dfa"
+                  WORKING_DIRECTORY "${BINDIR}"
+                  RESULT_VARIABLE AWK_FAIL)
+  if(AWK_FAIL)
+    message(FATAL_ERROR "Failed to generate pnglibconf.tf6")
+  endif()
+
+  execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+                  "out=pnglibconf.tf7" "pnglibconf.tf6"
+                  WORKING_DIRECTORY "${BINDIR}"
+                  RESULT_VARIABLE AWK_FAIL)
+  if(AWK_FAIL)
+    message(FATAL_ERROR "Failed to generate pnglibconf.tf7")
+  endif()
+
+  file(REMOVE "pnglibconf.tf6")
+  file(MAKE_DIRECTORY "${BINDIR}/scripts")
+  file(RENAME "pnglibconf.tf7" "${BINDIR}/scripts/pnglibconf.c")
+
+elseif ("${OUTPUT}" STREQUAL "pnglibconf.c")
+  # Generate pnglibconf.c
+
+  file(REMOVE "${BINDIR}/pnglibconf.tf4" "${BINDIR}/pnglibconf.tf5")
+
+  execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+                  out=pnglibconf.tf4 version=search
+                  ${SRCDIR}/pngconf.h ${SRCDIR}/scripts/pnglibconf.dfa
+                  ${SRCDIR}/pngusr.dfa ${DFA_XTRA}
+                  WORKING_DIRECTORY "${BINDIR}"
+                  RESULT_VARIABLE AWK_FAIL)
+  if(AWK_FAIL)
+    message(FATAL_ERROR "Failed to generate pnglibconf.tf4")
+  endif()
+
+  execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+                  out=pnglibconf.tf5 pnglibconf.tf4
+                  WORKING_DIRECTORY "${BINDIR}"
+                  RESULT_VARIABLE AWK_FAIL)
+  if(AWK_FAIL)
+    message(FATAL_ERROR "Failed to generate pnglibconf.tf5")
+  endif()
+
+  file(REMOVE "pnglibconf.tf4")
+  file(MAKE_DIRECTORY "${BINDIR}/scripts")
+  file(RENAME "pnglibconf.tf5" "${BINDIR}/pnglibconf.c")
+
+elseif ("${OUTPUT}" STREQUAL "pnglibconf.h")
+  # Generate pnglibconf.h
+
+  file(REMOVE "${BINDIR}/${OUTPUT}")
+  if(PNG_PREFIX)
+    file(REMOVE "pnglibconf.tf8")
+
+    execute_process(COMMAND "${AWK}" "s==0 && NR>1{print prev}
+                             s==0{prev=\$0}
+                             s==1{print \"#define\", \$1, \"${PNG_PREFIX}\" \$1}
+                             s==2{print \"#define ${PNG_PREFIX}png_\" \$1, \"PNG_\" \$1}
+                             END{print prev}" s=0 pnglibconf.out s=1 "${BINDIR}/scripts/prefix.out"
+                             s=2 "${SRCDIR}/scripts/macro.lst"
+                    OUTPUT_FILE pnglibconf.tf8
+                    RESULT_VARIABLE AWK_FAIL)
+    if(AWK_FAIL)
+      message(FATAL_ERROR "Failed to generate pnglibconf.tf8")
+    endif()
+
+    file(RENAME "pnglibconf.tf8" "${BINDIR}/${OUTPUT}")
+  else()
+    execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${BINDIR}/pnglibconf.out"
+                                                       "${BINDIR}/${OUTPUT}"
+                    RESULT_VARIABLE COPY_FAIL)
+    if(COPY_FAIL)
+      message(FATAL_ERROR "Failed to create pnglibconf.h")
+    endif()
+  endif()
+
+elseif ("${OUTPUT}" STREQUAL "pngprefix.h")
+  # Generate pngprefix.h
+
+  file(REMOVE "${BINDIR}/${OUTPUT}")
+
+  if(PNG_PREFIX)
+    file(REMOVE "pngprefix.tf1")
+
+    execute_process(COMMAND "${AWK}"
+                            "{print \"#define\", \$1, \"${PNG_PREFIX}\" \$1}"
+                            "${BINDIR}/scripts/intprefix.out"
+                    OUTPUT_FILE "pngprefix.tf1"
+                    RESULT_VARIABLE AWK_FAIL)
+    if(AWK_FAIL)
+      message(FATAL_ERROR "Failed to generate pngprefix.tf1")
+    endif()
+
+    file(RENAME "pngprefix.tf1" "${BINDIR}/${OUTPUT}")
+  else()
+    file(WRITE "${BINDIR}/${OUTPUT}" "/* No libpng symbol prefix configured. */")
+  endif()
+
+elseif("${OUTPUT}" STREQUAL "scripts/pnglibconf.h.prebuilt")
+  # Generate scripts/pnglibconf.h.prebuilt (fails build)
+
+  message(STATUS "Attempting to build scripts/pnglibconf.h.prebuilt")
+  message(STATUS "This is a machine generated file, but if you want to make")
+  message(STATUS "a new one simply build the 'genfiles' target, and copy")
+  message(STATUS "scripts/pnglibconf.out to scripts/pnglibconf.h.prebuilt")
+  message(STATUS "AND set PNG_ZLIB_VERNUM to 0 (you MUST do this)")
+  message(FATAL_ERROR "Stopping build")
+
+else()
+  message(FATAL_ERROR "Unsupported output: ${OUTPUT}")
+endif()
index 0c3dd74..985271a 100644 (file)
@@ -11,7 +11,7 @@
 
 # Modeled after libxml-config.
 
-version=1.6.21
+version=1.6.36
 prefix=""
 libdir=""
 libs=""
index b97114c..2f74923 100644 (file)
@@ -5,6 +5,6 @@ includedir=@includedir@/libpng16
 
 Name: libpng
 Description: Loads and saves PNG files
-Version: 1.6.21
+Version: 1.6.36
 Libs: -L${libdir} -lpng16
 Cflags: -I${includedir}
index 7d4b7c5..c849ecd 100644 (file)
@@ -219,7 +219,7 @@ clean:
        libpng-config $(LIBSO) $(LIBSOMAJ)* \
        libpng.pc
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index 341fce9..8880fa9 100644 (file)
@@ -219,7 +219,7 @@ clean:
        libpng-config $(LIBSO) $(LIBSOMAJ)* \
        libpng.pc
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
diff --git a/scripts/makefile.bor b/scripts/makefile.bor
deleted file mode 100644 (file)
index 6693772..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-# Makefile for libpng
-# 16-bit Borland C++ (Note: All modules are compiled in C mode)
-# To build the library, do:
-#       "make -fmakefile.bor -DMODEL=c"
-# or:   "make -fmakefile.bor -DMODEL=l"
-#
-# ------------ Borland C++ ------------
-
-### Absolutely necessary for this makefile to work
-.AUTODEPEND
-
-## Where zlib.h, zconf.h and zlib_MODEL.lib are
-ZLIB_DIR=..\zlib
-
-## Compiler, linker, librarian and other tools
-CC=bcc
-LD=bcc
-LIB=tlib
-CP=copy
-
-!ifndef MODEL
-MODEL=l
-!endif
-
-MODEL_ARG=-m$(MODEL)
-
-#TARGET_CPU=3
-# 2 = 286, 3 = 386, etc.
-!ifndef TARGET_CPU
-TARGET_CPU=2
-!endif
-
-# Use this if you don't want Borland's fancy exception handling
-# (for Borland C++ 4.0 or later)
-#NOEHLIB=noeh$(MODEL).lib
-
-!ifdef DEBUG
-CDEBUG=-v
-LDEBUG=-v
-!else
-CDEBUG=
-LDEBUG=
-!endif
-
-# STACKOFLOW=1
-!ifdef STACKOFLOW
-CDEBUG=$(CDEBUG) -N
-LDEBUG=$(LDEBUG) -N
-!endif
-
-# -X- turn on dependency generation in the object file
-# -w  set all warnings on
-# -O2 optimize for speed
-# -Z  global optimization
-CPPFLAGS=-I$(ZLIB_DIR)
-CFLAGS=-O2 -Z -X- -w -$(TARGET_CPU) $(MODEL_ARG) $(CDEBUG)
-
-# -M  generate map file
-LDFLAGS=-M -L$(ZLIB_DIR) $(MODEL_ARG) $(LDEBUG)
-
-# Pre-built configuration
-# See scripts\pnglibconf.mak for more options
-!ifndef PNGLIBCONF_H_PREBUILT
-PNGLIBCONF_H_PREBUILT = scripts\pnglibconf.h.prebuilt
-!endif
-
-## Variables
-
-OBJS = \
-       png.obj \
-       pngerror.obj \
-       pngget.obj \
-       pngmem.obj \
-       pngpread.obj \
-       pngread.obj \
-       pngrio.obj \
-       pngrtran.obj \
-       pngrutil.obj \
-       pngset.obj \
-       pngtrans.obj \
-       pngwio.obj \
-       pngwrite.obj \
-       pngwtran.obj \
-       pngwutil.obj
-
-LIBOBJS = \
-       +png.obj \
-       +pngerror.obj \
-       +pngget.obj \
-       +pngmem.obj \
-       +pngpread.obj \
-       +pngread.obj \
-       +pngrio.obj \
-       +pngrtran.obj \
-       +pngrutil.obj \
-       +pngset.obj \
-       +pngtrans.obj \
-       +pngwio.obj \
-       +pngwrite.obj \
-       +pngwtran.obj \
-       +pngwutil.obj
-
-LIBNAME=libpng$(MODEL).lib
-
-## Implicit rules
-
-# Braces let make "batch" calls to the compiler,
-# 2 calls instead of 12; space is important.
-.c.obj:
-       $(CC) $(CPPFLAGS) $(CFLAGS) -c {$*.c }
-
-.c.exe:
-       $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $*.c \
-         $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB)
-
-## Major targets
-
-all: libpng pngtest
-
-# try !include scripts\pnglibconf.mak for more options
-pnglibconf.h: $(PNGLIBCONF_H_PREBUILT)
-       $(CP) $(PNGLIBCONF_H_PREBUILT) $@
-
-libpng: $(LIBNAME)
-
-pngtest: pngtest$(MODEL).exe
-
-test: pngtest$(MODEL).exe
-       pngtest$(MODEL)
-
-## Minor Targets
-
-png.obj: png.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngerror.obj: pngerror.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngget.obj: pngget.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngmem.obj: pngmem.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngpread.obj: pngpread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngread.obj: pngread.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngrio.obj: pngrio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngrtran.obj: pngrtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngrutil.obj: pngrutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngset.obj: pngset.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngtrans.obj: pngtrans.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwio.obj: pngwio.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwrite.obj: pngwrite.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwtran.obj: pngwtran.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwutil.obj: pngwutil.c png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-
-$(LIBNAME): $(OBJS)
-       -del $(LIBNAME)
-       $(LIB) $(LIBNAME) @&&|
-$(LIBOBJS), libpng$(MODEL)
-|
-
-pngtest$(MODEL).obj: pngtest.c png.h pngconf.h pnglibconf.h
-       $(CC) $(CFLAGS) -opngtest$(MODEL) -c pngtest.c
-
-pngtest$(MODEL).exe: pngtest$(MODEL).obj
-       $(LD) $(LDFLAGS) pngtest$(MODEL).obj $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB)
-
-# Clean up anything else you want
-clean:
-       -del pnglibconf.h
-       -del *.obj
-       -del *.exe
-       -del *.lib
-       -del *.lst
-       -del *.map
-
-# End of makefile for libpng
index 3d9545e..60fb113 100644 (file)
@@ -23,7 +23,7 @@
 
 VERMAJ = 1
 VERMIN = 6
-VERMIC = 21
+VERMIC = 36
 VER = $(VERMAJ).$(VERMIN).$(VERMIC)
 NAME = libpng
 PACKAGE = $(NAME)-$(VER)
index be3f92c..33c27cc 100644 (file)
@@ -200,7 +200,7 @@ clean:
        $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \
        libpng.pc $(LIBNAME).*dylib pngtesti pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index cad1a5a..5fec61e 100644 (file)
@@ -62,7 +62,7 @@ test: pngtest
 pnglibconf.h: $(PNGLIBCONF_H_PREBUILT)
        cp $(PNGLIBCONF_H_PREBUILT) $@
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index 5948be8..4421e78 100644 (file)
@@ -1,7 +1,7 @@
 # makefile for libpng, HPUX (10.20 and 11.00) using the ANSI/C product.
 # Copyright (C) 1999-2002, 2006, 2009, 2010-2014 Glenn Randers-Pehrson
 # Copyright (C) 1995 Guy Eric Schalnat, Group 42
-# contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard
+# Contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard
 #
 # This code is released under the libpng license.
 # For conditions of distribution and use, see the disclaimer
@@ -206,7 +206,7 @@ clean:
        libpng-config $(LIBSO) $(LIBSOMAJ)* \
        libpng.pc pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index 5c8791b..efef1f3 100644 (file)
@@ -209,7 +209,7 @@ clean:
        libpng-config $(LIBSO) $(LIBSOMAJ)* \
        libpng.pc pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index b07612d..27b312a 100644 (file)
@@ -1,7 +1,7 @@
 # makefile for libpng, HPUX (10.20 and 11.00) using the ANSI/C product.
 # Copyright (C) 1999-2002, 2006, 2010-2014 Glenn Randers-Pehrson
 # Copyright (C) 1995 Guy Eric Schalnat, Group 42
-# contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard
+# Contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard
 #
 # This code is released under the libpng license.
 # For conditions of distribution and use, see the disclaimer
@@ -204,7 +204,7 @@ clean:
        libpng-config $(LIBSO) $(LIBSOMAJ)* \
        libpng.pc pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
diff --git a/scripts/makefile.knr b/scripts/makefile.knr
deleted file mode 100644 (file)
index d8de064..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-# makefile for libpng
-# Copyright (C) 2002, 2006, 2009, 2014 Glenn Randers-Pehrson
-# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
-#
-# This code is released under the libpng license.
-# For conditions of distribution and use, see the disclaimer
-# and license in png.h
-#
-# This makefile requires the file ansi2knr.c, which you can get
-# from the Ghostscript ftp site at ftp://ftp.cs.wisc.edu/ghost/
-# If you have libjpeg, you probably already have ansi2knr.c in the jpeg
-# source distribution.
-
-# where make install puts libpng.a and png.h
-prefix=/usr/local
-INCPATH=$(prefix)/include
-LIBPATH=$(prefix)/lib
-
-# override DESTDIR= on the make install command line to easily support
-# installing into a temporary location.  Example:
-#
-#    make install DESTDIR=/tmp/build/libpng
-#
-# If you're going to install into a temporary location
-# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
-# you execute make install.
-DESTDIR=
-
-CC = cc
-CPPFLAGS = -I../zlib
-CFLAGS = -O
-LDFLAGS = -L. -L../zlib/ -lpng -lz -lm
-# flags for ansi2knr
-ANSI2KNRFLAGS=
-
-RANLIB = ranlib
-#RANLIB = echo
-
-CP = cp
-RM_F = rm -f
-
-# Pre-built configuration
-# See scripts/pnglibconf.mak for more options
-PNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt
-
-OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
-       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
-       pngwtran.o pngmem.o pngerror.o pngpread.o
-
-all: ansi2knr libpng.a pngtest
-
-pnglibconf.h: $(PNGLIBCONF_H_PREBUILT)
-       $(CP) $(PNGLIBCONF_H_PREBUILT) $@
-
-# general rule to allow ansi2knr to work
-.c.o:
-       ./ansi2knr $*.c T$*.c
-       $(CC) $(CPPFLAGS) $(CFLAGS) -c T$*.c
-       rm -f T$*.c $*.o
-       mv T$*.o $*.o
-
-ansi2knr: ansi2knr.c
-       $(CC) $(CPPFLAGS) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c
-
-libpng.a: ansi2knr $(OBJS)
-       ar rc $@  $(OBJS)
-       $(RANLIB) $@
-
-pngtest: pngtest.o libpng.a
-       $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
-
-test: pngtest
-       ./pngtest
-
-install: libpng.a png.h pngconf.h pnglibconf.h
-       -@mkdir $(DESTDIR)$(INCPATH)
-       -@mkdir $(DESTDIR)$(INCPATH)/libpng
-       -@mkdir $(DESTDIR)$(LIBPATH)
-       -@rm -f $(DESTDIR)$(INCPATH)/png.h
-       -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h
-       cp png.h $(DESTDIR)$(INCPATH)/libpng
-       cp pngconf.h $(DESTDIR)$(INCPATH)/libpng
-       cp pnglibconf.h $(DESTDIR)$(INCPATH)/libpng
-       chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h
-       chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h
-       chmod 644 $(DESTDIR)$(INCPATH)/libpng/pnglibconf.h
-       (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)
-       cp libpng.a $(DESTDIR)$(LIBPATH)
-       chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a
-
-clean:
-       $(RM_F) *.o libpng.a pngtest pngout.png ansi2knr pnglibconf.h
-
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
-writelock:
-       chmod a-w *.[ch35] $(DOCS) scripts/*
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-png.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngerror.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngrio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-
-pngtest.o: png.h pngconf.h pnglibconf.h
index 1dc2409..32eb859 100644 (file)
@@ -10,7 +10,7 @@
 # Library name:
 LIBNAME = libpng16
 PNGMAJ = 16
-RELEASE = 21
+RELEASE = 36
 
 # Shared library names:
 LIBSO=$(LIBNAME).so
@@ -50,8 +50,7 @@ WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
 # for pgcc version 2.95.1, -O3 is buggy; don't use it.
 
 CPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5
-CFLAGS= -W -Wall -O3 -funroll-loops \
-       $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5
+CFLAGS=-W -Wall -O3 -funroll-loops $(ALIGN) # $(WARNMORE) -g
 
 LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng16 -lz -lm
 LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm
@@ -92,7 +91,7 @@ OBJSDLL = $(OBJS:.o=.pic.o)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
 
 .c.pic.o:
-       $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $*.c
 
 all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config
 
@@ -222,7 +221,7 @@ clean:
        $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \
        libpng.pc pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
similarity index 67%
rename from scripts/makefile.solaris-x86
rename to scripts/makefile.linux-opt
index b6d2437..76f6d1a 100644 (file)
@@ -1,9 +1,8 @@
-# makefile for libpng on Solaris 2.x with gcc
-# Copyright (C) 2004, 2006-2008, 2010-2014 Glenn Randers-Pehrson
-# Contributed by William L. Sebok, based on makefile.linux
-# Copyright (C) 1998 Greg Roelofs
-# Copyright (C) 1996, 1997 Andreas Dilger
-
+# makefile for libpng.a and libpng16.so on Linux ELF with gcc
+# Copyright (C) 1998,1999,2002,2006,2008,2010-2014,2017 Greg Roelofs and
+# Glenn Randers-Pehrson
+# Copyright (C) 1996,1997 Andreas Dilger
+#
 # This code is released under the libpng license.
 # For conditions of distribution and use, see the disclaimer
 # and license in png.h
@@ -11,6 +10,7 @@
 # Library name:
 LIBNAME = libpng16
 PNGMAJ = 16
+RELEASE = 36
 
 # Shared library names:
 LIBSO=$(LIBNAME).so
@@ -22,30 +22,45 @@ OLDSO=libpng.so
 AR_RC=ar rc
 CC=gcc
 MKDIR_P=mkdir -p
-LN_SF=ln -f -s
-RANLIB=echo
+LN_SF=ln -sf
+RANLIB=ranlib
 CP=cp
 RM_F=/bin/rm -f
 
-# Where make install puts libpng.a, libpng16.so*, and png.h
+# where "make install" puts libpng16.a, libpng16.so*,
+# libpng16/png.h, libpng16/pngconf.h, and libpng16/pnglibconf.h
+# Prefix must be a full pathname.
 prefix=/usr/local
 exec_prefix=$(prefix)
 
-# Where the zlib library and include files are located
-# Changing these to ../zlib poses a security risk.  If you want
-# to have zlib in an adjacent directory, specify the full path instead of "..".
-#ZLIBLIB=../zlib
-#ZLIBINC=../zlib
+# Where the zlib library and include files are located.
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+#WARNMORE=-Wwrite-strings -Wpointer-arith \
+#      -Wmissing-declarations -Wtraditional -Wcast-align \
+#      -Wstrict-prototypes -Wmissing-prototypes
 
-ZLIBLIB=/usr/local/lib
-ZLIBINC=/usr/local/include
+# for pgcc version 2.95.1, -O3 is buggy; don't use it.
 
-WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
-       -Wmissing-declarations -Wtraditional -Wcast-align \
-       -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
-CPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5
-CFLAGS=-W -Wall -O # $(WARNMORE) -g
-LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng16 -lz -lm
+CPPFLAGS=-I$(ZLIBINC)
+CPPFLAGS += -DPNG_ARM_NEON
+CPPFLAGS += -DPNG_MIPS_MSA
+CPPFLAGS += -DPNG_INTEL_SSE
+CPPFLAGS += -DPNG_POWERPC_VSX
+CPPFLAGS+=-ansi -pedantic -Wextra -Wall -Wshadow -Wno-sign-conversion
+CPPFLAGS+=-W -Wall -Wconversion $(ALIGN)
+# CPPFLAGS+=$(WARNMORE)
+CFLAGS= -O3 -funroll-loops
+
+LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng16 -lz -lm
+LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm
 
 INCPATH=$(prefix)/include
 LIBPATH=$(exec_prefix)/lib
@@ -71,9 +86,13 @@ DM=$(DESTDIR)$(MANPATH)
 # See scripts/pnglibconf.mak for more options
 PNGLIBCONF_H_PREBUILT = scripts/pnglibconf.h.prebuilt
 
-OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+OBJS =  png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
        pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
-       pngwtran.o pngmem.o pngerror.o pngpread.o
+       pngwtran.o pngmem.o pngerror.o pngpread.o \
+       arm/arm_init.o arm/filter_neon_intrinsics.o \
+       mips/mips_init.o mips/filter_msa_intrinsics.o \
+       intel/intel_init.o intel/filter_sse2_intrinsics.o\
+       powerpc/powerpc_init.o powerpc/filter_vsx_intrinsics.o
 
 OBJSDLL = $(OBJS:.o=.pic.o)
 
@@ -83,9 +102,9 @@ OBJSDLL = $(OBJS:.o=.pic.o)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
 
 .c.pic.o:
-       $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $*.c
 
-all: libpng.a $(LIBSO) pngtest libpng.pc libpng-config
+all: libpng.a $(LIBSO) pngtest pngtest-static libpng.pc libpng-config
 
 pnglibconf.h: $(PNGLIBCONF_H_PREBUILT)
        $(CP) $(PNGLIBCONF_H_PREBUILT) $@
@@ -105,9 +124,8 @@ libpng-config:
        ( cat scripts/libpng-config-head.in; \
        echo prefix=\"$(prefix)\"; \
        echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
-       echo cppflags=\""; \
        echo L_opts=\"-L$(LIBPATH)\"; \
-       echo R_opts=\"-R$(LIBPATH)\"; \
+       echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \
        echo libs=\"-lpng16 -lz -lm\"; \
        cat scripts/libpng-config-body.in ) > libpng-config
        chmod +x libpng-config
@@ -116,26 +134,23 @@ $(LIBSO): $(LIBSOMAJ)
        $(LN_SF) $(LIBSOMAJ) $(LIBSO)
 
 $(LIBSOMAJ): $(OBJSDLL)
-       @case "`type ld`" in *ucb*) \
-       echo; \
-       echo '## WARNING:'; \
-       echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \
-       echo '## and /usr/ucb/ld.  If they do, you need to adjust your PATH'; \
-       echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \
-       echo '## The environment variable LD_LIBRARY_PATH should not be set'; \
-       echo '## at all.  If it is, things are likely to break because of'; \
-       echo '## the libucb dependency that is created.'; \
-       echo; \
-       ;; \
-       esac
-       $(LD) -G -h $(LIBSOMAJ) \
-        -o $(LIBSOMAJ) $(OBJSDLL)
+       $(CC) -shared -Wl,-soname,$(LIBSOMAJ) -o $(LIBSOMAJ) $(OBJSDLL)
 
 pngtest: pngtest.o $(LIBSO)
        $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
 
-test: pngtest
+pngtest-static: pngtest.o libpng.a
+       $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A)
+
+test: pngtest pngtest-static
+       @echo ""
+       @echo "   Running pngtest dynamically linked with $(LIBSO):"
+       @echo ""
        ./pngtest
+       @echo ""
+       @echo "   Running pngtest statically linked with libpng.a:"
+       @echo ""
+       ./pngtest-static
 
 install-headers: png.h pngconf.h pnglibconf.h
        -@if [ ! -d $(DI) ]; then $(MKDIR_P) $(DI); fi
@@ -163,6 +178,7 @@ install-shared: install-headers $(LIBSOMAJ) libpng.pc
        (cd $(DL); \
        $(LN_SF) $(LIBSOREL) $(LIBSO); \
        $(LN_SF) $(LIBSO) $(OLDSO))
+
        -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR_P) $(DL)/pkgconfig; fi
        -@$(RM_F) $(DL)/pkgconfig/$(LIBNAME).pc
        -@$(RM_F) $(DL)/pkgconfig/libpng.pc
@@ -200,25 +216,23 @@ test-dd:
        echo Testing installed dynamic shared library in $(DL).
        $(CC) -I$(DI) $(CPPFLAGS) \
           `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \
-          -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags` \
-          -L$(DL) -L$(ZLIBLIB) -R$(ZLIBLIB) -R$(DL)
+          -L$(DL) -L$(ZLIBLIB) -Wl, -rpath,$(DL) -Wl,-rpath,$(ZLIBLIB) \
+          -o pngtestd `$(BINPATH)/$(LIBNAME)-config --ldflags`
        ./pngtestd pngtest.png
 
 test-installed:
-       echo
-       echo Testing installed dynamic shared library.
        $(CC) $(CPPFLAGS) \
           `$(BINPATH)/$(LIBNAME)-config --cflags` pngtest.c \
-          -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags` \
-          -L$(ZLIBLIB) -R$(ZLIBLIB)
+          -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
+          -o pngtesti `$(BINPATH)/$(LIBNAME)-config --ldflags`
        ./pngtesti pngtest.png
 
 clean:
-       $(RM_F) *.o libpng.a pngtest pngtesti pngout.png \
-       libpng-config $(LIBSO) $(LIBSOMAJ)* \
+       $(RM_F) *.o libpng.a pngtest pngout.png libpng-config \
+       $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \
        libpng.pc pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
@@ -239,5 +253,13 @@ pngwrite.o pngwrite.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pn
 pngwtran.o pngwtran.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngwutil.o pngwutil.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngpread.o pngpread.pic.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
+arm/arm_init.o arm/arm_init.o: pngpriv.h
+arm/filter_neon_intrinsics.o arm/filter_neon_intrinsics.pic.o: pngpriv.h
+mips/mips_init.o mips/mips_init.pic.o: pngpriv.h
+mips/filter_msa_intrinsics.o mips/filter_msa_intrinsics.pic.:  pngpriv.h
+intel/intel_init.o intel/intel_init.pic.:  pngpriv.h
+intel/filter_sse2_intrinsics.o intel/filter_sse2_intrinsics.pic.:  pngpriv.h
+powerpc/powerpc_init.o powerpc/powerpc_init.pic.:  pngpriv.h
+powerpc/filter_vsx_intrinsics.o powerpc/filter_vsx_intrinsics.pic.:  pngpriv.h
 
 pngtest.o: png.h pngconf.h pnglibconf.h
index 5633608..0357ae8 100644 (file)
@@ -78,7 +78,7 @@ install: libpng.a
 clean:
        rm -f *.o libpng.a pngtest pngout.png pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
diff --git a/scripts/makefile.msc b/scripts/makefile.msc
deleted file mode 100644 (file)
index 539d62e..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-# makefile for libpng
-# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
-# Copyright (C) 2006, 2009, 2014 Glenn Randers-Pehrson
-#
-# This code is released under the libpng license.
-# For conditions of distribution and use, see the disclaimer
-# and license in png.h
-#
-# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
-
-# -------- Microsoft C 5.1 and later, does not use assembler code --------
-MODEL=L
-CPPFLAGS=-I..\zlib
-CFLAGS=-Oait -Gs -nologo -W3 -A$(MODEL)
-#-Ox generates bad code with MSC 5.1
-CC=cl
-LD=link
-LDFLAGS=/e/st:0x1500/noe
-CP=copy
-O=.obj
-
-# Pre-built configuration
-# See scripts\pnglibconf.mak for more options
-PNGLIBCONF_H_PREBUILT = scripts\pnglibconf.h.prebuilt
-
-#uncomment next to put error messages in a file
-ERRFILE= >> pngerrs
-
-# variables
-OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
-OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
-OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
-
-all: libpng.lib
-
-pnglibconf.h: $(PNGLIBCONF_H_PREBUILT)
-       $(CP) $(PNGLIBCONF_H_PREBUILT) $@
-
-png$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngset$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngget$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngpread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngrtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngrutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngerror$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngmem$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngrio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngwio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngtrans$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngwrite$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngwtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngwutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
-       del libpng.lib
-       lib libpng $(OBJS1);
-       lib libpng $(OBJS2);
-       lib libpng $(OBJS3);
-
-pngtest$(O): png.h pngconf.h pnglibconf.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c $(ERRFILE)
-
-pngtest.exe: pngtest.obj libpng.lib
-       $(LD) $(LDFLAGS) pngtest.obj,,,libpng.lib ..\zlib\zlib.lib ;
-
-test: pngtest.exe
-       pngtest
-
-# End of makefile for libpng
-
index 8a8dee1..2af7a6a 100644 (file)
@@ -18,7 +18,7 @@ exec_prefix=$(prefix)
 # Library name:
 LIBNAME = libpng16
 PNGMAJ = 16
-RELEASE = 21
+RELEASE = 36
 
 # Shared library names:
 LIBSO=$(LIBNAME).dll
index f4cebc2..d0a6a37 100644 (file)
@@ -17,7 +17,7 @@ INCSDIR=${LOCALBASE}/include/libpng16
 
 LIB=   png16
 SHLIB_MAJOR=   0
-SHLIB_MINOR=   1.6.21
+SHLIB_MINOR=   1.6.36
 SRCS=  png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
        pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
        pngwtran.c pngmem.c pngerror.c pngpread.c
index da93b65..589c1f8 100644 (file)
@@ -17,7 +17,7 @@ INCSDIR=${LOCALBASE}/include
 
 LIB=   png
 SHLIB_MAJOR=   16
-SHLIB_MINOR=   1.6.21
+SHLIB_MINOR=   1.6.36
 SRCS=  png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
        pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
        pngwtran.c pngmem.c pngerror.c pngpread.c
index 0696751..4057b2e 100644 (file)
@@ -11,7 +11,7 @@ LIBDIR=       ${PREFIX}/lib
 MANDIR= ${PREFIX}/man/cat
 
 SHLIB_MAJOR=   16
-SHLIB_MINOR=   1.6.21
+SHLIB_MINOR=   1.6.36
 
 LIB=   png
 SRCS=  png.c pngerror.c pngget.c pngmem.c pngpread.c \
@@ -28,7 +28,7 @@ NOPROFILE= Yes
 CLEANFILES+= pngtest.o pngtest pnglibconf.h
 
 MAN=   libpng.3 libpngpf.3 png.5
-DOCS=  ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO \
+DOCS=  ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO \
        libpng-manual.txt
 
 # Pre-built configuration
index b9c7c40..01d7eaa 100644 (file)
@@ -1,5 +1,5 @@
 # makefile for SCO OSr5  ELF and Unixware 7 with Native cc
-# Contributed by Mike Hopkirk (hops@sco.com) modified from Makefile.lnx
+# Contributed by Mike Hopkirk (hops at sco.com) modified from Makefile.lnx
 #   force ELF build dynamic linking, SONAME setting in lib and RPATH in app
 # Copyright (C) 2002, 2006, 2010-2014 Glenn Randers-Pehrson
 # Copyright (C) 1998 Greg Roelofs
@@ -201,7 +201,7 @@ clean:
        $(LIBSO) $(LIBSOMAJ)* pngtest-static pngtesti \
        pnglibconf.h libpng.pc
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index a0d051d..82efe7a 100644 (file)
@@ -211,7 +211,7 @@ clean:
        $(RM_F) libpng.a pngtest pngtesti pngout.png libpng.pc \
        so_locations libpng-config $(LIBSO) $(LIBSOMAJ)* pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index 7df0902..5d9c23f 100644 (file)
@@ -212,7 +212,7 @@ clean:
        $(LIBSO) $(LIBSOMAJ)* \
        so_locations pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index ba9308c..93166f3 100644 (file)
@@ -222,7 +222,7 @@ clean:
        libpng-config $(LIBSO) $(LIBSOMAJ)* \
        libpng.pc pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index 8a450d3..f6d7b58 100644 (file)
@@ -44,8 +44,7 @@ WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
        -Wmissing-declarations -Wtraditional -Wcast-align \
        -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
 CPPFLAGS=-I$(ZLIBINC) # -DPNG_DEBUG=5
-CFLAGS= -W -Wall -O \
-       # $(WARNMORE) -g -DPNG_DEBUG=5
+CFLAGS=-W -Wall -O # $(WARNMORE) -g
 LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng16 -lz -lm
 
 INCPATH=$(prefix)/include
@@ -219,7 +218,7 @@ clean:
        libpng-config $(LIBSO) $(LIBSOMAJ)* \
        libpng.pc pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
index ee6a868..2f4871d 100644 (file)
@@ -109,7 +109,7 @@ clean:
        $(RM_F) *.o libpng.a pngtest pngout.png pnglibconf.h pnglibconf.c \
        pnglibconf.out
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
@@ -122,6 +122,7 @@ pngwio.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.
 pngmem.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngset.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngget.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
+pngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngrtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngrutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
@@ -129,6 +130,5 @@ pngtrans.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebu
 pngwrite.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngwtran.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 pngwutil.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-pngpread.o: png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
 
 pngtest.o: png.h pngconf.h pnglibconf.h
index efe308c..9a0e28e 100644 (file)
@@ -90,7 +90,7 @@ install: libpng.a
 clean:
        $(RM_F) *.o libpng.a pngtest pngout.png pnglibconf.h
 
-DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO
 writelock:
        chmod a-w *.[ch35] $(DOCS) scripts/*
 
diff --git a/scripts/makefile.tc3 b/scripts/makefile.tc3
deleted file mode 100644 (file)
index 1d01502..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-# Makefile for libpng
-# TurboC/C++ (Note: All modules are compiled in C mode)
-
-# To use, do "make -fmakefile.tc3"
-
-# ----- Turbo C++ 3.0 -----
-
-MODEL=l
-CPPFLAGS=-I..\zlib
-CFLAGS=-O2 -Z -m$(MODEL)
-CC=tcc
-LD=tcc
-LIB=tlib
-LDFLAGS=-m$(MODEL) -L..\zlib
-CP=copy
-
-# Pre-built configuration
-# See scripts\pnglibconf.mak for more options
-!ifndef PNGLIBCONF_H_PREBUILT
-PNGLIBCONF_H_PREBUILT = scripts\pnglibconf.h.prebuilt
-!endif
-
-O=.obj
-E=.exe
-
-# variables
-OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
-OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
-OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
-OBJSL1 = +png$(O) +pngset$(O) +pngget$(O) +pngrutil$(O) +pngtrans$(O)
-OBJSL2 = +pngwutil$(O) +pngmem$(O) +pngpread$(O) +pngread$(O) +pngerror$(O)
-OBJSL3 = +pngwrite$(O) +pngrtran$(O) +pngwtran$(O) +pngrio$(O) +pngwio$(O)
-
-all: libpng$(MODEL).lib pngtest$(E)
-
-pnglibconf.h: $(PNGLIBCONF_H_PREBUILT)
-       $(CP) $(PNGLIBCONF_H_PREBUILT) $@
-
-pngtest: pngtest$(E)
-
-test: pngtest$(E)
-       pngtest$(E)
-
-png$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-                 $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngset$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-                 $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngget$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-                 $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-                 $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngpread$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-                 $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngrtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-                 $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngrutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-                 $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngerror$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngmem$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngrio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngwio$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngtest$(O): png.h pngconf.h pnglibconf.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngtrans$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngwrite$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngwtran$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-pngwutil$(O): png.h pngconf.h pnglibconf.h pngpriv.h pngstruct.h pnginfo.h pngdebug.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c
-
-libpng$(MODEL).lib: $(OBJS1) $(OBJS2) $(OBJS3)
-       $(LIB) libpng$(MODEL) +$(OBJSL1)
-       $(LIB) libpng$(MODEL) +$(OBJSL2)
-       $(LIB) libpng$(MODEL) +$(OBJSL3)
-
-pngtest$(E): pngtest$(O) libpng$(MODEL).lib
-       $(LD) $(LDFLAGS) pngtest.obj libpng$(MODEL).lib zlib_$(MODEL).lib
-
-# End of makefile for libpng
index 81b82ff..fef5dfd 100755 (executable)
@@ -40,7 +40,7 @@ BEGIN{
    # the lines, for example by inserting spaces around operators, and all
    # C preprocessors notice lines that start with '#', most remove comments.
    # The technique adopted here is to make the final output lines into
-   # C strings (enclosed in double quotes), preceeded by PNG_DFN.  As a
+   # C strings (enclosed in double quotes), preceded by PNG_DFN.  As a
    # consequence the output cannot contain a 'raw' double quote - instead put
    # @' in, this will be replaced by a single " afterward.  See the parser
    # script dfn.awk for more capabilities (not required here).  Note that if
@@ -336,7 +336,7 @@ $1 == "option" && NF >= 2{
 
 # chunk NAME [requires OPT] [enables LIST] [on|off|disabled]
 #   Expands to the 'option' settings appropriate to the reading and
-#   writing of an ancilliary PNG chunk 'NAME':
+#   writing of an ancillary PNG chunk 'NAME':
 #
 #   option READ_NAME requires READ_ANCILLARY_CHUNKS [READ_OPT]
 #   option READ_NAME enables NAME LIST
@@ -805,8 +805,8 @@ END{
    print comment, "end of options", cend >out
 
    # Do the 'setting' values second, the algorithm the standard
-   # tree walk (O(1)) done in an O(2) while/for loop; interations
-   # settings x depth, outputing the deepest required macros
+   # tree walk (O(1)) done in an O(2) while/for loop; iterations
+   # settings x depth, outputting the deepest required macros
    # first.
    print "" >out
    print "/* SETTINGS */" >out
index adffd30..15bd08e 100644 (file)
@@ -8,7 +8,8 @@ com pnglibconf.h - library build configuration
 com
 version
 com
-com Copyright (c) 1998-2016 Glenn Randers-Pehrson
+com Copyright (c) 2018 Cosmin Truta
+com Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
 com
 com This code is released under the libpng license.
 com For conditions of distribution and use, see the disclaimer
@@ -189,7 +190,7 @@ setting USER_VERSIONINFO_LEGALTRADEMARKS
 
 setting API_RULE default 0
 
-# This allows a prefix to be added to the front of every API functon name (and
+# This allows a prefix to be added to the front of every API function name (and
 # therefore every symbol) by redefining all the function names with the prefix
 # at the end of pnglibconf.h.  It also turns on similar internal symbol renaming
 # by causing a similar build-time only file, pngprefix.h, to be generated.
@@ -229,6 +230,33 @@ option ARM_NEON_API disabled requires ALIGNED_MEMORY enables SET_OPTION,
 option ARM_NEON_CHECK disabled requires ALIGNED_MEMORY,
    sets ARM_NEON_OPT 1
 
+# These options are specific to the PowerPC VSX hardware optimizations.
+#
+# POWERPC_VSX_OPT: unset: check at compile time (__PPC64__,__ALTIVEC__,__VSX__
+#                      must be defined by the compiler, typically as a result
+#                      of specifying
+#                      "-mvsx -maltivec" compiler flags)
+#                   0: disable (even if the CPU supports VSX.)
+#                   1: check at run time (via POWERPC_VSX_{API,CHECK})
+#                   2: switch on unconditionally (inadvisable - instead pass
+#                      -mvsx -maltivec to compiler options)
+#           When building libpng avoid using any setting other than '0'; '1' is
+#           set automatically when either 'API' or 'CHECK' are configured in,
+#           '2' should not be necessary as "-mvsx -maltivec" will achieve the same
+#           effect as well as applying VSX optimizations to the rest of the
+#           libpng code.
+# POWERPC_VSX_API:   (PNG_POWERPC_VSX == 1) allow the optimization to be switched on
+#                 with png_set_option
+# POWERPC_VSX_CHECK: (PNG_POWERPC_VSX == 1) compile a run-time check to see if VSX
+#                 extensions are supported. This is supported not for all OSes
+#                 (see contrib/powerpc/README)
+setting POWERPC_VSX_OPT
+option POWERPC_VSX_API disabled enables SET_OPTION,
+  sets POWERPC_VSX_OPT 1
+option POWERPC_VSX_CHECK disabled,
+  sets POWERPC_VSX_OPT 1
+
+
 # These settings configure the default compression level (0-9) and 'strategy';
 # strategy is as defined by the implementors of zlib. It describes the input
 # data and modifies the zlib parameters in an attempt to optimize the balance
@@ -297,7 +325,7 @@ option WRITE_INT_FUNCTIONS disabled
 #     By default recoverable errors on write should just generate warnings,
 #     not generally safe because this allows the application to write invalid
 #     PNG files.  Applications should enable this themselves; it's useful
-#     because it means that a failure to write an ancilliary chunk can often be
+#     because it means that a failure to write an ancillary chunk can often be
 #     ignored.
 
 option WARNINGS
@@ -368,7 +396,7 @@ option IO_STATE
 option USER_LIMITS requires READ
 
 # The default settings given below for the limits mean that libpng will
-# limit the size of images or the size of data in ancilliary chunks to less
+# limit the size of images or the size of data in ancillary chunks to less
 # than the specification or implementation limits. Settings have the
 # following interpretations:
 #
@@ -532,7 +560,7 @@ option WRITE_CUSTOMIZE_ZTXT_COMPRESSION requires WRITE
 option WRITE_CUSTOMIZE_COMPRESSION requires WRITE
 
 # Any chunks you are not interested in, you can undef here.  The
-# ones that allocate memory may be expecially important (hIST,
+# ones that allocate memory may be especially important (hIST,
 # tEXt, zTXt, tRNS, pCAL).  Others will just save time and make png_info
 # a bit smaller.
 
@@ -552,6 +580,7 @@ option WRITE_ANCILLARY_CHUNKS requires WRITE
 
 # These options disable *all* the text chunks if turned off
 
+option TEXT disabled
 option READ_TEXT requires READ_ANCILLARY_CHUNKS enables TEXT
 option WRITE_TEXT requires WRITE_ANCILLARY_CHUNKS enables TEXT
 
@@ -687,7 +716,7 @@ setting sCAL_PRECISION default 5
 setting ZBUF_SIZE default 8192
 
 # This is the size of the decompression buffer used when counting or checking
-# the decompressed size of an LZ stream from a compressed ancilliary chunk; the
+# the decompressed size of an LZ stream from a compressed ancillary chunk; the
 # decompressed data is never used so a different size may be optimal.  This size
 # was determined using contrib/libtests/timepng.c with compressed zTXt data
 # around 11MByte in size.  Slight speed improvements (up to about 14% in
@@ -713,6 +742,7 @@ setting IDAT_READ_SIZE default PNG_ZBUF_SIZE
 # Ancillary chunks
 chunk bKGD
 chunk cHRM enables COLORSPACE
+chunk eXIf
 chunk gAMA enables GAMMA
 chunk hIST
 chunk iCCP enables COLORSPACE, GAMMA
@@ -873,9 +903,12 @@ option SIMPLIFIED_READ_BGR enables FORMAT_BGR,
 
 # Write:
 option SIMPLIFIED_WRITE,
-   requires WRITE STDIO, SETJMP, WRITE_SWAP, WRITE_PACK,
+   requires WRITE, SETJMP, WRITE_SWAP, WRITE_PACK,
       WRITE_tRNS, WRITE_gAMA, WRITE_sRGB, WRITE_cHRM
 
+# 1.6.22: allow simplified write without stdio support:
+option SIMPLIFIED_WRITE_STDIO requires SIMPLIFIED_WRITE STDIO
+
 option SIMPLIFIED_WRITE_AFIRST enables FORMAT_AFIRST,
    requires SIMPLIFIED_WRITE WRITE_SWAP_ALPHA
 
index a1ef17f..00340c6 100644 (file)
@@ -1,10 +1,9 @@
-/* libpng 1.6.21 STANDARD API DEFINITION */
-
 /* pnglibconf.h - library build configuration */
 
-/* Libpng version 1.6.21 - January 15, 2016 */
+/* libpng version 1.6.36 */
 
-/* Copyright (c) 1998-2015 Glenn Randers-Pehrson */
+/* Copyright (c) 2018 Cosmin Truta */
+/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
 
 /* This code is released under the libpng license. */
 /* For conditions of distribution and use, see the disclaimer */
@@ -44,6 +43,8 @@
 #define PNG_IO_STATE_SUPPORTED
 #define PNG_MNG_FEATURES_SUPPORTED
 #define PNG_POINTER_INDEXING_SUPPORTED
+/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
+/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
 #define PNG_PROGRESSIVE_READ_SUPPORTED
 #define PNG_READ_16BIT_SUPPORTED
 #define PNG_READ_ALPHA_MODE_SUPPORTED
@@ -82,6 +83,7 @@
 #define PNG_READ_USER_TRANSFORM_SUPPORTED
 #define PNG_READ_bKGD_SUPPORTED
 #define PNG_READ_cHRM_SUPPORTED
+#define PNG_READ_eXIf_SUPPORTED
 #define PNG_READ_gAMA_SUPPORTED
 #define PNG_READ_hIST_SUPPORTED
 #define PNG_READ_iCCP_SUPPORTED
 #define PNG_SIMPLIFIED_READ_SUPPORTED
 #define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
 #define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
 #define PNG_SIMPLIFIED_WRITE_SUPPORTED
 #define PNG_STDIO_SUPPORTED
 #define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
 #define PNG_WRITE_bKGD_SUPPORTED
 #define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_WRITE_eXIf_SUPPORTED
 #define PNG_WRITE_gAMA_SUPPORTED
 #define PNG_WRITE_hIST_SUPPORTED
 #define PNG_WRITE_iCCP_SUPPORTED
 #define PNG_WRITE_zTXt_SUPPORTED
 #define PNG_bKGD_SUPPORTED
 #define PNG_cHRM_SUPPORTED
+#define PNG_eXIf_SUPPORTED
 #define PNG_gAMA_SUPPORTED
 #define PNG_hIST_SUPPORTED
 #define PNG_iCCP_SUPPORTED
index 4c35fd7..82494bb 100644 (file)
@@ -1,4 +1,3 @@
-;Version 1.6.21
 ;--------------------------------------------------------------
 ; LIBPNG symbol list as a Win32 DEF file
 ; Contains all the symbols that can be exported from libpng
@@ -249,3 +248,8 @@ EXPORTS
  png_set_check_for_invalid_index @242
  png_get_palette_max @243
  png_set_option @244
+ png_image_write_to_memory @245
+ png_get_eXIf @246
+ png_set_eXIf @247
+ png_get_eXIf_1 @248
+ png_set_eXIf_1 @249
diff --git a/scripts/test.cmake.in b/scripts/test.cmake.in
new file mode 100644 (file)
index 0000000..fa6a889
--- /dev/null
@@ -0,0 +1,31 @@
+# test.cmake.in
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+set(TEST_OPTIONS "@TEST_OPTIONS@")
+set(TEST_FILES "@TEST_FILES@")
+
+foreach(file ${TEST_FILES})
+  file(TO_NATIVE_PATH "${file}" native_file)
+  list(APPEND NATIVE_TEST_FILES "${native_file}")
+endforeach()
+
+# Add the directory containing libpng to the PATH (Windows only)
+if(WIN32)
+  get_filename_component(LIBPNG_DIR "${LIBPNG}" PATH)
+  file(TO_NATIVE_PATH "${LIBPNG_DIR}" LIBPNG_DIR)
+  set(ENV{PATH} "${LIBPNG_DIR};$ENV{PATH}")
+endif()
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "Running ${TEST_COMMAND}" ${TEST_OPTIONS} ${NATIVE_TEST_FILES})
+
+execute_process(COMMAND "${TEST_COMMAND}" ${TEST_OPTIONS} ${NATIVE_TEST_FILES}
+                RESULT_VARIABLE TEST_STATUS)
+if(TEST_STATUS)
+  message(FATAL_ERROR "Returned failed status ${TEST_STATUS}!")
+endif()
index 8e575b0..b8521a4 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
 # test-driver - basic testsuite driver script.
 
-scriptversion=2013-07-13.22; # UTC
+scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+# Copyright (C) 2011-2018 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ scriptversion=2013-07-13.22; # UTC
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -140,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
 # Local Variables:
 # mode: shell-script
 # sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
index 0400b07..9d1b776 100755 (executable)
@@ -17,36 +17,38 @@ gamma="$1"
 shift
 alpha="$1"
 shift
-exec ./pngstest --tmpfile "${gamma}-${alpha}-" --log ${1+"$@"} `
-   for f in "${srcdir}/contrib/testpngs/"*.png
-   do
-      g=
-      case "$f" in
-         *-linear[.-]*)
-            test "$gamma" = "linear" && g="$f";;
+args=
+LC_ALL="C" # fix glob sort order to ASCII:
+for f in "${srcdir}/contrib/testpngs/"*.png
+do
+   g=
+   case "$f" in
+      *-linear[.-]*)
+         test "$gamma" = "linear" && g="$f";;
 
-         *-sRGB[.-]*)
-            test "$gamma" = "sRGB" && g="$f";;
+      *-sRGB[.-]*)
+         test "$gamma" = "sRGB" && g="$f";;
 
-         *-1.8[.-]*)
-            test "$gamma" = "1.8" && g="$f";;
+      *-1.8[.-]*)
+         test "$gamma" = "1.8" && g="$f";;
 
-         *)
-            test "$gamma" = "none" && g="$f";;
-      esac
+      *)
+         test "$gamma" = "none" && g="$f";;
+   esac
 
-      case "$g" in
-         "")
-            :;;
+   case "$g" in
+      "")
+         :;;
 
-         *-alpha[-.]*)
-            test "$alpha" = "alpha" && echo "$g";;
+      *-alpha[-.]*)
+         test "$alpha" = "alpha" && args="$args $g";;
 
-         *-tRNS[-.]*)
-            test "$alpha" = "tRNS" -o "$alpha" = "none" && echo "$g";;
+      *-tRNS[-.]*)
+         test "$alpha" = "tRNS" -o "$alpha" = "none" && args="$args $g";;
 
-         *)
-            test "$alpha" = "opaque" -o "$alpha" = "none" && echo "$g";;
-      esac
-   done
-`
+      *)
+         test "$alpha" = "opaque" -o "$alpha" = "none" && args="$args $g";;
+   esac
+done
+# This only works if the arguments don't contain spaces; they don't.
+exec ./pngstest --tmpfile "${gamma}-${alpha}-" --log ${1+"$@"} $args
diff --git a/tests/pngstest-0g01 b/tests/pngstest-0g01
deleted file mode 100755 (executable)
index 4a495cc..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 0g01
diff --git a/tests/pngstest-0g02 b/tests/pngstest-0g02
deleted file mode 100755 (executable)
index 1a607c8..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 0g02
diff --git a/tests/pngstest-0g04 b/tests/pngstest-0g04
deleted file mode 100755 (executable)
index 595ba01..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 0g04
diff --git a/tests/pngstest-0g08 b/tests/pngstest-0g08
deleted file mode 100755 (executable)
index 21a8b4b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 0g08
diff --git a/tests/pngstest-0g16 b/tests/pngstest-0g16
deleted file mode 100755 (executable)
index 0104c37..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 0g16
diff --git a/tests/pngstest-2c08 b/tests/pngstest-2c08
deleted file mode 100755 (executable)
index 9e0de6f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 2c08
diff --git a/tests/pngstest-2c16 b/tests/pngstest-2c16
deleted file mode 100755 (executable)
index c1b88b0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 2c16
diff --git a/tests/pngstest-3p01 b/tests/pngstest-3p01
deleted file mode 100755 (executable)
index 6aeb8d0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 3p01
diff --git a/tests/pngstest-3p02 b/tests/pngstest-3p02
deleted file mode 100755 (executable)
index 770a75c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 3p02
diff --git a/tests/pngstest-3p04 b/tests/pngstest-3p04
deleted file mode 100755 (executable)
index 957d6ae..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 3p04
diff --git a/tests/pngstest-3p08 b/tests/pngstest-3p08
deleted file mode 100755 (executable)
index d0947af..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 3p08
diff --git a/tests/pngstest-4a08 b/tests/pngstest-4a08
deleted file mode 100755 (executable)
index 2fab57f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 4a08
diff --git a/tests/pngstest-4a16 b/tests/pngstest-4a16
deleted file mode 100755 (executable)
index e4ad5aa..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 4a16
diff --git a/tests/pngstest-6a08 b/tests/pngstest-6a08
deleted file mode 100755 (executable)
index aa6c03c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 6a08
diff --git a/tests/pngstest-6a16 b/tests/pngstest-6a16
deleted file mode 100755 (executable)
index 545b1b3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec "${srcdir}/tests/pngstest" 6a16
diff --git a/tests/pngstest-error b/tests/pngstest-error
deleted file mode 100755 (executable)
index ebf3a7b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-code=77 # skipped
-for t in "${srcdir}/contrib/pngsuite/"x*".png"
-do
-   if test "$t" != "${srcdir}/contrib/pngsuite/x*.png"
-   then
-      # not skipped, test it
-      if ./pngstest --strict --tmpfile "error" --log "$@" "$t"
-      then
-         code=0 # oops, success: should not happen!
-      fi
-   fi
-done
-exit $code
diff --git a/tests/pngtest-badpngs b/tests/pngtest-badpngs
new file mode 100755 (executable)
index 0000000..7777523
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# various crashers
+# using --relaxed because some come from fuzzers that don't maintain CRC's
+
+./pngtest --relaxed ${srcdir}/contrib/testpngs/crashers/badcrc.png
+./pngtest --relaxed ${srcdir}/contrib/testpngs/crashers/badadler.png
+./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/bad_iCCP.png
+./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/empty_ancillary_chunks.png
+./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/huge_*_chunk.png \
+    ${srcdir}/contrib/testpngs/crashers/huge_*safe_to_copy.png
+
+exec ./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/huge_IDAT.png
index 4317b18..88a1f6b 100755 (executable)
@@ -1,2 +1,2 @@
 #!/bin/sh
-exec ./pngunknown --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save "${srcdir}/pngtest.png"
+exec ./pngunknown --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save eXIf=save "${srcdir}/pngtest.png"
diff --git a/tests/pngvalid-progressive-interlace-size b/tests/pngvalid-progressive-interlace-size
deleted file mode 100755 (executable)
index a31b283..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec ./pngvalid --size --progressive-read
diff --git a/tests/pngvalid-progressive-interlace-transform b/tests/pngvalid-progressive-interlace-transform
deleted file mode 100755 (executable)
index edf9a8a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec ./pngvalid --transform