Browse Source

Update to libpng 1.6.34.
Enabled SSE for x86 and x64.

woollybah 7 years ago
parent
commit
ed86c64d5f
51 changed files with 4615 additions and 472 deletions
  1. 12 20
      libpng.mod/ANNOUNCE
  2. 270 3
      libpng.mod/CHANGES
  3. 162 52
      libpng.mod/CMakeLists.txt
  4. 61 10
      libpng.mod/INSTALL
  5. 6 3
      libpng.mod/LICENSE
  6. 11 0
      libpng.mod/Makefile.am
  7. 67 12
      libpng.mod/Makefile.in
  8. 11 7
      libpng.mod/README
  9. 1 0
      libpng.mod/TODO
  10. 3 3
      libpng.mod/arm/filter_neon.S
  11. 12 0
      libpng.mod/config.h.in
  12. 198 12
      libpng.mod/configure
  13. 135 3
      libpng.mod/configure.ac
  14. 1 1
      libpng.mod/contrib/arm-neon/android-ndk.c
  15. 7 7
      libpng.mod/contrib/arm-neon/linux.c
  16. 83 0
      libpng.mod/contrib/mips-msa/README
  17. 64 0
      libpng.mod/contrib/mips-msa/linux.c
  18. 81 0
      libpng.mod/contrib/powerpc-vsx/README
  19. 57 0
      libpng.mod/contrib/powerpc-vsx/linux.c
  20. 36 0
      libpng.mod/contrib/powerpc-vsx/linux_aux.c
  21. 7 2
      libpng.mod/example.c
  22. 406 0
      libpng.mod/intel/filter_sse2_intrinsics.c
  23. 53 0
      libpng.mod/intel/intel_init.c
  24. 100 41
      libpng.mod/libpng-manual.txt
  25. 124 54
      libpng.mod/libpng.3
  26. 16 1
      libpng.mod/libpng.bmx
  27. 1 0
      libpng.mod/libpng.pc.in
  28. 4 4
      libpng.mod/libpngpf.3
  29. 807 0
      libpng.mod/mips/filter_msa_intrinsics.c
  30. 129 0
      libpng.mod/mips/mips_init.c
  31. 5 5
      libpng.mod/png.5
  32. 124 44
      libpng.mod/png.c
  33. 43 32
      libpng.mod/png.h
  34. 1 1
      libpng.mod/pngconf.h
  35. 4 4
      libpng.mod/pngerror.c
  36. 31 2
      libpng.mod/pngget.c
  37. 8 0
      libpng.mod/pnginfo.h
  38. 3 2
      libpng.mod/pngpread.c
  39. 132 20
      libpng.mod/pngpriv.h
  40. 30 8
      libpng.mod/pngread.c
  41. 23 18
      libpng.mod/pngrtran.c
  42. 170 47
      libpng.mod/pngrutil.c
  43. 57 6
      libpng.mod/pngset.c
  44. 3 3
      libpng.mod/pngstruct.h
  45. 79 14
      libpng.mod/pngtest.c
  46. BIN
      libpng.mod/pngtest.png
  47. 28 14
      libpng.mod/pngtrans.c
  48. 17 6
      libpng.mod/pngwrite.c
  49. 40 11
      libpng.mod/pngwutil.c
  50. 767 0
      libpng.mod/powerpc/filter_vsx_intrinsics.c
  51. 125 0
      libpng.mod/powerpc/powerpc_init.c

+ 12 - 20
libpng.mod/ANNOUNCE

@@ -1,4 +1,4 @@
-Libpng 1.6.27 - December 29, 2016
+Libpng 1.6.34 - September 29, 2017
 
 
 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 codes.
 
 
@@ -7,32 +7,24 @@ Files available for download:
 Source files with LF line endings (for Unix/Linux) and with a
 Source files with LF line endings (for Unix/Linux) and with a
 "configure" script
 "configure" script
 
 
-   libpng-1.6.27.tar.xz (LZMA-compressed, recommended)
-   libpng-1.6.27.tar.gz
+   libpng-1.6.34.tar.xz (LZMA-compressed, recommended)
+   libpng-1.6.34.tar.gz
 
 
 Source files with CRLF line endings (for Windows), without the
 Source files with CRLF line endings (for Windows), without the
 "configure" script
 "configure" script
 
 
-   lpng1627.7z  (LZMA-compressed, recommended)
-   lpng1627.zip
+   lpng1634.7z  (LZMA-compressed, recommended)
+   lpng1634.zip
 
 
 Other information:
 Other information:
 
 
-   libpng-1.6.27-README.txt
-   libpng-1.6.27-LICENSE.txt
-   libpng-1.6.27-*.asc (armored detached GPG signatures)
-
-Changes since the last public release (1.6.26):
-  Control ADLER32 checking with new PNG_IGNORE_ADLER32 option.
-  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).
-  Fixed a potential null pointer dereference in png_set_text_2() (bug report
-    and patch by Patrick Keshishian).
+   libpng-1.6.34-README.txt
+   libpng-1.6.34-LICENSE.txt
+   libpng-1.6.34-*.asc (armored detached GPG signatures)
+
+Changes since the last public release (1.6.33):
+  Removed contrib/pngsuite/i*.png; some of these were incorrect and caused
+    test failures.
 
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
 (subscription required; visit

+ 270 - 3
libpng.mod/CHANGES

@@ -833,7 +833,7 @@ Version 1.0.7beta11 [May 7, 2000]
   Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
   Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
     which are no longer used.
     which are no longer used.
   Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is
   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.
     is defined.
   Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
   Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
     overrun when old applications fill the info_ptr->text structure directly.
     overrun when old applications fill the info_ptr->text structure directly.
@@ -5761,7 +5761,9 @@ Version 1.6.27beta01 [November 2, 2016]
     if built with zlib-1.2.8.1.
     if built with zlib-1.2.8.1.
 
 
 Version 1.6.27rc01 [December 27, 2016]
 Version 1.6.27rc01 [December 27, 2016]
-  Control ADLER32 checking with new PNG_IGNORE_ADLER32 option.
+  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'
   Removed the use of a macro containing the pre-processor 'defined'
     operator.  It is unclear whether this is valid; a macro that
     operator.  It is unclear whether this is valid; a macro that
     "generates" 'defined' is not permitted, but the use of the word
     "generates" 'defined' is not permitted, but the use of the word
@@ -5772,7 +5774,272 @@ Version 1.6.27rc01 [December 27, 2016]
 
 
 Version 1.6.27 [December 29, 2016]
 Version 1.6.27 [December 29, 2016]
   Fixed a potential null pointer dereference in png_set_text_2() (bug report
   Fixed a potential null pointer dereference in png_set_text_2() (bug report
-    and patch by Patrick Keshishian).
+    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 accomodate
+    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 compatability.
+
+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 these were incorrect and caused
+    test failures.
 
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
 (subscription required; visit

+ 162 - 52
libpng.mod/CMakeLists.txt

@@ -1,6 +1,6 @@
 # CMakeLists.txt
 # CMakeLists.txt
 
 
-# Copyright (C) 2007,2009-2016 Glenn Randers-Pehrson
+# Copyright (C) 2007,2009-2017 Glenn Randers-Pehrson
 # Written by Christian Ehrlicher, 2007
 # Written by Christian Ehrlicher, 2007
 # Revised by Roger Lowman, 2009-2010
 # Revised by Roger Lowman, 2009-2010
 # Revised by Clifford Yapp, 2011-2012
 # Revised by Clifford Yapp, 2011-2012
@@ -11,8 +11,8 @@
 # For conditions of distribution and use, see the disclaimer
 # For conditions of distribution and use, see the disclaimer
 # and license in png.h
 # and license in png.h
 
 
-cmake_minimum_required(VERSION 2.8.3)
-cmake_policy(VERSION 2.8.3)
+cmake_minimum_required(VERSION 3.0.2)
+cmake_policy(VERSION 3.0.2)
 
 
 # Set MacOSX @rpath usage globally.
 # Set MacOSX @rpath usage globally.
 if (POLICY CMP0020)
 if (POLICY CMP0020)
@@ -31,18 +31,27 @@ endif(POLICY CMP0054)
 
 
 set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")
 set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")
 
 
-project(libpng C)
+project(libpng ASM C)
 enable_testing()
 enable_testing()
 
 
 set(PNGLIB_MAJOR 1)
 set(PNGLIB_MAJOR 1)
 set(PNGLIB_MINOR 6)
 set(PNGLIB_MINOR 6)
-set(PNGLIB_RELEASE 27)
+set(PNGLIB_RELEASE 34)
 set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
 set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
 set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
 set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
 
 
+include(GNUInstallDirs)
+
 # needed packages
 # needed packages
-find_package(ZLIB REQUIRED)
-include_directories(${ZLIB_INCLUDE_DIR})
+
+#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(NOT PNG_BUILD_ZLIB)
 
 
 if(NOT WIN32)
 if(NOT WIN32)
   find_library(M_LIBRARY
   find_library(M_LIBRARY
@@ -67,11 +76,16 @@ option(PNG_FRAMEWORK "Build OS X framework" OFF)
 option(PNG_DEBUG     "Build with debug output" OFF)
 option(PNG_DEBUG     "Build with debug output" OFF)
 option(PNGARG        "Disable ANSI-C prototypes" OFF)
 option(PNGARG        "Disable ANSI-C prototypes" OFF)
 
 
+option(PNG_HARDWARE_OPTIMIZATIONS "Enable Hardware Optimizations" ON)
+
+
 set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names")
 set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names")
 set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings")
 set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings")
 
 
+if(PNG_HARDWARE_OPTIMIZATIONS)
 # set definitions and sources for arm
 # set definitions and sources for arm
-if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^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_POSSIBLE_VALUES check on off)
   set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations:
   set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations:
      check: (default) use internal checking code;
      check: (default) use internal checking code;
@@ -88,7 +102,7 @@ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm")
       arm/arm_init.c
       arm/arm_init.c
       arm/filter_neon.S
       arm/filter_neon.S
       arm/filter_neon_intrinsics.c)
       arm/filter_neon_intrinsics.c)
-      
+
     if(${PNG_ARM_NEON} STREQUAL "on")
     if(${PNG_ARM_NEON} STREQUAL "on")
       add_definitions(-DPNG_ARM_NEON_OPT=2)
       add_definitions(-DPNG_ARM_NEON_OPT=2)
     elseif(${PNG_ARM_NEON} STREQUAL "check")
     elseif(${PNG_ARM_NEON} STREQUAL "check")
@@ -99,6 +113,79 @@ if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm")
   endif()
   endif()
 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 "no")
+    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 "no")
+    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 "no")
+    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()
+endif(PNG_HARDWARE_OPTIMIZATIONS)
+
 # SET LIBNAME
 # SET LIBNAME
 set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
 set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
 
 
@@ -175,7 +262,7 @@ find_program(AWK NAMES gawk awk)
 
 
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 
-if(NOT AWK)
+if(NOT AWK OR ANDROID)
   # No awk available to generate sources; use pre-built pnglibconf.h
   # No awk available to generate sources; use pre-built pnglibconf.h
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
                  ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
                  ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
@@ -354,7 +441,7 @@ else()
     "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
     "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
     "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
     "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
     "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
     "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
-endif(NOT AWK)
+endif(NOT AWK OR ANDROID)
 
 
 # OUR SOURCES
 # OUR SOURCES
 set(libpng_public_hdrs
 set(libpng_public_hdrs
@@ -368,7 +455,7 @@ set(libpng_private_hdrs
   pnginfo.h
   pnginfo.h
   pngstruct.h
   pngstruct.h
 )
 )
-if(AWK)
+if(AWK AND NOT ANDROID)
   list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
   list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
 endif()
 endif()
 set(libpng_sources
 set(libpng_sources
@@ -390,6 +477,9 @@ set(libpng_sources
   pngwtran.c
   pngwtran.c
   pngwutil.c
   pngwutil.c
   ${libpng_arm_sources}
   ${libpng_arm_sources}
+  ${libpng_intel_sources}
+  ${libpng_mips_sources}
+  ${libpng_powerpc_sources}
 )
 )
 set(pngtest_sources
 set(pngtest_sources
   pngtest.c
   pngtest.c
@@ -665,31 +755,58 @@ if(PNG_SHARED)
   list(APPEND PNG_BIN_TARGETS png-fix-itxt)
   list(APPEND PNG_BIN_TARGETS png-fix-itxt)
 endif()
 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)
-
 # Set a variable with CMake code which:
 # Set a variable with CMake code which:
 # Creates a symlink from src to dest (if possible) or alternatively
 # Creates a symlink from src to dest (if possible) or alternatively
 # copies if different.
 # 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 "Specify either a TARGET or a FILE for CREATE_SYMLINK to link to.")
+  endif(NOT S_TARGET AND NOT S_FILE)
+
+  if(S_TARGET AND S_FILE)
+    message(FATAL_ERROR "CREATE_SYMLINK called with both source file ${S_FILE} and build target ${S_TARGET} arguments - can only handle 1 type per call.")
+  endif(S_TARGET AND S_FILE)
+
+  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 AND NOT MSYS)
+      execute_process(
+	COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${S_FILE} ${DEST_FILE}
+	WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+	)
+    else(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+      execute_process(
+	COMMAND ${CMAKE_COMMAND} -E create_symlink ${S_FILE} ${DEST_FILE}
+	WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+	)
+    endif(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+  endif(S_FILE)
+
+  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 AND NOT MSYS)
+      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(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+      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(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+
+  endif(S_TARGET)
+
+endfunction()
 
 
 # Create source generation scripts.
 # Create source generation scripts.
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in
@@ -717,17 +834,17 @@ if(NOT WIN32 OR CYGWIN OR MINGW)
   set(LIBS        "-lz -lm")
   set(LIBS        "-lz -lm")
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
     ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY)
     ${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
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in
     ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)
     ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)
-  CREATE_SYMLINK(${PNGLIB_NAME}-config libpng-config)
+  CREATE_SYMLINK(libpng-config FILE ${PNGLIB_NAME}-config)
 endif(NOT WIN32 OR CYGWIN OR MINGW)
 endif(NOT WIN32 OR CYGWIN OR MINGW)
 
 
 # SET UP LINKS
 # SET UP LINKS
 if(PNG_SHARED)
 if(PNG_SHARED)
   set_target_properties(png PROPERTIES
   set_target_properties(png PROPERTIES
-#   VERSION 16.${PNGLIB_RELEASE}.1.6.27
+#   VERSION 16.${PNGLIB_RELEASE}.1.6.34
     VERSION 16.${PNGLIB_RELEASE}.0
     VERSION 16.${PNGLIB_RELEASE}.0
     SOVERSION 16
     SOVERSION 16
     CLEAN_DIRECT_OUTPUT 1)
     CLEAN_DIRECT_OUTPUT 1)
@@ -754,26 +871,20 @@ if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
   if(PNG_SHARED)
   if(PNG_SHARED)
     # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
     # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
     if(CYGWIN OR MINGW)
     if(CYGWIN OR MINGW)
-       get_target_property(BUILD_TARGET_LOCATION png 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})
+      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(CYGWIN OR MINGW)
     endif(CYGWIN OR MINGW)
 
 
     if(NOT WIN32)
     if(NOT WIN32)
-      get_target_property(BUILD_TARGET_LOCATION png 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})
+      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(NOT WIN32)
     endif(NOT WIN32)
   endif(PNG_SHARED)
   endif(PNG_SHARED)
 
 
   if(PNG_STATIC)
   if(PNG_STATIC)
     if(NOT WIN32 OR CYGWIN OR MINGW)
     if(NOT WIN32 OR CYGWIN OR MINGW)
-      get_target_property(BUILD_TARGET_LOCATION png_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})
+      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(NOT WIN32 OR CYGWIN OR MINGW)
     endif(NOT WIN32 OR CYGWIN OR MINGW)
  endif()
  endif()
 endif()
 endif()
@@ -803,7 +914,7 @@ if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
   install(FILES libpng.3 libpngpf.3      DESTINATION ${PNG_MAN_DIR}/man3)
   install(FILES libpng.3 libpngpf.3      DESTINATION ${PNG_MAN_DIR}/man3)
   install(FILES png.5                    DESTINATION ${PNG_MAN_DIR}/man5)
   install(FILES png.5                    DESTINATION ${PNG_MAN_DIR}/man5)
   # Install pkg-config files
   # 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
     install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
             DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
             DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
     install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
     install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
@@ -812,7 +923,7 @@ if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
             DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
             DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
     install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
     install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
             DESTINATION bin)
             DESTINATION bin)
-  endif(NOT WIN32 OR CYGWIN OR MINGW)
+  endif(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
 endif()
 endif()
 
 
 # On versions of CMake that support it, create an export file CMake
 # On versions of CMake that support it, create an export file CMake
@@ -832,4 +943,3 @@ endif()
 # to create msvc import lib for mingw compiled shared lib
 # to create msvc import lib for mingw compiled shared lib
 # pexports libpng.dll > libpng.def
 # pexports libpng.dll > libpng.def
 # lib /def:libpng.def /machine:x86
 # lib /def:libpng.def /machine:x86
-

+ 61 - 10
libpng.mod/INSTALL

@@ -16,10 +16,11 @@ Contents
       XI. Prepending a prefix to exported symbols
       XI. Prepending a prefix to exported symbols
      XII. Configuring for compiler xxx:
      XII. Configuring for compiler xxx:
     XIII. Removing unwanted object code
     XIII. Removing unwanted object code
-     XIV. Changes to the build and configuration of libpng in libpng-1.5.x
-      XV. Setjmp/longjmp issues
-     XVI. Common linking failures
-    XVII. Other sources of information about libpng
+     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
 I. Simple installation
 
 
@@ -78,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
 Before installing libpng, you must first install zlib, if it
 is not already on your system.  zlib can usually be found
 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 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
 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
 to have access to the zlib.h and zconf.h include files that
@@ -281,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
 The size of the library itself should not be an issue, because only
 those sections that are actually used will be loaded into memory.
 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 capabilites, 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
 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
 file and in the GIT repository logs.  These will be of no concern to the vast
@@ -372,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
 libpng, because than the settings would not accurately reflect the settings
 that were used to build libpng.
 that were used to build libpng.
 
 
-XV. Setjmp/longjmp issues
+XVI. Setjmp/longjmp issues
 
 
 Libpng uses setjmp()/longjmp() for error handling.  Unfortunately setjmp()
 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
 is known to be not thread-safe on some platforms and we don't know of
@@ -390,7 +441,7 @@ This requires setjmp/longjmp, so you must either build the library
 with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED
 with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED
 and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined.
 and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined.
 
 
-XVI. Common linking failures
+XVII. Common linking failures
 
 
 If your application fails to find libpng or zlib entries while linking:
 If your application fails to find libpng or zlib entries while linking:
 
 
@@ -402,7 +453,7 @@ If your application fails to find libpng or zlib entries while linking:
   If you are using the vstudio project, observe the WARNING in
   If you are using the vstudio project, observe the WARNING in
   project/vstudio/README.txt.
   project/vstudio/README.txt.
 
 
-XVII. Other sources of information about libpng:
+XVIII. Other sources of information about libpng:
 
 
 Further information can be found in the README and libpng-manual.txt
 Further information can be found in the README and libpng-manual.txt
 files, in the individual makefiles, in png.h, and the manual pages
 files, in the individual makefiles, in png.h, and the manual pages

+ 6 - 3
libpng.mod/LICENSE

@@ -10,8 +10,8 @@ this sentence.
 
 
 This code is released under the libpng license.
 This code is released under the libpng license.
 
 
-libpng versions 1.0.7, July 1, 2000 through 1.6.27, December 29, 2016 are
-Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
 derived from libpng-1.0.6, and are distributed according to the same
 derived from libpng-1.0.6, and are distributed according to the same
 disclaimer and license as libpng-1.0.6 with the following individuals
 disclaimer and license as libpng-1.0.6 with the following individuals
 added to the list of Contributing Authors:
 added to the list of Contributing Authors:
@@ -22,6 +22,9 @@ added to the list of Contributing Authors:
    Cosmin Truta
    Cosmin Truta
    Gilles Vollant
    Gilles Vollant
    James Yu
    James Yu
+   Mandar Sahastrabuddhe
+   Google Inc.
+   Vadim Barkov
 
 
 and with the following additions to the disclaimer:
 and with the following additions to the disclaimer:
 
 
@@ -127,4 +130,4 @@ any encryption software.  See the EAR, paragraphs 734.3(b)(3) and
 
 
 Glenn Randers-Pehrson
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
 glennrp at users.sourceforge.net
-December 29, 2016
+September 29, 2017

+ 11 - 0
libpng.mod/Makefile.am

@@ -60,6 +60,7 @@ pngcp_LDADD = libpng@PNGLIB_MAJOR@@[email protected]
 # set of parameters:
 # set of parameters:
 TESTS =\
 TESTS =\
    tests/pngtest\
    tests/pngtest\
+   tests/pngtest-badpngs\
    tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\
    tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\
    tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\
    tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\
    tests/pngvalid-gamma-expand16-background\
    tests/pngvalid-gamma-expand16-background\
@@ -102,6 +103,16 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += mips/mips_init.c\
 	mips/filter_msa_intrinsics.c
 	mips/filter_msa_intrinsics.c
 endif
 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
 nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h
 
 
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined -export-dynamic \
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined -export-dynamic \

+ 67 - 12
libpng.mod/Makefile.in

@@ -17,7 +17,7 @@
 # Makefile.am, the source file for Makefile.in (and hence Makefile), is
 # Makefile.am, the source file for Makefile.in (and hence Makefile), is
 #
 #
 # Copyright (c) 2004-2016 Glenn Randers-Pehrson
 # Copyright (c) 2004-2016 Glenn Randers-Pehrson
-# Last changed in libpng 1.6.25beta03 [August 29, 2016]
+# Last changed in libpng 1.6.25 [September 1, 2016]
 #
 #
 # This code is released under the libpng license.
 # This code is released under the libpng license.
 # For conditions of distribution and use, see the disclaimer
 # For conditions of distribution and use, see the disclaimer
@@ -111,13 +111,19 @@ bin_PROGRAMS = pngfix$(EXEEXT) png-fix-itxt$(EXEEXT)
 @PNG_MIPS_MSA_TRUE@am__append_3 = mips/mips_init.c\
 @PNG_MIPS_MSA_TRUE@am__append_3 = mips/mips_init.c\
 @PNG_MIPS_MSA_TRUE@	mips/filter_msa_intrinsics.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
 #   Versioned symbols and restricted exports
-@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_TRUE@am__append_4 = -Wl,-M -Wl,libpng.vers
-@HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_FALSE@am__append_5 = -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
 #   Only restricted exports when possible
-@HAVE_LD_VERSION_SCRIPT_FALSE@am__append_6 = -export-symbols libpng.sym
-@DO_PNG_PREFIX_TRUE@am__append_7 = -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 = .
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/scripts/libtool.m4 \
 am__aclocal_m4_deps = $(top_srcdir)/scripts/libtool.m4 \
@@ -175,17 +181,23 @@ am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST = png.c \
 	pngwtran.c pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h \
 	pngwtran.c pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h \
 	pngpriv.h pngstruct.h pngusr.dfa arm/arm_init.c \
 	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 \
-	mips/mips_init.c mips/filter_msa_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
 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@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_MIPS_MSA_TRUE@am__objects_2 = mips/mips_init.lo \
 @PNG_MIPS_MSA_TRUE@am__objects_2 = mips/mips_init.lo \
 @PNG_MIPS_MSA_TRUE@	mips/filter_msa_intrinsics.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 \
 am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = png.lo pngerror.lo \
 	pngget.lo pngmem.lo pngpread.lo pngread.lo pngrio.lo \
 	pngget.lo pngmem.lo pngpread.lo pngread.lo pngrio.lo \
 	pngrtran.lo pngrutil.lo pngset.lo pngtrans.lo pngwio.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_2) $(am__objects_3) $(am__objects_4)
 nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS =
 nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS =
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS =  \
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS =  \
 	$(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) \
 	$(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) \
@@ -697,6 +709,7 @@ pngcp_LDADD = libpng@PNGLIB_MAJOR@@[email protected]
 # set of parameters:
 # set of parameters:
 TESTS = \
 TESTS = \
    tests/pngtest\
    tests/pngtest\
+   tests/pngtest-badpngs\
    tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\
    tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\
    tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\
    tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\
    tests/pngvalid-gamma-expand16-background\
    tests/pngvalid-gamma-expand16-background\
@@ -726,12 +739,13 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c \
 	pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.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 \
 	pngrutil.c pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c \
 	pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h \
 	pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h \
-	pngstruct.h pngusr.dfa $(am__append_2) $(am__append_3)
+	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
 nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined \
 libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined \
 	-export-dynamic -version-number \
 	-export-dynamic -version-number \
 	@PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0 \
 	@PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0 \
-	$(am__append_4) $(am__append_5) $(am__append_6)
+	$(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_FALSE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.sym
 @HAVE_LD_VERSION_SCRIPT_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.vers
 @HAVE_LD_VERSION_SCRIPT_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.vers
 pkginclude_HEADERS = png.h pngconf.h
 pkginclude_HEADERS = png.h pngconf.h
@@ -767,7 +781,7 @@ SUFFIXES = .chk .out
 SYMBOL_CFLAGS = -DPNGLIB_LIBNAME='PNG@PNGLIB_MAJOR@@PNGLIB_MINOR@_0' \
 SYMBOL_CFLAGS = -DPNGLIB_LIBNAME='PNG@PNGLIB_MAJOR@@PNGLIB_MINOR@_0' \
 	-DPNGLIB_VERSION='@PNGLIB_VERSION@' \
 	-DPNGLIB_VERSION='@PNGLIB_VERSION@' \
 	-DSYMBOL_PREFIX='$(SYMBOL_PREFIX)' -DPNG_NO_USE_READ_MACROS \
 	-DSYMBOL_PREFIX='$(SYMBOL_PREFIX)' -DPNG_NO_USE_READ_MACROS \
-	-DPNG_BUILDING_SYMBOL_TABLE $(am__append_7)
+	-DPNG_BUILDING_SYMBOL_TABLE $(am__append_9)
 
 
 # EXT_LIST is a list of the possibly library directory extensions, this exists
 # 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
 # because we can't find a good way of discovering the file extensions that are
@@ -885,6 +899,26 @@ mips/$(DEPDIR)/$(am__dirstamp):
 mips/mips_init.lo: mips/$(am__dirstamp) mips/$(DEPDIR)/$(am__dirstamp)
 mips/mips_init.lo: mips/$(am__dirstamp) mips/$(DEPDIR)/$(am__dirstamp)
 mips/filter_msa_intrinsics.lo: mips/$(am__dirstamp) \
 mips/filter_msa_intrinsics.lo: mips/$(am__dirstamp) \
 	mips/$(DEPDIR)/$(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@@[email protected]: $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) $(EXTRA_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) 
 libpng@PNGLIB_MAJOR@@[email protected]: $(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)
 	$(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)
@@ -1053,8 +1087,12 @@ mostlyclean-compile:
 	-rm -f arm/*.lo
 	-rm -f arm/*.lo
 	-rm -f contrib/libtests/*.$(OBJEXT)
 	-rm -f contrib/libtests/*.$(OBJEXT)
 	-rm -f contrib/tools/*.$(OBJEXT)
 	-rm -f contrib/tools/*.$(OBJEXT)
+	-rm -f intel/*.$(OBJEXT)
+	-rm -f intel/*.lo
 	-rm -f mips/*.$(OBJEXT)
 	-rm -f mips/*.$(OBJEXT)
 	-rm -f mips/*.lo
 	-rm -f mips/*.lo
+	-rm -f powerpc/*.$(OBJEXT)
+	-rm -f powerpc/*.lo
 
 
 distclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 	-rm -f *.tab.c
@@ -1086,8 +1124,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/png-fix-itxt.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)/pngcp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngcp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngfix.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngfix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/filter_sse2_intrinsics.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/intel_init.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/filter_msa_intrinsics.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/filter_msa_intrinsics.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/mips_init.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/mips_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/powerpc_init.Plo@am__quote@
 
 
 .S.o:
 .S.o:
 @am__fastdepCCAS_TRUE@	$(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
 @am__fastdepCCAS_TRUE@	$(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -1143,7 +1185,9 @@ mostlyclean-libtool:
 clean-libtool:
 clean-libtool:
 	-rm -rf .libs _libs
 	-rm -rf .libs _libs
 	-rm -rf arm/.libs arm/_libs
 	-rm -rf arm/.libs arm/_libs
+	-rm -rf intel/.libs intel/_libs
 	-rm -rf mips/.libs mips/_libs
 	-rm -rf mips/.libs mips/_libs
+	-rm -rf powerpc/.libs powerpc/_libs
 
 
 distclean-libtool:
 distclean-libtool:
 	-rm -f libtool config.lt
 	-rm -f libtool config.lt
@@ -1504,6 +1548,13 @@ tests/pngtest.log: tests/pngtest
 	--log-file $$b.log --trs-file $$b.trs \
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
 	"$$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
 tests/pngvalid-gamma-16-to-8.log: tests/pngvalid-gamma-16-to-8
 	@p='tests/pngvalid-gamma-16-to-8'; \
 	@p='tests/pngvalid-gamma-16-to-8'; \
 	b='tests/pngvalid-gamma-16-to-8'; \
 	b='tests/pngvalid-gamma-16-to-8'; \
@@ -1951,8 +2002,12 @@ distclean-generic:
 	-rm -f contrib/libtests/$(am__dirstamp)
 	-rm -f contrib/libtests/$(am__dirstamp)
 	-rm -f contrib/tools/$(DEPDIR)/$(am__dirstamp)
 	-rm -f contrib/tools/$(DEPDIR)/$(am__dirstamp)
 	-rm -f contrib/tools/$(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/$(DEPDIR)/$(am__dirstamp)
 	-rm -f mips/$(am__dirstamp)
 	-rm -f mips/$(am__dirstamp)
+	-rm -f powerpc/$(DEPDIR)/$(am__dirstamp)
+	-rm -f powerpc/$(am__dirstamp)
 
 
 maintainer-clean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "This command is intended for maintainers to use"
@@ -1969,7 +2024,7 @@ clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
 
 
 distclean: distclean-am
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) mips/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) intel/$(DEPDIR) mips/$(DEPDIR) powerpc/$(DEPDIR)
 	-rm -f Makefile
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-libtool distclean-tags
 	distclean-hdr distclean-libtool distclean-tags
@@ -2021,7 +2076,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-am
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) mips/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) arm/$(DEPDIR) contrib/libtests/$(DEPDIR) contrib/tools/$(DEPDIR) intel/$(DEPDIR) mips/$(DEPDIR) powerpc/$(DEPDIR)
 	-rm -f Makefile
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
 

+ 11 - 7
libpng.mod/README

@@ -1,4 +1,4 @@
-README for libpng version 1.6.27 - December 29, 2016 (shared library 16.0)
+README for libpng version 1.6.34 - September 29, 2017 (shared library 16.0)
 See the note about version numbers near the top of png.h
 See the note about version numbers near the top of png.h
 
 
 See INSTALL for instructions on how to install libpng.
 See INSTALL for instructions on how to install libpng.
@@ -23,7 +23,7 @@ earlier versions if you are using a shared library.  The type of the
 png_uint_32, which will affect shared-library applications that use
 png_uint_32, which will affect shared-library applications that use
 this function.
 this function.
 
 
-To avoid problems with changes to the internals of png info_struct,
+To avoid problems with changes to the internals of the png info_struct,
 new APIs have been made available in 0.95 to avoid direct application
 new APIs have been made available in 0.95 to avoid direct application
 access to info_ptr.  These functions are the png_set_<chunk> and
 access to info_ptr.  These functions are the png_set_<chunk> and
 png_get_<chunk> functions.  These functions should be used when
 png_get_<chunk> functions.  These functions should be used when
@@ -88,11 +88,11 @@ zlib should be available at the same place that libpng is, or at zlib.net.
 
 
 You may also want a copy of the PNG specification.  It is available
 You may also want a copy of the PNG specification.  It is available
 as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
 as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
-these at http://www.libpng.org/pub/png/documents/
+these at http://www.libpng.org/pub/png/pngdocs.html .
 
 
-This code is currently being archived at libpng.sf.net in the
-[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.
+This code is currently being archived at libpng.sourceforge.io in the
+[DOWNLOAD] area, and at http://libpng.download/src .  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
 I am not a lawyer, but I believe that the Export Control Classification
 Number (ECCN) for libpng is EAR99, which means not subject to export
 Number (ECCN) for libpng is EAR99, which means not subject to export
@@ -179,14 +179,16 @@ Files in this distribution:
       pngwtran.c    =>  Write data transformations
       pngwtran.c    =>  Write data transformations
       pngwutil.c    =>  Write utility functions
       pngwutil.c    =>  Write utility functions
       arm           =>  Contains optimized code for the ARM platform
       arm           =>  Contains optimized code for the ARM platform
+      powerpc       =>  Contains optimized code for the PowerPC platform
       contrib       =>  Contributions
       contrib       =>  Contributions
        arm-neon         =>  Optimized code for ARM-NEON platform
        arm-neon         =>  Optimized code for ARM-NEON platform
+       powerpc-vsx      =>  Optimized code for POWERPC-VSX platform
        examples         =>  Example programs
        examples         =>  Example programs
        gregbook         =>  source code for PNG reading and writing, from
        gregbook         =>  source code for PNG reading and writing, from
                             Greg Roelofs' "PNG: The Definitive Guide",
                             Greg Roelofs' "PNG: The Definitive Guide",
                             O'Reilly, 1999
                             O'Reilly, 1999
-       intel            =>  Optimized code for INTEL-SSE2 platform
        libtests         =>  Test programs
        libtests         =>  Test programs
+       mips-msa         =>  Optimized code for MIPS-MSA platform
        pngminim         =>  Minimal decoder, encoder, and progressive decoder
        pngminim         =>  Minimal decoder, encoder, and progressive decoder
                             programs demonstrating use of pngusr.dfa
                             programs demonstrating use of pngusr.dfa
        pngminus         =>  Simple pnm2png and png2pnm programs
        pngminus         =>  Simple pnm2png and png2pnm programs
@@ -194,6 +196,8 @@ Files in this distribution:
        testpngs
        testpngs
        tools            =>  Various tools
        tools            =>  Various tools
        visupng          =>  Contains a MSVC workspace for VisualPng
        visupng          =>  Contains a MSVC workspace for VisualPng
+      intel             =>  Optimized code for INTEL-SSE2 platform
+      mips              =>  Optimized code for MIPS platform
       projects      =>  Contains project files and workspaces for
       projects      =>  Contains project files and workspaces for
                         building a DLL
                         building a DLL
        owatcom          =>  Contains a WATCOM project for building libpng
        owatcom          =>  Contains a WATCOM project for building libpng

+ 1 - 0
libpng.mod/TODO

@@ -25,5 +25,6 @@ Use greater precision when changing to linear gamma for compositing against
 Investigate pre-incremented loop counters and other loop constructions.
 Investigate pre-incremented loop counters and other loop constructions.
 Add interpolated method of handling interlacing.
 Add interpolated method of handling interlacing.
 Extend pngvalid.c to validate more of the libpng transformations.
 Extend pngvalid.c to validate more of the libpng transformations.
+Refactor preprocessor conditionals to compile entire statements
 
 
 */
 */

+ 3 - 3
libpng.mod/arm/filter_neon.S

@@ -1,9 +1,9 @@
 
 
 /* filter_neon.S - NEON optimised filter functions
 /* filter_neon.S - NEON optimised filter functions
  *
  *
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Copyright (c) 2014,2017 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.16 [December 22, 2014]
+ * Last changed in libpng 1.6.31 [July 27, 2017]
  *
  *
  * This code is released under the libpng license.
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * For conditions of distribution and use, see the disclaimer
@@ -16,7 +16,7 @@
 #define PNG_VERSION_INFO_ONLY
 #define PNG_VERSION_INFO_ONLY
 #include "../pngpriv.h"
 #include "../pngpriv.h"
 
 
-#if defined(__linux__) && defined(__ELF__)
+#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
 #endif
 #endif
 
 

+ 12 - 0
libpng.mod/config.h.in

@@ -78,6 +78,9 @@
 /* Enable ARM Neon optimizations */
 /* Enable ARM Neon optimizations */
 #undef PNG_ARM_NEON_OPT
 #undef PNG_ARM_NEON_OPT
 
 
+/* Enable Intel SSE optimizations */
+#undef PNG_INTEL_SSE_OPT
+
 /* Turn on MIPS MSA optimizations at run-time */
 /* Turn on MIPS MSA optimizations at run-time */
 #undef PNG_MIPS_MSA_API_SUPPORTED
 #undef PNG_MIPS_MSA_API_SUPPORTED
 
 
@@ -87,6 +90,15 @@
 /* Enable MIPS MSA optimizations */
 /* Enable MIPS MSA optimizations */
 #undef PNG_MIPS_MSA_OPT
 #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. */
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 #undef STDC_HEADERS
 
 

+ 198 - 12
libpng.mod/configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libpng 1.6.27.
+# Generated by GNU Autoconf 2.69 for libpng 1.6.34.
 #
 #
 # Report bugs to <[email protected]>.
 # Report bugs to <[email protected]>.
 #
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 # Identity of this package.
 PACKAGE_NAME='libpng'
 PACKAGE_NAME='libpng'
 PACKAGE_TARNAME='libpng'
 PACKAGE_TARNAME='libpng'
-PACKAGE_VERSION='1.6.27'
-PACKAGE_STRING='libpng 1.6.27'
+PACKAGE_VERSION='1.6.34'
+PACKAGE_STRING='libpng 1.6.34'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 PACKAGE_URL=''
 
 
@@ -635,6 +635,10 @@ ac_includes_default="\
 ac_subst_vars='am__EXEEXT_FALSE
 ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LTLIBOBJS
+PNG_POWERPC_VSX_FALSE
+PNG_POWERPC_VSX_TRUE
+PNG_INTEL_SSE_FALSE
+PNG_INTEL_SSE_TRUE
 PNG_MIPS_MSA_FALSE
 PNG_MIPS_MSA_FALSE
 PNG_MIPS_MSA_TRUE
 PNG_MIPS_MSA_TRUE
 PNG_ARM_NEON_FALSE
 PNG_ARM_NEON_FALSE
@@ -809,8 +813,11 @@ with_libpng_prefix
 enable_unversioned_links
 enable_unversioned_links
 enable_unversioned_libpng_pc
 enable_unversioned_libpng_pc
 enable_unversioned_libpng_config
 enable_unversioned_libpng_config
+enable_hardware_optimizations
 enable_arm_neon
 enable_arm_neon
 enable_mips_msa
 enable_mips_msa
+enable_intel_sse
+enable_powerpc_vsx
 '
 '
       ac_precious_vars='build_alias
       ac_precious_vars='build_alias
 host_alias
 host_alias
@@ -1365,7 +1372,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # 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.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
   cat <<_ACEOF
-\`configure' configures libpng 1.6.27 to adapt to many kinds of systems.
+\`configure' configures libpng 1.6.34 to adapt to many kinds of systems.
 
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 
@@ -1435,7 +1442,7 @@ fi
 
 
 if test -n "$ac_init_help"; then
 if test -n "$ac_init_help"; then
   case $ac_init_help in
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libpng 1.6.27:";;
+     short | recursive ) echo "Configuration of libpng 1.6.34:";;
    esac
    esac
   cat <<\_ACEOF
   cat <<\_ACEOF
 
 
@@ -1487,6 +1494,8 @@ Optional Features:
                           link to the versioned version. This is done by
                           link to the versioned version. This is done by
                           default - use --disable-unversioned-libpng-config to
                           default - use --disable-unversioned-libpng-config to
                           change this.
                           change this.
+  --enable-hardware-optimizations
+                          Enable hardware optimizations: =no/off, yes/on:
   --enable-arm-neon     Enable ARM NEON optimizations: =no/off, check, api,
   --enable-arm-neon     Enable ARM NEON optimizations: =no/off, check, api,
                           yes/on: no/off: disable the optimizations; check:
                           yes/on: no/off: disable the optimizations; check:
                           use internal checking code (deprecated and poorly
                           use internal checking code (deprecated and poorly
@@ -1501,6 +1510,16 @@ Optional Features:
                           call to png_set_option; yes/on: turn on
                           call to png_set_option; yes/on: turn on
                           unconditionally. If not specified: determined by the
                           unconditionally. If not specified: determined by the
                           compiler.
                           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:
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1603,7 +1622,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
 if $ac_init_version; then
   cat <<\_ACEOF
   cat <<\_ACEOF
-libpng configure 1.6.27
+libpng configure 1.6.34
 generated by GNU Autoconf 2.69
 generated by GNU Autoconf 2.69
 
 
 Copyright (C) 2012 Free Software Foundation, Inc.
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1935,7 +1954,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 running configure, to aid debugging if configure makes a mistake.
 
 
-It was created by libpng $as_me 1.6.27, which was
+It was created by libpng $as_me 1.6.34, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
 
   $ $0 $@
   $ $0 $@
@@ -2806,7 +2825,7 @@ fi
 
 
 # Define the identity of the package.
 # Define the identity of the package.
  PACKAGE='libpng'
  PACKAGE='libpng'
- VERSION='1.6.27'
+ VERSION='1.6.34'
 
 
 
 
 cat >>confdefs.h <<_ACEOF
 cat >>confdefs.h <<_ACEOF
@@ -2927,10 +2946,10 @@ fi
 
 
 
 
 
 
-PNGLIB_VERSION=1.6.27
+PNGLIB_VERSION=1.6.34
 PNGLIB_MAJOR=1
 PNGLIB_MAJOR=1
 PNGLIB_MINOR=6
 PNGLIB_MINOR=6
-PNGLIB_RELEASE=27
+PNGLIB_RELEASE=34
 
 
 
 
 
 
@@ -13487,6 +13506,64 @@ fi
 # HOST SPECIFIC OPTIONS
 # 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
 # ARM
 # ===
 # ===
 #
 #
@@ -13598,6 +13675,107 @@ else
 fi
 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:${as_lineno-$LINENO}: Extra options for compiler: $PNG_COPTS" >&5
 $as_echo "$as_me: Extra options for compiler: $PNG_COPTS" >&6;}
 $as_echo "$as_me: Extra options for compiler: $PNG_COPTS" >&6;}
 
 
@@ -13784,6 +13962,14 @@ if test -z "${PNG_MIPS_MSA_TRUE}" && test -z "${PNG_MIPS_MSA_FALSE}"; then
   as_fn_error $? "conditional \"PNG_MIPS_MSA\" was never defined.
   as_fn_error $? "conditional \"PNG_MIPS_MSA\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 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}"
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
 ac_write_fail=0
@@ -14181,7 +14367,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 # values after options handling.
 ac_log="
 ac_log="
-This file was extended by libpng $as_me 1.6.27, which was
+This file was extended by libpng $as_me 1.6.34, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_FILES    = $CONFIG_FILES
@@ -14247,7 +14433,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 ac_cs_version="\\
-libpng config.status 1.6.27
+libpng config.status 1.6.34
 configured by $0, generated by GNU Autoconf 2.69,
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
   with options \\"\$ac_cs_config\\"
 
 

+ 135 - 3
libpng.mod/configure.ac

@@ -25,7 +25,7 @@ AC_PREREQ([2.68])
 
 
 dnl Version number stuff here:
 dnl Version number stuff here:
 
 
-AC_INIT([libpng],[1.6.27],[[email protected]])
+AC_INIT([libpng],[1.6.34],[[email protected]])
 AC_CONFIG_MACRO_DIR([scripts])
 AC_CONFIG_MACRO_DIR([scripts])
 
 
 # libpng does not follow GNU file name conventions (hence 'foreign')
 # libpng does not follow GNU file name conventions (hence 'foreign')
@@ -46,10 +46,10 @@ dnl automake, so the following is not necessary (and is not defined anyway):
 dnl AM_PREREQ([1.11.2])
 dnl AM_PREREQ([1.11.2])
 dnl stop configure from automagically running automake
 dnl stop configure from automagically running automake
 
 
-PNGLIB_VERSION=1.6.27
+PNGLIB_VERSION=1.6.34
 PNGLIB_MAJOR=1
 PNGLIB_MAJOR=1
 PNGLIB_MINOR=6
 PNGLIB_MINOR=6
-PNGLIB_RELEASE=27
+PNGLIB_RELEASE=34
 
 
 dnl End of version number stuff
 dnl End of version number stuff
 
 
@@ -300,6 +300,55 @@ AM_CONDITIONAL([DO_INSTALL_LIBPNG_CONFIG],
 # HOST SPECIFIC OPTIONS
 # 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
 # ARM
 # ===
 # ===
 #
 #
@@ -391,6 +440,89 @@ AM_CONDITIONAL([PNG_MIPS_MSA],
       mipsel*|mips64el*) :;;
       mipsel*|mips64el*) :;;
     esac])
     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]])
 AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]])
 
 
 # Config files, substituting as above
 # Config files, substituting as above

+ 1 - 1
libpng.mod/contrib/arm-neon/android-ndk.c

@@ -17,7 +17,7 @@
  *
  *
  * Documentation:
  * Documentation:
  *    http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
  *    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
  * 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
  * with an implementation of the Android ARM 'cpu-features' library.  The code

+ 7 - 7
libpng.mod/contrib/arm-neon/linux.c

@@ -1,8 +1,8 @@
 /* contrib/arm-neon/linux.c
 /* 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.
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * For conditions of distribution and use, see the disclaimer
@@ -62,7 +62,7 @@ png_have_neon(png_structp png_ptr)
 
 
                counter=0;
                counter=0;
                state = Feature;
                state = Feature;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
 
             case Feature:
             case Feature:
                /* Match 'FEATURE', ASCII case insensitive. */
                /* Match 'FEATURE', ASCII case insensitive. */
@@ -75,7 +75,7 @@ png_have_neon(png_structp png_ptr)
 
 
                /* did not match 'feature' */
                /* did not match 'feature' */
                state = SkipLine;
                state = SkipLine;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
 
             case SkipLine:
             case SkipLine:
             skipLine:
             skipLine:
@@ -110,7 +110,7 @@ png_have_neon(png_structp png_ptr)
 
 
                state = Neon;
                state = Neon;
                counter = 0;
                counter = 0;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
 
             case Neon:
             case Neon:
                /* Look for 'neon' tag */
                /* Look for 'neon' tag */
@@ -122,7 +122,7 @@ png_have_neon(png_structp png_ptr)
                }
                }
 
 
                state = SkipTag;
                state = SkipTag;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
 
             case SkipTag:
             case SkipTag:
                /* Skip non-space characters */
                /* Skip non-space characters */

+ 83 - 0
libpng.mod/contrib/mips-msa/README

@@ -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
[email protected].  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.

+ 64 - 0
libpng.mod/contrib/mips-msa/linux.c

@@ -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: [email protected]
+ *
+ * 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;
+}

+ 81 - 0
libpng.mod/contrib/powerpc-vsx/README

@@ -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 ARM NEON 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
[email protected].  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.

+ 57 - 0
libpng.mod/contrib/powerpc-vsx/linux.c

@@ -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: [email protected]
+ *
+ * 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;
+}

+ 36 - 0
libpng.mod/contrib/powerpc-vsx/linux_aux.c

@@ -0,0 +1,36 @@
+/* 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: [email protected]
+ *
+ * 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)
+{
+
+   const 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;
+}
+

+ 7 - 2
libpng.mod/example.c

@@ -114,13 +114,13 @@ int main(int argc, const char **argv)
 
 
          else
          else
          {
          {
-            /* Calling png_free_image is optional unless the simplified API was
+            /* Calling png_image_free is optional unless the simplified API was
              * not run to completion.  In this case if there wasn't enough
              * 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
              * memory for 'buffer' we didn't complete the read, so we must free
              * the image:
              * the image:
              */
              */
             if (buffer == NULL)
             if (buffer == NULL)
-               png_free_image(&image);
+               png_image_free(&image);
 
 
             else
             else
                free(buffer);
                free(buffer);
@@ -983,6 +983,11 @@ void write_png(char *file_name /* , ... other image information ... */)
    png_uint_32 k, height, width;
    png_uint_32 k, height, width;
 
 
    /* In this example, "image" is a one-dimensional array of bytes */
    /* 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_byte image[height*width*bytes_per_pixel];
 
 
    png_bytep row_pointers[height];
    png_bytep row_pointers[height];

+ 406 - 0
libpng.mod/intel/filter_sse2_intrinsics.c

@@ -0,0 +1,406 @@
+
+/* filter_sse2_intrinsics.c - SSE2 optimized filter functions
+ *
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett
+ * Derived from arm/filter_neon_intrinsics.c
+ *
+ * Last changed in libpng 1.6.31 [July 27, 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"
+
+#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) {
+   return _mm_cvtsi32_si128(*(const int*)p);
+}
+
+static void store4(void* p, __m128i v) {
+   *(int*)p = _mm_cvtsi128_si32(v);
+}
+
+static __m128i load3(const void* p) {
+   /* We'll load 2 bytes, then 1 byte,
+    * then mask them together, and finally load into SSE.
+    */
+   const png_uint_16* p01 = (png_const_uint_16p)p;
+   const png_byte*    p2  = (const png_byte*)(p01+1);
+
+   png_uint_32 v012 = (png_uint_32)(*p01)
+                    | (png_uint_32)(*p2) << 16;
+   return load4(&v012);
+}
+
+static void store3(void* p, __m128i v) {
+   /* We'll pull from SSE as a 32-bit int, then write
+    * its bottom two bytes, then its third byte.
+    */
+   png_uint_32 v012;
+   png_uint_16* p01;
+   png_byte*    p2;
+
+   store4(&v012, v);
+
+   p01 = (png_uint_16p)p;
+   p2  = (png_byte*)(p01+1);
+   *p01 = (png_uint_16)v012;
+   *p2  = (png_byte)(v012 >> 16);
+}
+
+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.
+    */
+   png_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.
+    */
+   png_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.
+    */
+
+   png_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.
+    */
+   png_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.
+    */
+   png_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.
+    */
+   png_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 */

+ 53 - 0
libpng.mod/intel/intel_init.c

@@ -0,0 +1,53 @@
+
+/* intel_init.c - SSE2 optimized filter functions
+ *
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett, Google, Inc.
+ * Derived from arm/arm_init.c
+ *
+ * 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
+ */
+
+#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 */

+ 100 - 41
libpng.mod/libpng-manual.txt

@@ -1,9 +1,9 @@
 libpng-manual.txt - A description on how to use and modify libpng
 libpng-manual.txt - A description on how to use and modify libpng
 
 
- libpng version 1.6.27 - December 29, 2016
+ libpng version 1.6.34 - September 29, 2017
  Updated and distributed by Glenn Randers-Pehrson
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
  <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 1998-2017 Glenn Randers-Pehrson
 
 
  This document is released under the libpng license.
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
  For conditions of distribution and use, see the disclaimer
@@ -11,9 +11,9 @@ libpng-manual.txt - A description on how to use and modify libpng
 
 
  Based on:
  Based on:
 
 
- libpng versions 0.97, January 1998, through 1.6.27 - December 29, 2016
+ libpng versions 0.97, January 1998, through 1.6.34 - September 29, 2017
  Updated and distributed by Glenn Randers-Pehrson
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 1998-2017 Glenn Randers-Pehrson
 
 
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
  Updated and distributed by Andreas Dilger
@@ -66,17 +66,17 @@ file format in application programs.
 
 
 The PNG specification (second edition), November 2003, is available as
 The PNG specification (second edition), November 2003, is available as
 a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
 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 W3C and ISO documents have identical technical content.
 
 
 The PNG-1.2 specification is available at
 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
 It is technically equivalent
 to the PNG specification (second edition) but has some additional material.
 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
+<https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
+W3C Recommendation <https://www.w3.org/TR/REC-png-961001>.
 
 
 Some additional chunks are described in the special-purpose public chunks
 Some additional chunks are described in the special-purpose public chunks
 documents at <http://www.libpng.org/pub/png/spec/register/>
 documents at <http://www.libpng.org/pub/png/spec/register/>
@@ -101,7 +101,7 @@ majority of the needs of its users.
 
 
 Libpng uses zlib for its compression and decompression of PNG files.
 Libpng uses zlib for its compression and decompression of PNG files.
 Further information about zlib, and the latest version of zlib, can
 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
 The zlib compression utility is a general purpose utility that is
 useful for more than PNG files, and can be used without libpng.
 useful for more than PNG files, and can be used without libpng.
 See the documentation delivered with zlib for more details.
 See the documentation delivered with zlib for more details.
@@ -688,8 +688,9 @@ where 0x7fffffffL means unlimited.  You can retrieve this limit with
    chunk_cache_max = png_get_chunk_cache_max(png_ptr);
    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
 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);
    png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);
 
 
@@ -985,8 +986,17 @@ premultiplication.
 
 
     png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
     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
 that the output is for a sRGB system and causes all PNG files without gAMA
 chunks to be assumed to be encoded using sRGB.
 chunks to be assumed to be encoded using sRGB.
 
 
@@ -1001,7 +1011,7 @@ early Mac systems behaved.
 This is the classic Jim Blinn approach and will work in academic
 This is the classic Jim Blinn approach and will work in academic
 environments where everything is done by the book.  It has the shortcoming
 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
 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
 Most of the time the output precision will be so low as to show
 significant banding in dark areas of the image.
 significant banding in dark areas of the image.
 
 
@@ -1190,7 +1200,20 @@ row_pointers prior to calling png_read_png() with
    png_set_rows(png_ptr, info_ptr, &row_pointers);
    png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 
 Alternatively you could allocate your image in one big block and define
 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
 If you use png_set_rows(), the application is responsible for freeing
 row_pointers (and row_pointers[i], if they were separately allocated).
 row_pointers (and row_pointers[i], if they were separately allocated).
@@ -1317,6 +1340,11 @@ in until png_read_end() has read the chunk data following the image.
     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
 
     rowbytes       - number of bytes needed to hold a row
     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);
     signature = png_get_signature(png_ptr, info_ptr);
 
 
@@ -1435,6 +1463,11 @@ png_set_rgb_to_gray()).
                      the single transparent color for
                      the single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
                      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_get_hIST(png_ptr, info_ptr, &hist);
                      (PNG_INFO_hIST)
                      (PNG_INFO_hIST)
 
 
@@ -2146,6 +2179,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
 array of pointers to each row, as it will be needed for some
 of the functions below.
 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_*()
 Remember: Before you call png_read_update_info(), the png_get_*()
 functions return the values corresponding to the original PNG image.
 functions return the values corresponding to the original PNG image.
 After you call png_read_update_info the values refer to the image
 After you call png_read_update_info the values refer to the image
@@ -2470,6 +2513,7 @@ your application instead of by libpng, you can use
              PNG_INFO_gAMA, PNG_INFO_sBIT,
              PNG_INFO_gAMA, PNG_INFO_sBIT,
              PNG_INFO_cHRM, PNG_INFO_PLTE,
              PNG_INFO_cHRM, PNG_INFO_PLTE,
              PNG_INFO_tRNS, PNG_INFO_bKGD,
              PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_eXIf,
              PNG_INFO_hIST, PNG_INFO_pHYs,
              PNG_INFO_hIST, PNG_INFO_pHYs,
              PNG_INFO_oFFs, PNG_INFO_tIME,
              PNG_INFO_oFFs, PNG_INFO_tIME,
              PNG_INFO_pCAL, PNG_INFO_sRGB,
              PNG_INFO_pCAL, PNG_INFO_sRGB,
@@ -3069,6 +3113,11 @@ width, height, bit_depth, and color_type must be the same in each call.
                      single transparent color for
                      single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
                      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);
     png_set_hIST(png_ptr, info_ptr, hist);
 
 
     hist           - histogram of palette (array of
     hist           - histogram of palette (array of
@@ -3824,7 +3873,7 @@ PNG_FORMAT_FLAG_LINEAR flag below.
 
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
 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.
 approximation used elsewhere in libpng.
 
 
 When an alpha channel is present it is expected to denote pixel coverage
 When an alpha channel is present it is expected to denote pixel coverage
@@ -4088,7 +4137,7 @@ READ APIs
 
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
 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.
 approximation used elsewhere in libpng.
 
 
 WRITE APIS
 WRITE APIS
@@ -4246,8 +4295,6 @@ functions after png_create_*_struct() has been called by calling:
         png_voidp error_ptr, png_error_ptr error_fn,
         png_voidp error_ptr, png_error_ptr error_fn,
         png_error_ptr warning_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
 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
 default function will be used, calling fprintf() and/or longjmp() if a
 problem is encountered.  The replacement error functions should have
 problem is encountered.  The replacement error functions should have
@@ -4259,6 +4306,11 @@ parameters as follows:
     void user_warning_fn(png_structp png_ptr,
     void user_warning_fn(png_structp png_ptr,
         png_const_charp warning_msg);
         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
 The motivation behind using setjmp() and longjmp() is the C++ throw and
 catch exception handling methods.  This makes the code much easier to write,
 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.
 as there is no need to check every return code of every function call.
@@ -4266,7 +4318,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 a longjmp, so the user may want to be careful about doing anything
 after setjmp returns non-zero besides returning itself.  Consult your
 after setjmp returns non-zero besides returning itself.  Consult your
 compiler documentation for more details.  For an alternative approach, you
 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.
 which is illustrated in pngvalid.c and in contrib/visupng.
 
 
 Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
 Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
@@ -4494,7 +4546,7 @@ 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
 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
 or any other MNG chunks; your application must provide its own support for
 them.  You may wish to consider using libmng (available at
 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
 
 
@@ -4917,18 +4969,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
 that it could be used to override them.  Now this function will reduce or
 increase the limits.
 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_width_max        0x7fffffff    1,000,000
    png_user_height_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
    png_user_chunk_malloc_max 0 (unlimited) 8,000,000
 
 
 The png_set_option() function (and the "options" member of the png struct) was
 The png_set_option() function (and the "options" member of the png struct) was
@@ -5178,6 +5226,11 @@ 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
 enforced, and the palette was always limited to 256 entries. An over-length
 PLTE chunk found in an input PNG is silently truncated.
 PLTE chunk found in an input PNG is silently truncated.
 
 
+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
 XIII.  Detecting libpng
 
 
 The png_get_io_ptr() function has been present since libpng-0.88, has never
 The png_get_io_ptr() function has been present since libpng-0.88, has never
@@ -5194,27 +5247,33 @@ 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)
 going back to version 0.70.  You can access the git repository (read only)
 at
 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 by selecting the "code" button at
+or you can browse it with a web browser at
 
 
-    https://sourceforge.net/projects/libpng
+    https://github.com/glennrp/libpng or
+    https://sourceforge.net/p/libpng/code/ci/libpng16/tree/
 
 
 Patches can be sent to glennrp at users.sourceforge.net or to
 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
 png-mng-implement at lists.sourceforge.net or you can upload them to
 the libpng bug tracker at
 the libpng bug tracker at
 
 
-    http://libpng.sourceforge.net
+    https://libpng.sourceforge.io/
+
+or as a "pull request" to
+
+    https://github.com/glennrp/libpng/pulls
 
 
 We also accept patches built from the tar or zip distributions, and
 We also accept patches built from the tar or zip distributions, and
 simple verbal discriptions of bug fixes, reported either to the
 simple verbal discriptions of bug fixes, reported either to the
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
-mailing list, or directly to glennrp.
+mailing list, as github issues, or directly to glennrp.
 
 
 XV. Coding style
 XV. Coding style
 
 
 Our coding style is similar to the "Allman" 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:
 braces on separate lines:
 
 
     if (condition)
     if (condition)
@@ -5315,7 +5374,7 @@ Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as
 though it were a function.
 though it were a function.
 
 
 Control keywords if, for, while, and switch are always followed by a space
 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
 We put a space after each comma and after each semicolon
 in "for" statements, and we put spaces before and after each
 in "for" statements, and we put spaces before and after each
@@ -5341,7 +5400,7 @@ for a few type names that we inherit from zlib.h.
 
 
 We prefer "if (something != 0)" and "if (something == 0)" over
 We prefer "if (something != 0)" and "if (something == 0)" over
 "if (something)" and if "(!something)", respectively, and for pointers
 "if (something)" and if "(!something)", respectively, and for pointers
-we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)". 
+we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)".
 
 
 We do not use the TAB character for indentation in the C sources.
 We do not use the TAB character for indentation in the C sources.
 
 
@@ -5355,7 +5414,7 @@ Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 an official declaration.
 
 
 This is your unofficial assurance that libpng from version 0.71 and
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.27 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.34 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 versions were also Y2K compliant.
 
 
 Libpng only has two year fields.  One is a 2-byte unsigned integer
 Libpng only has two year fields.  One is a 2-byte unsigned integer

+ 124 - 54
libpng.mod/libpng.3

@@ -1,6 +1,6 @@
-.TH LIBPNG 3 "December 29, 2016"
+.TH LIBPNG 3 "September 29, 2017"
 .SH NAME
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.27
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.34
 .SH SYNOPSIS
 .SH SYNOPSIS
 \fB
 \fB
 #include <png.h>\fP
 #include <png.h>\fP
@@ -97,6 +97,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.27
 
 
 \fBpng_byte png_get_header_version (png_const_structp \fIpng_ptr\fP\fB);\fP
 \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_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
 \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
@@ -347,6 +351,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.6.27
 
 
 \fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
 \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, const 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_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
 \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
@@ -510,10 +518,10 @@ Following is a copy of the libpng-manual.txt file that accompanies libpng.
 .SH LIBPNG.TXT
 .SH LIBPNG.TXT
 libpng-manual.txt - A description on how to use and modify libpng
 libpng-manual.txt - A description on how to use and modify libpng
 
 
- libpng version 1.6.27 - December 29, 2016
+ libpng version 1.6.34 - September 29, 2017
  Updated and distributed by Glenn Randers-Pehrson
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
  <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 1998-2017 Glenn Randers-Pehrson
 
 
  This document is released under the libpng license.
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
  For conditions of distribution and use, see the disclaimer
@@ -521,9 +529,9 @@ libpng-manual.txt - A description on how to use and modify libpng
 
 
  Based on:
  Based on:
 
 
- libpng versions 0.97, January 1998, through 1.6.27 - December 29, 2016
+ libpng versions 0.97, January 1998, through 1.6.34 - September 29, 2017
  Updated and distributed by Glenn Randers-Pehrson
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ Copyright (c) 1998-2017 Glenn Randers-Pehrson
 
 
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
  Updated and distributed by Andreas Dilger
@@ -576,17 +584,17 @@ file format in application programs.
 
 
 The PNG specification (second edition), November 2003, is available as
 The PNG specification (second edition), November 2003, is available as
 a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
 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 W3C and ISO documents have identical technical content.
 
 
 The PNG-1.2 specification is available at
 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
 It is technically equivalent
 to the PNG specification (second edition) but has some additional material.
 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
+<https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
+W3C Recommendation <https://www.w3.org/TR/REC-png-961001>.
 
 
 Some additional chunks are described in the special-purpose public chunks
 Some additional chunks are described in the special-purpose public chunks
 documents at <http://www.libpng.org/pub/png/spec/register/>
 documents at <http://www.libpng.org/pub/png/spec/register/>
@@ -611,7 +619,7 @@ majority of the needs of its users.
 
 
 Libpng uses zlib for its compression and decompression of PNG files.
 Libpng uses zlib for its compression and decompression of PNG files.
 Further information about zlib, and the latest version of zlib, can
 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
 The zlib compression utility is a general purpose utility that is
 useful for more than PNG files, and can be used without libpng.
 useful for more than PNG files, and can be used without libpng.
 See the documentation delivered with zlib for more details.
 See the documentation delivered with zlib for more details.
@@ -1198,8 +1206,9 @@ where 0x7fffffffL means unlimited.  You can retrieve this limit with
    chunk_cache_max = png_get_chunk_cache_max(png_ptr);
    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
 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);
    png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);
 
 
@@ -1495,8 +1504,17 @@ premultiplication.
 
 
     png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
     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
 that the output is for a sRGB system and causes all PNG files without gAMA
 chunks to be assumed to be encoded using sRGB.
 chunks to be assumed to be encoded using sRGB.
 
 
@@ -1511,7 +1529,7 @@ early Mac systems behaved.
 This is the classic Jim Blinn approach and will work in academic
 This is the classic Jim Blinn approach and will work in academic
 environments where everything is done by the book.  It has the shortcoming
 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
 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
 Most of the time the output precision will be so low as to show
 significant banding in dark areas of the image.
 significant banding in dark areas of the image.
 
 
@@ -1700,7 +1718,20 @@ row_pointers prior to calling png_read_png() with
    png_set_rows(png_ptr, info_ptr, &row_pointers);
    png_set_rows(png_ptr, info_ptr, &row_pointers);
 
 
 Alternatively you could allocate your image in one big block and define
 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
 If you use png_set_rows(), the application is responsible for freeing
 row_pointers (and row_pointers[i], if they were separately allocated).
 row_pointers (and row_pointers[i], if they were separately allocated).
@@ -1827,6 +1858,11 @@ in until png_read_end() has read the chunk data following the image.
     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 
 
     rowbytes       - number of bytes needed to hold a row
     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);
     signature = png_get_signature(png_ptr, info_ptr);
 
 
@@ -1945,6 +1981,11 @@ png_set_rgb_to_gray()).
                      the single transparent color for
                      the single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
                      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_get_hIST(png_ptr, info_ptr, &hist);
                      (PNG_INFO_hIST)
                      (PNG_INFO_hIST)
 
 
@@ -2656,6 +2697,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
 array of pointers to each row, as it will be needed for some
 of the functions below.
 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_*()
 Remember: Before you call png_read_update_info(), the png_get_*()
 functions return the values corresponding to the original PNG image.
 functions return the values corresponding to the original PNG image.
 After you call png_read_update_info the values refer to the image
 After you call png_read_update_info the values refer to the image
@@ -2980,6 +3031,7 @@ your application instead of by libpng, you can use
              PNG_INFO_gAMA, PNG_INFO_sBIT,
              PNG_INFO_gAMA, PNG_INFO_sBIT,
              PNG_INFO_cHRM, PNG_INFO_PLTE,
              PNG_INFO_cHRM, PNG_INFO_PLTE,
              PNG_INFO_tRNS, PNG_INFO_bKGD,
              PNG_INFO_tRNS, PNG_INFO_bKGD,
+             PNG_INFO_eXIf,
              PNG_INFO_hIST, PNG_INFO_pHYs,
              PNG_INFO_hIST, PNG_INFO_pHYs,
              PNG_INFO_oFFs, PNG_INFO_tIME,
              PNG_INFO_oFFs, PNG_INFO_tIME,
              PNG_INFO_pCAL, PNG_INFO_sRGB,
              PNG_INFO_pCAL, PNG_INFO_sRGB,
@@ -3579,6 +3631,11 @@ width, height, bit_depth, and color_type must be the same in each call.
                      single transparent color for
                      single transparent color for
                      non-paletted images (PNG_INFO_tRNS)
                      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);
     png_set_hIST(png_ptr, info_ptr, hist);
 
 
     hist           - histogram of palette (array of
     hist           - histogram of palette (array of
@@ -4334,7 +4391,7 @@ PNG_FORMAT_FLAG_LINEAR flag below.
 
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
 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.
 approximation used elsewhere in libpng.
 
 
 When an alpha channel is present it is expected to denote pixel coverage
 When an alpha channel is present it is expected to denote pixel coverage
@@ -4598,7 +4655,7 @@ READ APIs
 
 
 When the simplified API needs to convert between sRGB and linear colorspaces,
 When the simplified API needs to convert between sRGB and linear colorspaces,
 the actual sRGB transfer curve defined in the sRGB specification (see the
 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.
 approximation used elsewhere in libpng.
 
 
 WRITE APIS
 WRITE APIS
@@ -4756,8 +4813,6 @@ functions after png_create_*_struct() has been called by calling:
         png_voidp error_ptr, png_error_ptr error_fn,
         png_voidp error_ptr, png_error_ptr error_fn,
         png_error_ptr warning_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
 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
 default function will be used, calling fprintf() and/or longjmp() if a
 problem is encountered.  The replacement error functions should have
 problem is encountered.  The replacement error functions should have
@@ -4769,6 +4824,11 @@ parameters as follows:
     void user_warning_fn(png_structp png_ptr,
     void user_warning_fn(png_structp png_ptr,
         png_const_charp warning_msg);
         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
 The motivation behind using setjmp() and longjmp() is the C++ throw and
 catch exception handling methods.  This makes the code much easier to write,
 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.
 as there is no need to check every return code of every function call.
@@ -4776,7 +4836,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 a longjmp, so the user may want to be careful about doing anything
 after setjmp returns non-zero besides returning itself.  Consult your
 after setjmp returns non-zero besides returning itself.  Consult your
 compiler documentation for more details.  For an alternative approach, you
 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.
 which is illustrated in pngvalid.c and in contrib/visupng.
 
 
 Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
 Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
@@ -5004,7 +5064,7 @@ 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
 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
 or any other MNG chunks; your application must provide its own support for
 them.  You may wish to consider using libmng (available at
 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
 
 
@@ -5427,18 +5487,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
 that it could be used to override them.  Now this function will reduce or
 increase the limits.
 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_width_max        0x7fffffff    1,000,000
    png_user_height_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
    png_user_chunk_malloc_max 0 (unlimited) 8,000,000
 
 
 The png_set_option() function (and the "options" member of the png struct) was
 The png_set_option() function (and the "options" member of the png struct) was
@@ -5688,6 +5744,11 @@ 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
 enforced, and the palette was always limited to 256 entries. An over-length
 PLTE chunk found in an input PNG is silently truncated.
 PLTE chunk found in an input PNG is silently truncated.
 
 
+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
 .SH XIII.  Detecting libpng
 
 
 The png_get_io_ptr() function has been present since libpng-0.88, has never
 The png_get_io_ptr() function has been present since libpng-0.88, has never
@@ -5704,27 +5765,33 @@ 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)
 going back to version 0.70.  You can access the git repository (read only)
 at
 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 by selecting the "code" button at
+or you can browse it with a web browser at
 
 
-    https://sourceforge.net/projects/libpng
+    https://github.com/glennrp/libpng or
+    https://sourceforge.net/p/libpng/code/ci/libpng16/tree/
 
 
 Patches can be sent to glennrp at users.sourceforge.net or to
 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
 png-mng-implement at lists.sourceforge.net or you can upload them to
 the libpng bug tracker at
 the libpng bug tracker at
 
 
-    http://libpng.sourceforge.net
+    https://libpng.sourceforge.io/
+
+or as a "pull request" to
+
+    https://github.com/glennrp/libpng/pulls
 
 
 We also accept patches built from the tar or zip distributions, and
 We also accept patches built from the tar or zip distributions, and
 simple verbal discriptions of bug fixes, reported either to the
 simple verbal discriptions of bug fixes, reported either to the
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
 SourceForge bug tracker, to the png-mng-implement at lists.sf.net
-mailing list, or directly to glennrp.
+mailing list, as github issues, or directly to glennrp.
 
 
 .SH XV. Coding style
 .SH XV. Coding style
 
 
 Our coding style is similar to the "Allman" 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:
 braces on separate lines:
 
 
     if (condition)
     if (condition)
@@ -5825,7 +5892,7 @@ Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as
 though it were a function.
 though it were a function.
 
 
 Control keywords if, for, while, and switch are always followed by a space
 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
 We put a space after each comma and after each semicolon
 in "for" statements, and we put spaces before and after each
 in "for" statements, and we put spaces before and after each
@@ -5851,7 +5918,7 @@ for a few type names that we inherit from zlib.h.
 
 
 We prefer "if (something != 0)" and "if (something == 0)" over
 We prefer "if (something != 0)" and "if (something == 0)" over
 "if (something)" and if "(!something)", respectively, and for pointers
 "if (something)" and if "(!something)", respectively, and for pointers
-we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)". 
+we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)".
 
 
 We do not use the TAB character for indentation in the C sources.
 We do not use the TAB character for indentation in the C sources.
 
 
@@ -5865,7 +5932,7 @@ Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 an official declaration.
 
 
 This is your unofficial assurance that libpng from version 0.71 and
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.27 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.34 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 versions were also Y2K compliant.
 
 
 Libpng only has two year fields.  One is a 2-byte unsigned integer
 Libpng only has two year fields.  One is a 2-byte unsigned integer
@@ -5963,11 +6030,11 @@ the first widely used release:
  ...
  ...
  1.0.19                  10    10019  10.so.0.19[.0]
  1.0.19                  10    10019  10.so.0.19[.0]
  ...
  ...
- 1.2.56                  13    10256  12.so.0.56[.0]
+ 1.2.59                  13    10259  12.so.0.59[.0]
  ...
  ...
- 1.5.27                  15    10527  15.so.15.27[.0]
+ 1.5.30                  15    10530  15.so.15.30[.0]
  ...
  ...
- 1.6.27                  16    10627  16.so.16.27[.0]
+ 1.6.34                  16    10634  16.so.16.34[.0]
 
 
 Henceforth the source version will match the shared-library minor
 Henceforth the source version will match the shared-library minor
 and patch numbers; the shared-library major version number will be
 and patch numbers; the shared-library major version number will be
@@ -5984,7 +6051,7 @@ release number plus "betaNN" or "rcNN".
 .LP
 .LP
 .IR libpng :
 .IR libpng :
 .IP
 .IP
-http://libpng.sourceforge.net (follow the [DOWNLOAD] link)
+https://libpng.sourceforge.io/ (follow the [DOWNLOAD] link)
 http://www.libpng.org/pub/png
 http://www.libpng.org/pub/png
 
 
 .LP
 .LP
@@ -5994,7 +6061,7 @@ http://www.libpng.org/pub/png
 .I libpng
 .I libpng
 or at
 or at
 .br
 .br
-ftp://ftp.info-zip.org/pub/infozip/zlib
+https://zlib.net/
 
 
 .LP
 .LP
 .IR PNG specification: RFC 2083
 .IR PNG specification: RFC 2083
@@ -6003,11 +6070,11 @@ ftp://ftp.info-zip.org/pub/infozip/zlib
 .I libpng
 .I libpng
 or at
 or at
 .br
 .br
-ftp://ftp.rfc-editor.org:/in-notes/rfc2083.txt
+https://www.ietf.org/rfc/rfc2083.txt
 .br
 .br
 or (as a W3C Recommendation) at
 or (as a W3C Recommendation) at
 .br
 .br
-http://www.w3.org/TR/REC-png.html
+https://www.w3.org/TR/REC-png.html
 
 
 .LP
 .LP
 In the case of any inconsistency between the PNG specification
 In the case of any inconsistency between the PNG specification
@@ -6023,7 +6090,7 @@ possible without all of you.
 
 
 Thanks to Frank J. T. Wojcik for helping with the documentation.
 Thanks to Frank J. T. Wojcik for helping with the documentation.
 
 
-Libpng version 1.6.27 - December 29, 2016:
+Libpng version 1.6.34 - September 29, 2017:
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
 Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
 Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
 
 
@@ -6048,8 +6115,8 @@ this sentence.
 
 
 This code is released under the libpng license.
 This code is released under the libpng license.
 
 
-libpng versions 1.0.7, July 1, 2000 through 1.6.27, December 29, 2016 are
-Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
 derived from libpng-1.0.6, and are distributed according to the same
 derived from libpng-1.0.6, and are distributed according to the same
 disclaimer and license as libpng-1.0.6 with the following individuals
 disclaimer and license as libpng-1.0.6 with the following individuals
 added to the list of Contributing Authors:
 added to the list of Contributing Authors:
@@ -6060,6 +6127,9 @@ added to the list of Contributing Authors:
    Cosmin Truta
    Cosmin Truta
    Gilles Vollant
    Gilles Vollant
    James Yu
    James Yu
+   Mandar Sahastrabuddhe
+   Google Inc.
+   Vadim Barkov
 
 
 and with the following additions to the disclaimer:
 and with the following additions to the disclaimer:
 
 
@@ -6173,7 +6243,7 @@ files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
 
 
 Glenn Randers-Pehrson
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
 glennrp at users.sourceforge.net
-December 29, 2016
+September 29, 2017
 
 
 .\" end of man page
 .\" end of man page
 
 

+ 16 - 1
libpng.mod/libpng.bmx

@@ -2,12 +2,15 @@ SuperStrict
 
 
 Module Pub.LibPNG
 Module Pub.LibPNG
 
 
-ModuleInfo "Version: 1.08"
+ModuleInfo "Version: 1.09"
 ModuleInfo "Author: Guy Eric Schalnat, Andreas Dilger, Glenn Randers-Pehrson, Others"
 ModuleInfo "Author: Guy Eric Schalnat, Andreas Dilger, Glenn Randers-Pehrson, Others"
 ModuleInfo "License: ZLib/PNG License"
 ModuleInfo "License: ZLib/PNG License"
 ModuleInfo "Modserver: BRL"
 ModuleInfo "Modserver: BRL"
 ModuleInfo "Credit: Adapted for BlitzMax by Mark Sibly"
 ModuleInfo "Credit: Adapted for BlitzMax by Mark Sibly"
 
 
+ModuleInfo "History: 1.09"
+ModuleInfo "History: Update to libpng 1.6.34."
+ModuleInfo "History: Enabled SSE for x86 and x64."
 ModuleInfo "History: 1.08"
 ModuleInfo "History: 1.08"
 ModuleInfo "History: Exposed user data."
 ModuleInfo "History: Exposed user data."
 ModuleInfo "History: 1.07"
 ModuleInfo "History: 1.07"
@@ -25,6 +28,12 @@ ModuleInfo "History: Fixed for Intel Macs"
 ModuleInfo "History: 1.02"
 ModuleInfo "History: 1.02"
 ModuleInfo "History: Update to libpng 1.2.12"
 ModuleInfo "History: Update to libpng 1.2.12"
 
 
+?x86
+ModuleInfo "CC_OPTS: -DPNG_INTEL_SSE"
+?x64
+ModuleInfo "CC_OPTS: -DPNG_INTEL_SSE"
+?
+
 Import Pub.ZLib
 Import Pub.ZLib
 
 
 Import "png.c"
 Import "png.c"
@@ -45,6 +54,12 @@ Import "pngwutil.c"
 ?ios
 ?ios
 Import "arm/arm_init.c"
 Import "arm/arm_init.c"
 Import "arm/filter_neon_intrinsics.c"
 Import "arm/filter_neon_intrinsics.c"
+?x86
+Import "intel/filter_sse2_intrinsics.c"
+Import "intel/intel_init.c"
+?x64
+Import "intel/filter_sse2_intrinsics.c"
+Import "intel/intel_init.c"
 ?
 ?
 
 
 Extern
 Extern

+ 1 - 0
libpng.mod/libpng.pc.in

@@ -6,6 +6,7 @@ includedir=@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
 Name: libpng
 Name: libpng
 Description: Loads and saves PNG files
 Description: Loads and saves PNG files
 Version: @PNGLIB_VERSION@
 Version: @PNGLIB_VERSION@
+Requires: zlib
 Libs: -L${libdir} -lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
 Libs: -L${libdir} -lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
 Libs.private: @LIBS@
 Libs.private: @LIBS@
 Cflags: -I${includedir}
 Cflags: -I${includedir}

+ 4 - 4
libpng.mod/libpngpf.3

@@ -1,11 +1,11 @@
-.TH LIBPNGPF 3 "December 29, 2016"
+.TH LIBPNGPF 3 "April 1, 2017"
 .SH NAME
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.27
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.34
 (private functions)
 (private functions)
 .SH SYNOPSIS
 .SH SYNOPSIS
-\fB#include \fI"pngpriv.h"
+\fB\fB#include \fI\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.
+\fB\fBAs of libpng version \fP\fI\fP\fI1.5.1\fP\fB\fP\fB, this section is no longer \fP\fI\fP\fImaintained\fP\fB\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 \fI\fIfunction.
 
 
 .SH DESCRIPTION
 .SH DESCRIPTION
 The functions previously listed here are used privately by libpng and are not
 The functions previously listed here are used privately by libpng and are not

+ 807 - 0
libpng.mod/mips/filter_msa_intrinsics.c

@@ -0,0 +1,807 @@
+
+/* filter_msa_intrinsics.c - MSA optimised filter functions
+ *
+ * Copyright (c) 2016 Glenn Randers-Pehrson
+ * Written by Mandar Sahastrabuddhe, August 2016.
+ * Last changed in libpng 1.6.25 [September 1, 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)
+{
+   png_size_t i, cnt, cnt16, cnt32;
+   png_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)
+{
+   png_size_t count;
+   png_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)
+{
+   png_size_t count;
+   png_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)
+{
+   png_size_t i;
+   png_bytep src = row;
+   png_bytep nxt = row;
+   png_const_bytep pp = prev_row;
+   png_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)
+{
+   png_size_t i;
+   png_bytep src = row;
+   png_bytep nxt = row;
+   png_const_bytep pp = prev_row;
+   png_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 */

+ 129 - 0
libpng.mod/mips/mips_init.c

@@ -0,0 +1,129 @@
+
+/* mips_init.c - MSA optimised filter functions
+ *
+ * Copyright (c) 2016 Glenn Randers-Pehrson
+ * Written by Mandar Sahastrabuddhe, 2016.
+ * Last changed in libpng 1.6.25 [September 1, 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 */

+ 5 - 5
libpng.mod/png.5

@@ -1,4 +1,4 @@
-.TH PNG 5 "December 29, 2016"
+.TH PNG 5 "April 1, 2017"
 .SH NAME
 .SH NAME
 png \- Portable Network Graphics (PNG) format
 png \- Portable Network Graphics (PNG) format
 .SH DESCRIPTION
 .SH DESCRIPTION
@@ -23,11 +23,11 @@ platforms.
 PNG specification (second edition), November 2003:
 PNG specification (second edition), November 2003:
 .IP
 .IP
 .br
 .br
-  <http://www.w3.org/TR/2003/REC-PNG-20031110/
+  <https://www.w3.org/TR/2003/REC-PNG-20031110/
 PNG 1.2 specification, July 1999:
 PNG 1.2 specification, July 1999:
 .IP
 .IP
 .br
 .br
-http://png-mng.sourceforge.net/pub/png/spec/1.2/
+https://png-mng.sourceforge.io/pub/png/spec/1.2/
 .LP
 .LP
 PNG 1.0 specification, October 1996:
 PNG 1.0 specification, October 1996:
 .IP
 .IP
@@ -35,11 +35,11 @@ PNG 1.0 specification, October 1996:
 RFC 2083
 RFC 2083
 .IP
 .IP
 .br
 .br
-http://www.ietf.org/rfc/rfc2083.txt
+https://www.ietf.org/rfc/rfc2083.txt
 .br
 .br
 or (as a W3C Recommendation) at
 or (as a W3C Recommendation) at
 .br
 .br
-http://www.w3.org/TR/REC-png-961001
+https://www.w3.org/TR/REC-png-961001
 .SH AUTHORS
 .SH AUTHORS
 This man page: Glenn Randers-Pehrson
 This man page: Glenn Randers-Pehrson
 .LP
 .LP

+ 124 - 44
libpng.mod/png.c

@@ -1,8 +1,8 @@
 
 
 /* png.c - location for general purpose libpng functions
 /* png.c - location for general purpose libpng functions
  *
  *
- * Last changed in libpng 1.6.27 [December 29, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -14,7 +14,27 @@
 #include "pngpriv.h"
 #include "pngpriv.h"
 
 
 /* Generate a compiler error if there is an old png.h in the search path. */
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_27 Your_png_h_is_not_version_1_6_27;
+typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34;
+
+#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
 /* 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
  * of the PNG file signature.  If the PNG data is embedded into another
@@ -595,6 +615,26 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
    }
    }
 #endif
 #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
 #ifdef PNG_hIST_SUPPORTED
    /* Free any hIST entry */
    /* Free any hIST entry */
    if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
    if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
@@ -776,15 +816,15 @@ png_get_copyright(png_const_structrp png_ptr)
 #else
 #else
 #  ifdef __STDC__
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
    return PNG_STRING_NEWLINE \
-      "libpng version 1.6.27 - December 29, 2016" PNG_STRING_NEWLINE \
-      "Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson" \
+      "libpng version 1.6.34 - September 29, 2017" PNG_STRING_NEWLINE \
+      "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \
       PNG_STRING_NEWLINE \
       PNG_STRING_NEWLINE \
       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
       "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
       "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
       PNG_STRING_NEWLINE;
       PNG_STRING_NEWLINE;
 #  else
 #  else
-   return "libpng version 1.6.27 - December 29, 2016\
-      Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\
+   return "libpng version 1.6.34 - September 29, 2017\
+      Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
 #  endif
 #  endif
@@ -1873,12 +1913,12 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
     */
     */
    if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
    if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
       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 &&
    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",
       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)
    if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
    {
    {
@@ -1939,7 +1979,6 @@ icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
    if (profile_length < 132)
    if (profile_length < 132)
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
           "too short");
           "too short");
-
    return 1;
    return 1;
 }
 }
 
 
@@ -2184,22 +2223,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
        * being in range.  All defined tag types have an 8 byte header - a 4 byte
        * type signature then 0.
        * 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)
       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
           * only a warning here because libpng does not care about the
           * alignment.
           * alignment.
           */
           */
          (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
          (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 */
    return 1; /* success, maybe with warnings */
@@ -2832,7 +2872,7 @@ png_pow10(int power)
    if (power < 0)
    if (power < 0)
    {
    {
       if (power < DBL_MIN_10_EXP) return 0;
       if (power < DBL_MIN_10_EXP) return 0;
-      recip = 1, power = -power;
+      recip = 1; power = -power;
    }
    }
 
 
    if (power > 0)
    if (power > 0)
@@ -2857,6 +2897,14 @@ png_pow10(int power)
 /* Function to format a floating point value in ASCII with a given
 /* Function to format a floating point value in ASCII with a given
  * precision.
  * 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 */
 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, png_size_t size,
     double fp, unsigned int precision)
     double fp, unsigned int precision)
@@ -2910,7 +2958,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
             double test = png_pow10(exp_b10+1);
             double test = png_pow10(exp_b10+1);
 
 
             if (test <= DBL_MAX)
             if (test <= DBL_MAX)
-               ++exp_b10, base = test;
+            {
+               ++exp_b10; base = test;
+            }
 
 
             else
             else
                break;
                break;
@@ -2924,7 +2974,10 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
           * test on DBL_MAX above.
           * test on DBL_MAX above.
           */
           */
          fp /= base;
          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
          /* Because of the code above fp may, at this point, be
           * less than .1, this is ok because the code below can
           * less than .1, this is ok because the code below can
@@ -2941,7 +2994,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 */
             if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
             {
             {
-               czero = (unsigned int)(-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. */
                exp_b10 = 0;      /* Dot added below before first output. */
             }
             }
             else
             else
@@ -2975,7 +3028,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
                      /* Rounding up to 10, handle that here. */
                      /* Rounding up to 10, handle that here. */
                      if (czero > 0)
                      if (czero > 0)
                      {
                      {
-                        --czero, d = 1;
+                        --czero; d = 1;
                         if (cdigits == 0) --clead;
                         if (cdigits == 0) --clead;
                      }
                      }
                      else
                      else
@@ -2989,7 +3042,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
 
 
                            else if (ch == 46)
                            else if (ch == 46)
                            {
                            {
-                              ch = *--ascii, ++size;
+                              ch = *--ascii; ++size;
                               /* Advance exp_b10 to '1', so that the
                               /* Advance exp_b10 to '1', so that the
                                * decimal point happens after the
                                * decimal point happens after the
                                * previous digit.
                                * previous digit.
@@ -3016,7 +3069,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
                               int ch = *--ascii;
                               int ch = *--ascii;
 
 
                               if (ch == 46)
                               if (ch == 46)
-                                 ++size, exp_b10 = 1;
+                              {
+                                 ++size; exp_b10 = 1;
+                              }
 
 
                               /* Else lost a leading zero, so 'exp_b10' is
                               /* Else lost a leading zero, so 'exp_b10' is
                                * still ok at (-1)
                                * still ok at (-1)
@@ -3052,21 +3107,26 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
                       */
                       */
                      if (exp_b10 != (-1))
                      if (exp_b10 != (-1))
                      {
                      {
-                        if (exp_b10 == 0) *ascii++ = 46, --size;
+                        if (exp_b10 == 0)
+                        {
+                           *ascii++ = 46; --size;
+                        }
                         /* PLUS 1: TOTAL 4 */
                         /* PLUS 1: TOTAL 4 */
                         --exp_b10;
                         --exp_b10;
                      }
                      }
-                     *ascii++ = 48, --czero;
+                     *ascii++ = 48; --czero;
                   }
                   }
 
 
                   if (exp_b10 != (-1))
                   if (exp_b10 != (-1))
                   {
                   {
                      if (exp_b10 == 0)
                      if (exp_b10 == 0)
-                        *ascii++ = 46, --size; /* counted above */
+                     {
+                        *ascii++ = 46; --size; /* counted above */
+                     }
 
 
                      --exp_b10;
                      --exp_b10;
                   }
                   }
-                  *ascii++ = (char)(48 + (int)d), ++cdigits;
+                  *ascii++ = (char)(48 + (int)d); ++cdigits;
                }
                }
             }
             }
             while (cdigits+czero < precision+clead && fp > DBL_MIN);
             while (cdigits+czero < precision+clead && fp > DBL_MIN);
@@ -3075,7 +3135,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
 
 
             /* Check for an exponent, if we don't need one we are
             /* Check for an exponent, if we don't need one we are
              * done and just need to terminate the string.  At
              * done and just need to terminate the string.  At
-             * this point exp_b10==(-1) is effectively if flag - it got
+             * this point exp_b10==(-1) is effectively a flag - it got
              * to '-1' because of the decrement after outputting
              * to '-1' because of the decrement after outputting
              * the decimal point above (the exponent required is
              * the decimal point above (the exponent required is
              * *not* -1!)
              * *not* -1!)
@@ -3089,7 +3149,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
                 * zeros were *not* output, so this doesn't increase
                 * the output count.
                 * the output count.
                 */
                 */
-               while (--exp_b10 >= 0) *ascii++ = 48;
+               while (exp_b10-- > 0) *ascii++ = 48;
 
 
                *ascii = 0;
                *ascii = 0;
 
 
@@ -3107,7 +3167,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
              */
              */
             size -= cdigits;
             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 following use of an unsigned temporary avoids ambiguities in
              * the signed arithmetic on exp_b10 and permits GCC at least to do
              * the signed arithmetic on exp_b10 and permits GCC at least to do
@@ -3118,12 +3178,12 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
 
 
                if (exp_b10 < 0)
                if (exp_b10 < 0)
                {
                {
-                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
-                  uexp_b10 = (unsigned int)(-exp_b10);
+                  *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
+                  uexp_b10 = 0U-exp_b10;
                }
                }
 
 
                else
                else
-                  uexp_b10 = (unsigned int)exp_b10;
+                  uexp_b10 = 0U+exp_b10;
 
 
                cdigits = 0;
                cdigits = 0;
 
 
@@ -3166,6 +3226,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
    /* Here on buffer too small. */
    /* Here on buffer too small. */
    png_error(png_ptr, "ASCII conversion 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 */
 #  endif /* FLOATING_POINT */
 
 
@@ -3185,7 +3248,9 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
 
 
       /* Avoid overflow here on the minimum integer. */
       /* Avoid overflow here on the minimum integer. */
       if (fp < 0)
       if (fp < 0)
-         *ascii++ = 45, num = (png_uint_32)(-fp);
+      {
+         *ascii++ = 45; num = (png_uint_32)(-fp);
+      }
       else
       else
          num = (png_uint_32)fp;
          num = (png_uint_32)fp;
 
 
@@ -3223,7 +3288,10 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
                 * then ndigits digits to first:
                 * then ndigits digits to first:
                 */
                 */
                i = 5;
                i = 5;
-               while (ndigits < i) *ascii++ = 48, --i;
+               while (ndigits < i)
+               {
+                  *ascii++ = 48; --i;
+               }
                while (ndigits >= first) *ascii++ = digits[--ndigits];
                while (ndigits >= first) *ascii++ = digits[--ndigits];
                /* Don't output the trailing zeros! */
                /* Don't output the trailing zeros! */
             }
             }
@@ -3274,6 +3342,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 nearest .00001).  Overflow and divide by zero are signalled in
  * the result, a boolean - true on success, false on overflow.
  * 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
 int
 png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
 png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
     png_int_32 divisor)
     png_int_32 divisor)
@@ -3388,6 +3465,9 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
 
 
    return 0;
    return 0;
 }
 }
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic pop
+#endif /* GCC_STRICT_OVERFLOW */
 #endif /* READ_GAMMA || INCH_CONVERSIONS */
 #endif /* READ_GAMMA || INCH_CONVERSIONS */
 
 
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
@@ -3681,7 +3761,7 @@ png_log16bit(png_uint_32 x)
  * of getting this accuracy in practice.
  * of getting this accuracy in practice.
  *
  *
  * To deal with this the following exp() function works out the exponent of the
  * 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.
  * top four fractional bits then multiplying in the remaining bits.
  */
  */
 static const png_uint_32
 static const png_uint_32
@@ -4260,13 +4340,13 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
    if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
    if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
       (option & 1) == 0)
       (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) & 0xff);
 
 
-      return (current & mask) >> option;
+      return (int)(current & mask) >> option;
    }
    }
 
 
    return PNG_OPTION_INVALID;
    return PNG_OPTION_INVALID;
@@ -4278,7 +4358,7 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
 /* sRGB conversion tables; these are machine generated with the code in
 /* sRGB conversion tables; these are machine generated with the code in
  * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
  * 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.
  * 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 sRGB to linear table is exact (to the nearest 16-bit linear fraction).
  * The inverse (linear to sRGB) table has accuracies as follows:
  * The inverse (linear to sRGB) table has accuracies as follows:

+ 43 - 32
libpng.mod/png.h

@@ -1,9 +1,9 @@
 
 
 /* png.h - header file for PNG reference library
 /* png.h - header file for PNG reference library
  *
  *
- * libpng version 1.6.27, December 29, 2016
+ * libpng version 1.6.34, September 29, 2017
  *
  *
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -12,7 +12,7 @@
  * Authors and maintainers:
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   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.89, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.6.27, December 29, 2016:
+ *   libpng versions 0.97, January 1998, through 1.6.34, September 29, 2017:
  *     Glenn Randers-Pehrson.
  *     Glenn Randers-Pehrson.
  *   See also "Contributing Authors", below.
  *   See also "Contributing Authors", below.
  */
  */
@@ -25,12 +25,8 @@
  *
  *
  * This code is released under the libpng license.
  * This code is released under the libpng license.
  *
  *
- * 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 1.0.7, July 1, 2000 through 1.6.27, December 29, 2016 are
- * Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+ * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
  * derived from libpng-1.0.6, and are distributed according to the same
  * derived from libpng-1.0.6, and are distributed according to the same
  * disclaimer and license as libpng-1.0.6 with the following individuals
  * disclaimer and license as libpng-1.0.6 with the following individuals
  * added to the list of Contributing Authors:
  * added to the list of Contributing Authors:
@@ -42,6 +38,8 @@
  *    Gilles Vollant
  *    Gilles Vollant
  *    James Yu
  *    James Yu
  *    Mandar Sahastrabuddhe
  *    Mandar Sahastrabuddhe
+ *    Google Inc.
+ *    Vadim Barkov
  *
  *
  * and with the following additions to the disclaimer:
  * and with the following additions to the disclaimer:
  *
  *
@@ -52,10 +50,10 @@
  *    risk of satisfactory quality, performance, accuracy, and effort is with
  *    risk of satisfactory quality, performance, accuracy, and effort is with
  *    the user.
  *    the user.
  *
  *
- * Some files in the "contrib" directory have other copyright owners and
+ * 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.
  * are released under other open source licenses.
  *
  *
- *
  * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
  * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
  * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
  * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
  * libpng-0.96, and are distributed according to the same disclaimer and
  * libpng-0.96, and are distributed according to the same disclaimer and
@@ -66,9 +64,6 @@
  *    Glenn Randers-Pehrson
  *    Glenn Randers-Pehrson
  *    Willem van Schaik
  *    Willem van Schaik
  *
  *
- * Some files in the "scripts" directory have different copyright owners
- * but are also released under this license.
- *
  * libpng versions 0.89, June 1996, through 0.96, May 1997, are
  * libpng versions 0.89, June 1996, through 0.96, May 1997, are
  * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
  * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
  * and are distributed according to the same disclaimer and license as
  * and are distributed according to the same disclaimer and license as
@@ -214,11 +209,11 @@
  *    ...
  *    ...
  *    1.0.19                  10    10019  10.so.0.19[.0]
  *    1.0.19                  10    10019  10.so.0.19[.0]
  *    ...
  *    ...
- *    1.2.56                  13    10256  12.so.0.56[.0]
+ *    1.2.59                  13    10257  12.so.0.59[.0]
  *    ...
  *    ...
- *    1.5.27                  15    10527  15.so.15.27[.0]
+ *    1.5.30                  15    10527  15.so.15.30[.0]
  *    ...
  *    ...
- *    1.6.27                  16    10627  16.so.16.27[.0]
+ *    1.6.34                  16    10633  16.so.16.34[.0]
  *
  *
  *    Henceforth the source version will match the shared-library major
  *    Henceforth the source version will match the shared-library major
  *    and minor numbers; the shared-library major version number will be
  *    and minor numbers; the shared-library major version number will be
@@ -239,20 +234,20 @@
  *
  *
  * See libpng.txt or libpng.3 for more information.  The PNG specification
  * See libpng.txt or libpng.3 for more information.  The PNG specification
  * is available as a W3C Recommendation and as an ISO Specification,
  * is available as a W3C Recommendation and as an ISO Specification,
- * <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ * <https://www.w3.org/TR/2003/REC-PNG-20031110/
  */
  */
 
 
 /*
 /*
  * Y2K compliance in libpng:
  * Y2K compliance in libpng:
  * =========================
  * =========================
  *
  *
- *    December 29, 2016
+ *    September 29, 2017
  *
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
  *    an official declaration.
  *
  *
  *    This is your unofficial assurance that libpng from version 0.71 and
  *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.6.27 are Y2K compliant.  It is my belief that
+ *    upward through 1.6.34 are Y2K compliant.  It is my belief that
  *    earlier versions were also Y2K compliant.
  *    earlier versions were also Y2K compliant.
  *
  *
  *    Libpng only has two year fields.  One is a 2-byte unsigned integer
  *    Libpng only has two year fields.  One is a 2-byte unsigned integer
@@ -314,8 +309,8 @@
  */
  */
 
 
 /* Version information for png.h - this should match the version in png.c */
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.27"
-#define PNG_HEADER_VERSION_STRING " libpng version 1.6.27 - December 29, 2016\n"
+#define PNG_LIBPNG_VER_STRING "1.6.34"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.34 - September 29, 2017\n"
 
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
 #define PNG_LIBPNG_VER_DLLNUM  16
@@ -323,7 +318,7 @@
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 27
+#define PNG_LIBPNG_VER_RELEASE 34
 
 
 /* This should match the numeric part of the final component of
 /* This should match the numeric part of the final component of
  * PNG_LIBPNG_VER_STRING, omitting any leading zero:
  * PNG_LIBPNG_VER_STRING, omitting any leading zero:
@@ -354,7 +349,7 @@
  * version 1.0.0 was mis-numbered 100 instead of 10000).  From
  * 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
  * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
  */
  */
-#define PNG_LIBPNG_VER 10627 /* 1.6.27 */
+#define PNG_LIBPNG_VER 10634 /* 1.6.34 */
 
 
 /* Library configuration: these options cannot be changed after
 /* Library configuration: these options cannot be changed after
  * the library has been built.
  * the library has been built.
@@ -464,7 +459,7 @@ extern "C" {
 /* This triggers a compiler error in png.c, if png.c and png.h
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  * do not agree upon the version number.
  */
  */
-typedef char* png_libpng_version_1_6_27;
+typedef char* png_libpng_version_1_6_34;
 
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
  *
@@ -781,6 +776,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
 #define PNG_INFO_sPLT 0x2000U  /* 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_sCAL 0x4000U  /* ESR, 1.0.6 */
 #define PNG_INFO_IDAT 0x8000U  /* 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
 /* This is used for the transformation routines, as some of them
  * change these values for the row.  It also should enable using
  * change these values for the row.  It also should enable using
@@ -1793,7 +1789,8 @@ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
 #define PNG_FREE_PLTE 0x1000U
 #define PNG_FREE_PLTE 0x1000U
 #define PNG_FREE_TRNS 0x2000U
 #define PNG_FREE_TRNS 0x2000U
 #define PNG_FREE_TEXT 0x4000U
 #define PNG_FREE_TEXT 0x4000U
-#define PNG_FREE_ALL  0x7fffU
+#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 */
 #define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
 
 
 #ifdef PNG_USER_MEM_SUPPORTED
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -2012,6 +2009,18 @@ PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
     png_fixed_point int_blue_Z))
     png_fixed_point int_blue_Z))
 #endif
 #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, const 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, const png_uint_32 num_exif, const png_bytep exif));
+#endif
+
 #ifdef PNG_gAMA_SUPPORTED
 #ifdef PNG_gAMA_SUPPORTED
 PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
 PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
     png_const_inforp info_ptr, double *file_gamma))
     png_const_inforp info_ptr, double *file_gamma))
@@ -2030,9 +2039,6 @@ PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
 #ifdef PNG_hIST_SUPPORTED
 #ifdef PNG_hIST_SUPPORTED
 PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
 PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
     png_inforp info_ptr, png_uint_16p *hist));
     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_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
     png_inforp info_ptr, png_const_uint_16p hist));
     png_inforp info_ptr, png_const_uint_16p hist));
 #endif
 #endif
@@ -2758,7 +2764,7 @@ typedef struct
  *
  *
  * When the simplified API needs to convert between sRGB and linear colorspaces,
  * When the simplified API needs to convert between sRGB and linear colorspaces,
  * the actual sRGB transfer curve defined in the sRGB specification (see the
  * 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.
  * approximation used elsewhere in libpng.
  *
  *
  * When an alpha channel is present it is expected to denote pixel coverage
  * When an alpha channel is present it is expected to denote pixel coverage
@@ -2813,6 +2819,8 @@ typedef struct
 #  define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
 #  define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
 #endif
 #endif
 
 
+#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
+
 /* Commonly used formats have predefined macros.
 /* Commonly used formats have predefined macros.
  *
  *
  * First the single byte (sRGB) formats:
  * First the single byte (sRGB) formats:
@@ -3231,7 +3239,10 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
 #  define PNG_MIPS_MSA   6 /* HARDWARE: MIPS Msa SIMD instructions supported */
 #  define PNG_MIPS_MSA   6 /* HARDWARE: MIPS Msa SIMD instructions supported */
 #endif
 #endif
 #define PNG_IGNORE_ADLER32 8
 #define PNG_IGNORE_ADLER32 8
-#define PNG_OPTION_NEXT  10 /* Next option - numbers must be even */
+#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 */
 /* Return values: NOTE: there are four values and 'off' is *not* zero */
 #define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
 #define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
@@ -3255,7 +3266,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
  * one to use is one more than this.)
  * one to use is one more than this.)
  */
  */
 #ifdef PNG_EXPORT_LAST_ORDINAL
 #ifdef PNG_EXPORT_LAST_ORDINAL
-  PNG_EXPORT_LAST_ORDINAL(245);
+  PNG_EXPORT_LAST_ORDINAL(249);
 #endif
 #endif
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 1 - 1
libpng.mod/pngconf.h

@@ -1,7 +1,7 @@
 
 
 /* pngconf.h - machine configurable file for libpng
 /* pngconf.h - machine configurable file for libpng
  *
  *
- * libpng version 1.6.27, December 29, 2016
+ * libpng version 1.6.34, September 29, 2017
  *
  *
  * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)

+ 4 - 4
libpng.mod/pngerror.c

@@ -1,8 +1,8 @@
 
 
 /* pngerror.c - stub functions for i/o and memory allocation
 /* pngerror.c - stub functions for i/o and memory allocation
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -163,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
          case PNG_NUMBER_FORMAT_02u:
          case PNG_NUMBER_FORMAT_02u:
             /* Expects at least 2 digits. */
             /* Expects at least 2 digits. */
             mincount = 2;
             mincount = 2;
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
 
          case PNG_NUMBER_FORMAT_u:
          case PNG_NUMBER_FORMAT_u:
             *--end = digits[number % 10];
             *--end = digits[number % 10];
@@ -173,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
          case PNG_NUMBER_FORMAT_02x:
          case PNG_NUMBER_FORMAT_02x:
             /* This format expects at least two digits */
             /* This format expects at least two digits */
             mincount = 2;
             mincount = 2;
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
 
 
          case PNG_NUMBER_FORMAT_x:
          case PNG_NUMBER_FORMAT_x:
             *--end = digits[number & 0xf];
             *--end = digits[number & 0xf];

+ 31 - 2
libpng.mod/pngget.c

@@ -1,8 +1,8 @@
 
 
 /* pngget.c - retrieval of values from info struct
 /* pngget.c - retrieval of values from info struct
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -773,6 +773,35 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
 }
 }
 #endif
 #endif
 
 
+#ifdef PNG_eXIf_SUPPORTED
+png_uint_32 PNGAPI
+png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
+    png_bytep *exif)
+{
+  png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
+  PNG_UNUSED(info_ptr)
+  PNG_UNUSED(exif)
+  return 0;
+}
+
+png_uint_32 PNGAPI
+png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
+    png_uint_32 *num_exif, png_bytep *exif)
+{
+   png_debug1(1, "in %s retrieval function", "eXIf");
+
+   if (png_ptr != NULL && info_ptr != NULL &&
+       (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
+   {
+      *num_exif = info_ptr->num_exif;
+      *exif = info_ptr->exif;
+      return (PNG_INFO_eXIf);
+   }
+
+   return (0);
+}
+#endif
+
 #ifdef PNG_hIST_SUPPORTED
 #ifdef PNG_hIST_SUPPORTED
 png_uint_32 PNGAPI
 png_uint_32 PNGAPI
 png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
 png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,

+ 8 - 0
libpng.mod/pnginfo.h

@@ -185,6 +185,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
    png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
    png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
 #endif
 #endif
 
 
+#ifdef PNG_eXIf_SUPPORTED
+   int num_exif;  /* Added at libpng-1.6.31 */
+   png_bytep exif;
+# ifdef PNG_READ_eXIf_SUPPORTED
+   png_bytep eXIf_buf;  /* Added at libpng-1.6.32 */
+# endif
+#endif
+
 #ifdef PNG_hIST_SUPPORTED
 #ifdef PNG_hIST_SUPPORTED
    /* The hIST chunk contains the relative frequency or importance of the
    /* The hIST chunk contains the relative frequency or importance of the
     * various palette entries, so that a viewer can intelligently select a
     * various palette entries, so that a viewer can intelligently select a

+ 3 - 2
libpng.mod/pngpread.c

@@ -1,8 +1,8 @@
 
 
 /* pngpread.c - read a png file in push mode
 /* pngpread.c - read a png file in push mode
  *
  *
- * Last changed in libpng 1.6.24 [August 4, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -189,6 +189,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
       png_crc_read(png_ptr, chunk_tag, 4);
       png_crc_read(png_ptr, chunk_tag, 4);
       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+      png_check_chunk_length(png_ptr, png_ptr->push_length);
       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    }
    }
 
 

+ 132 - 20
libpng.mod/pngpriv.h

@@ -1,8 +1,8 @@
 
 
 /* pngpriv.h - private declarations for use inside libpng
 /* pngpriv.h - private declarations for use inside libpng
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -35,7 +35,9 @@
  * Windows/Visual Studio) there is no effect; the OS specific tests below are
  * Windows/Visual Studio) there is no effect; the OS specific tests below are
  * still required (as of 2011-05-02.)
  * 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
 #ifndef PNG_VERSION_INFO_ONLY
 /* Standard library headers not required by png.h: */
 /* Standard library headers not required by png.h: */
@@ -190,6 +192,50 @@
 #  endif
 #  endif
 #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
+#      endif
+#   endif
+#endif
+
+#if PNG_INTEL_SSE_OPT > 0
+#   ifndef PNG_INTEL_SSE_IMPLEMENTATION
+#      if defined(__SSE4_1__) || defined(__AVX__)
+          /* We are not actually using AVX, but checking for AVX is the best
+             way we can detect SSE4.1 and SSSE3 on MSVC.
+          */
+#         define PNG_INTEL_SSE_IMPLEMENTATION 3
+#      elif defined(__SSSE3__)
+#         define PNG_INTEL_SSE_IMPLEMENTATION 2
+#      elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
+       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
+#         define PNG_INTEL_SSE_IMPLEMENTATION 1
+#      else
+#         define PNG_INTEL_SSE_IMPLEMENTATION 0
+#      endif
+#   endif
+
+#   if PNG_INTEL_SSE_IMPLEMENTATION > 0
+#      define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
+#   endif
+#endif
+
 #if PNG_MIPS_MSA_OPT > 0
 #if PNG_MIPS_MSA_OPT > 0
 #  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
 #  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
 #  ifndef PNG_MIPS_MSA_IMPLEMENTATION
 #  ifndef PNG_MIPS_MSA_IMPLEMENTATION
@@ -210,6 +256,11 @@
 #  endif
 #  endif
 #endif /* PNG_MIPS_MSA_OPT > 0 */
 #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
 /* 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
  * different preprocessor settings to those required for a simple library?  If
@@ -403,6 +454,21 @@
 #  define png_fixed_error(s1,s2) png_err(s1)
 #  define png_fixed_error(s1,s2) png_err(s1)
 #endif
 #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
 /* 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
  * 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
  * explicit, static, cast and provides the static_cast<> rune to ensure that
@@ -417,25 +483,20 @@
    static_cast<type>(static_cast<const void*>(value))
    static_cast<type>(static_cast<const void*>(value))
 #else
 #else
 #  define png_voidcast(type, value) (value)
 #  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_aligncast(type, value) ((void*)(value))
 #  define png_aligncastconst(type, value) ((const void*)(value))
 #  define png_aligncastconst(type, value) ((const void*)(value))
 #endif /* __cplusplus */
 #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) ||\
 #if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
     defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
     defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
    /* png.c requires the following ANSI-C constants if the conversion of
    /* png.c requires the following ANSI-C constants if the conversion of
@@ -781,6 +842,7 @@
 #define png_PLTE PNG_U32( 80,  76,  84,  69)
 #define png_PLTE PNG_U32( 80,  76,  84,  69)
 #define png_bKGD PNG_U32( 98,  75,  71,  68)
 #define png_bKGD PNG_U32( 98,  75,  71,  68)
 #define png_cHRM PNG_U32( 99,  72,  82,  77)
 #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_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
 #define png_gAMA PNG_U32(103,  65,  77,  65)
 #define png_gAMA PNG_U32(103,  65,  77,  65)
 #define png_gIFg PNG_U32(103,  73,  70, 103)
 #define png_gIFg PNG_U32(103,  73,  70, 103)
@@ -1081,6 +1143,11 @@ PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
     int intent),PNG_EMPTY);
     int intent),PNG_EMPTY);
 #endif
 #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
 #ifdef PNG_WRITE_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
 PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
    png_const_charp name, png_const_bytep profile), PNG_EMPTY);
    png_const_charp name, png_const_bytep profile), PNG_EMPTY);
@@ -1256,6 +1323,38 @@ 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);
     row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
 #endif
 #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 */
 /* Choose the best filter to use and filter the row data */
 PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
 PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
     png_row_infop row_info),PNG_EMPTY);
     png_row_infop row_info),PNG_EMPTY);
@@ -1348,6 +1447,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 #endif
 #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
 #ifdef PNG_READ_gAMA_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
 PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
@@ -1423,8 +1527,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 #endif
 #endif
 
 
-PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
-    png_uint_32 chunk_name),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
+    const png_uint_32 chunk_name),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
+    const png_uint_32 chunk_length),PNG_EMPTY);
 
 
 PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
 PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
     png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
@@ -1991,6 +2098,11 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
 #endif
 #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
 #endif
 
 
 PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
 PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,

+ 30 - 8
libpng.mod/pngread.c

@@ -1,8 +1,8 @@
 
 
 /* pngread.c - read a PNG file
 /* pngread.c - read a PNG file
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -175,6 +175,11 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
          png_handle_cHRM(png_ptr, info_ptr, length);
          png_handle_cHRM(png_ptr, info_ptr, length);
 #endif
 #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
 #ifdef PNG_READ_gAMA_SUPPORTED
       else if (chunk_name == png_gAMA)
       else if (chunk_name == png_gAMA)
          png_handle_gAMA(png_ptr, info_ptr, length);
          png_handle_gAMA(png_ptr, info_ptr, length);
@@ -534,6 +539,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
       png_error(png_ptr, "Invalid attempt to read row data");
       png_error(png_ptr, "Invalid attempt to read row data");
 
 
    /* Fill the row with IDAT 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);
    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_NONE)
@@ -842,6 +848,11 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
          png_handle_cHRM(png_ptr, info_ptr, length);
          png_handle_cHRM(png_ptr, info_ptr, length);
 #endif
 #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
 #ifdef PNG_READ_gAMA_SUPPORTED
       else if (chunk_name == png_gAMA)
       else if (chunk_name == png_gAMA)
          png_handle_gAMA(png_ptr, info_ptr, length);
          png_handle_gAMA(png_ptr, info_ptr, length);
@@ -1883,7 +1894,7 @@ png_create_colormap_entry(png_image_read_control *display,
          {
          {
             case 4:
             case 4:
                entry[afirst ? 0 : 3] = (png_uint_16)alpha;
                entry[afirst ? 0 : 3] = (png_uint_16)alpha;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
 
             case 3:
             case 3:
                if (alpha < 65535)
                if (alpha < 65535)
@@ -1905,7 +1916,7 @@ png_create_colormap_entry(png_image_read_control *display,
 
 
             case 2:
             case 2:
                entry[1 ^ afirst] = (png_uint_16)alpha;
                entry[1 ^ afirst] = (png_uint_16)alpha;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
 
 
             case 1:
             case 1:
                if (alpha < 65535)
                if (alpha < 65535)
@@ -1934,6 +1945,7 @@ png_create_colormap_entry(png_image_read_control *display,
          {
          {
             case 4:
             case 4:
                entry[afirst ? 0 : 3] = (png_byte)alpha;
                entry[afirst ? 0 : 3] = (png_byte)alpha;
+               /* FALLTHROUGH */
             case 3:
             case 3:
                entry[afirst + (2 ^ bgr)] = (png_byte)blue;
                entry[afirst + (2 ^ bgr)] = (png_byte)blue;
                entry[afirst + 1] = (png_byte)green;
                entry[afirst + 1] = (png_byte)green;
@@ -1942,6 +1954,7 @@ png_create_colormap_entry(png_image_read_control *display,
 
 
             case 2:
             case 2:
                entry[1 ^ afirst] = (png_byte)alpha;
                entry[1 ^ afirst] = (png_byte)alpha;
+               /* FALLTHROUGH */
             case 1:
             case 1:
                entry[afirst] = (png_byte)green;
                entry[afirst] = (png_byte)green;
                break;
                break;
@@ -2861,7 +2874,7 @@ png_image_read_colormap(png_voidp argument)
       case P_sRGB:
       case P_sRGB:
          /* Change to 8-bit sRGB */
          /* Change to 8-bit sRGB */
          png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
          png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
-         /* FALL THROUGH */
+         /* FALLTHROUGH */
 
 
       case P_FILE:
       case P_FILE:
          if (png_ptr->bit_depth > 8)
          if (png_ptr->bit_depth > 8)
@@ -3179,8 +3192,7 @@ png_image_read_colormapped(png_voidp argument)
             image->colormap_entries == 244 /* 216 + 1 + 27 */)
             image->colormap_entries == 244 /* 216 + 1 + 27 */)
             break;
             break;
 
 
-         /* goto bad_output; */
-         /* FALL THROUGH */
+         goto bad_output;
 
 
       default:
       default:
       bad_output:
       bad_output:
@@ -3747,7 +3759,13 @@ png_image_read_direct(png_voidp argument)
          mode = PNG_ALPHA_PNG;
          mode = PNG_ALPHA_PNG;
          output_gamma = PNG_DEFAULT_sRGB;
          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
       /* If 'do_local_background' is set check for the presence of gamma
        * correction; this is part of the work-round for the libpng bug
        * correction; this is part of the work-round for the libpng bug
        * described above.
        * described above.
@@ -3973,6 +3991,10 @@ png_image_read_direct(png_voidp argument)
       else if (do_local_compose != 0) /* internal error */
       else if (do_local_compose != 0) /* internal error */
          png_error(png_ptr, "png_image_read: alpha channel lost");
          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)
       if (info_ptr->bit_depth == 16)
          info_format |= PNG_FORMAT_FLAG_LINEAR;
          info_format |= PNG_FORMAT_FLAG_LINEAR;
 
 

+ 23 - 18
libpng.mod/pngrtran.c

@@ -1,8 +1,8 @@
 
 
 /* pngrtran.c - transforms the data in a row for PNG readers
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
  *
- * Last changed in libpng 1.6.24 [August 4, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -49,6 +49,7 @@ 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 */
       case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
          png_warning(png_ptr,
          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_ERROR_QUIT:                                /* Error/quit */
 
 
       case PNG_CRC_DEFAULT:
       case PNG_CRC_DEFAULT:
@@ -429,7 +430,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
       int i;
       int i;
 
 
       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
-          (png_uint_32)((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++)
       for (i = 0; i < num_palette; i++)
          png_ptr->quantize_index[i] = (png_byte)i;
          png_ptr->quantize_index[i] = (png_byte)i;
    }
    }
@@ -446,7 +447,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
 
 
          /* Initialize an array to sort colors */
          /* Initialize an array to sort colors */
          png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
          png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)((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 */
          /* Initialize the quantize_sort array */
          for (i = 0; i < num_palette; i++)
          for (i = 0; i < num_palette; i++)
@@ -580,9 +581,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
 
 
          /* Initialize palette index arrays */
          /* Initialize palette index arrays */
          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)((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_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
-             (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte))));
+             (png_alloc_size_t)((png_uint_32)num_palette *
+             (sizeof (png_byte))));
 
 
          /* Initialize the sort array */
          /* Initialize the sort array */
          for (i = 0; i < num_palette; i++)
          for (i = 0; i < num_palette; i++)
@@ -591,7 +594,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
             png_ptr->palette_to_index[i] = (png_byte)i;
             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))));
              (sizeof (png_dsortp))));
 
 
          num_new_palette = num_palette;
          num_new_palette = num_palette;
@@ -622,7 +625,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
                   {
                   {
 
 
                      t = (png_dsortp)png_malloc_warn(png_ptr,
                      t = (png_dsortp)png_malloc_warn(png_ptr,
-                         (png_uint_32)(sizeof (png_dsort)));
+                         (png_alloc_size_t)(sizeof (png_dsort)));
 
 
                      if (t == NULL)
                      if (t == NULL)
                          break;
                          break;
@@ -747,9 +750,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
       png_size_t num_entries = ((png_size_t)1 << total_bits);
       png_size_t num_entries = ((png_size_t)1 << total_bits);
 
 
       png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
       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))));
           (sizeof (png_byte))));
 
 
       memset(distance, 0xff, num_entries * (sizeof (png_byte)));
       memset(distance, 0xff, num_entries * (sizeof (png_byte)));
@@ -1253,7 +1256,7 @@ png_init_rgb_transformations(png_structrp png_ptr)
             default:
             default:
 
 
             case 8:
             case 8:
-               /* FALL THROUGH (Already 8 bits) */
+               /* FALLTHROUGH */ /*  (Already 8 bits) */
 
 
             case 16:
             case 16:
                /* Already a full 16 bits */
                /* Already a full 16 bits */
@@ -2934,7 +2937,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
  * 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
  * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
  * versions dated 1998 through November 2002 have been archived at
  * 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 )
  * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
  * Charles Poynton poynton at poynton.com
  * Charles Poynton poynton at poynton.com
  *
  *
@@ -3321,7 +3324,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
                             == png_ptr->trans_color.gray)
                             == png_ptr->trans_color.gray)
                         {
                         {
                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
-                           tmp |= 
+                           tmp |=
                               (unsigned int)(png_ptr->background.gray << shift);
                               (unsigned int)(png_ptr->background.gray << shift);
                            *sp = (png_byte)(tmp & 0xff);
                            *sp = (png_byte)(tmp & 0xff);
                         }
                         }
@@ -4302,7 +4305,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
             if (num_trans > 0)
             if (num_trans > 0)
             {
             {
                sp = row + (png_size_t)row_width - 1;
                sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 2) - 1;
+               dp = row + ((png_size_t)row_width << 2) - 1;
 
 
                for (i = 0; i < row_width; i++)
                for (i = 0; i < row_width; i++)
                {
                {
@@ -4463,7 +4466,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
             {
             {
                gray = gray & 0xff;
                gray = gray & 0xff;
                sp = row + (png_size_t)row_width - 1;
                sp = row + (png_size_t)row_width - 1;
-               dp = row + (png_size_t)(row_width << 1) - 1;
+               dp = row + ((png_size_t)row_width << 1) - 1;
 
 
                for (i = 0; i < row_width; i++)
                for (i = 0; i < row_width; i++)
                {
                {
@@ -4519,7 +4522,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
             png_byte green = (png_byte)(trans_color->green & 0xff);
             png_byte green = (png_byte)(trans_color->green & 0xff);
             png_byte blue = (png_byte)(trans_color->blue & 0xff);
             png_byte blue = (png_byte)(trans_color->blue & 0xff);
             sp = row + (png_size_t)row_info->rowbytes - 1;
             sp = row + (png_size_t)row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 2) - 1;
+            dp = row + ((png_size_t)row_width << 2) - 1;
             for (i = 0; i < row_width; i++)
             for (i = 0; i < row_width; i++)
             {
             {
                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
@@ -4542,7 +4545,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
             png_byte green_low = (png_byte)(trans_color->green & 0xff);
             png_byte green_low = (png_byte)(trans_color->green & 0xff);
             png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
             png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
             sp = row + row_info->rowbytes - 1;
             sp = row + row_info->rowbytes - 1;
-            dp = row + (png_size_t)(row_width << 3) - 1;
+            dp = row + ((png_size_t)row_width << 3) - 1;
             for (i = 0; i < row_width; i++)
             for (i = 0; i < row_width; i++)
             {
             {
                if (*(sp - 5) == red_high &&
                if (*(sp - 5) == red_high &&
@@ -4601,7 +4604,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 *sp = row + row_info->rowbytes; /* source, last byte + 1 */
       png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
       png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
       while (dp > sp)
       while (dp > sp)
-         dp[-2] = dp[-1] = *--sp, dp -= 2;
+      {
+         dp[-2] = dp[-1] = *--sp; dp -= 2;
+      }
 
 
       row_info->rowbytes *= 2;
       row_info->rowbytes *= 2;
       row_info->bit_depth = 16;
       row_info->bit_depth = 16;

+ 170 - 47
libpng.mod/pngrutil.c

@@ -1,8 +1,8 @@
 
 
 /* pngrutil.c - utilities to read a PNG file
 /* pngrutil.c - utilities to read a PNG file
  *
  *
- * Last changed in libpng 1.6.27 [December 29, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -181,6 +181,9 @@ png_read_chunk_header(png_structrp png_ptr)
    /* Check to see if chunk name is valid. */
    /* Check to see if chunk name is valid. */
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    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
 #ifdef PNG_IO_STATE_SUPPORTED
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
 #endif
 #endif
@@ -311,6 +314,7 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
 
 
       if (buffer != NULL)
       if (buffer != NULL)
       {
       {
+         memset(buffer, 0, new_size); /* just in case */
          png_ptr->read_buffer = buffer;
          png_ptr->read_buffer = buffer;
          png_ptr->read_buffer_size = new_size;
          png_ptr->read_buffer_size = new_size;
       }
       }
@@ -418,7 +422,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
             png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
             png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
       }
       }
 
 
-#if ZLIB_VERNUM >= 0x1281 && \
+#if ZLIB_VERNUM >= 0x1290 && \
    defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
    defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
       if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
       if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
          /* Turn off validation of the ADLER32 checksum in IDAT chunks */
          /* Turn off validation of the ADLER32 checksum in IDAT chunks */
@@ -670,6 +674,8 @@ png_decompress_chunk(png_structrp png_ptr,
 
 
                if (text != NULL)
                if (text != NULL)
                {
                {
+                  memset(text, 0, buffer_size);
+
                   ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
                   ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
                       png_ptr->read_buffer + prefix_size, &lzsize,
                       png_ptr->read_buffer + prefix_size, &lzsize,
                       text + prefix_size, newlength);
                       text + prefix_size, newlength);
@@ -733,9 +739,7 @@ png_decompress_chunk(png_structrp png_ptr,
             {
             {
                /* inflateReset failed, store the error message */
                /* inflateReset failed, store the error message */
                png_zstream_error(png_ptr, ret);
                png_zstream_error(png_ptr, ret);
-
-               if (ret == Z_STREAM_END)
-                  ret = PNG_UNEXPECTED_ZLIB_RETURN;
+               ret = PNG_UNEXPECTED_ZLIB_RETURN;
             }
             }
          }
          }
 
 
@@ -1377,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
     * 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
     * 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.
     * 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_crc_finish(png_ptr, length);
       png_chunk_benign_error(png_ptr, "too short");
       png_chunk_benign_error(png_ptr, "too short");
@@ -1413,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);
       png_crc_read(png_ptr, (png_bytep)keyword, read_length);
       length -= 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;
       keyword_length = 0;
       while (keyword_length < 80 && keyword_length < read_length &&
       while (keyword_length < 80 && keyword_length < read_length &&
          keyword[keyword_length] != 0)
          keyword[keyword_length] != 0)
@@ -1431,7 +1447,7 @@ 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)
             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];
                Byte local_buffer[PNG_INFLATE_BUF_SIZE];
                png_alloc_size_t size = (sizeof profile_header);
                png_alloc_size_t size = (sizeof profile_header);
 
 
@@ -1461,7 +1477,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                         /* Now read the tag table; a variable size buffer is
                         /* Now read the tag table; a variable size buffer is
                          * needed at this point, allocate one for the whole
                          * needed at this point, allocate one for the whole
                          * profile.  The header check has already validated
                          * 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(
                         const png_uint_32 tag_count = png_get_uint_32(
                             profile_header+128);
                             profile_header+128);
@@ -1568,19 +1584,11 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
                                        return;
                                        return;
                                     }
                                     }
                                  }
                                  }
-
-                                 else if (size > 0)
-                                    errmsg = "truncated";
-
-#ifndef __COVERITY__
-                                 else
+                                 if (errmsg == NULL)
                                     errmsg = png_ptr->zstream.msg;
                                     errmsg = png_ptr->zstream.msg;
-#endif
                               }
                               }
-
                               /* else png_icc_check_tag_table output an error */
                               /* else png_icc_check_tag_table output an error */
                            }
                            }
-
                            else /* profile truncated */
                            else /* profile truncated */
                               errmsg = png_ptr->zstream.msg;
                               errmsg = png_ptr->zstream.msg;
                         }
                         }
@@ -2009,6 +2017,69 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 }
 }
 #endif
 #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
 #ifdef PNG_READ_hIST_SUPPORTED
 void /* PRIVATE */
 void /* PRIVATE */
 png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
 png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
@@ -2537,6 +2608,9 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
    if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
       png_ptr->mode |= PNG_AFTER_IDAT;
       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*/);
    buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
 
 
    if (buffer == NULL)
    if (buffer == NULL)
@@ -2583,23 +2657,28 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
       {
       {
          png_text text;
          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
       else
@@ -2975,7 +3054,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
          case 2:
          case 2:
             png_ptr->user_chunk_cache_max = 1;
             png_ptr->user_chunk_cache_max = 1;
             png_chunk_benign_error(png_ptr, "no space in chunk cache");
             png_chunk_benign_error(png_ptr, "no space in chunk cache");
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
          case 1:
          case 1:
             /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
             /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
              * chunk being skipped, now there will be a hard error below.
              * chunk being skipped, now there will be a hard error below.
@@ -2984,7 +3063,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
 
 
          default: /* not at limit */
          default: /* not at limit */
             --(png_ptr->user_chunk_cache_max);
             --(png_ptr->user_chunk_cache_max);
-            /* FALL THROUGH */
+            /* FALLTHROUGH */
          case 0: /* no limit */
          case 0: /* no limit */
 #  endif /* USER_LIMITS */
 #  endif /* USER_LIMITS */
             /* Here when the limit isn't reached or when limits are compiled
             /* Here when the limit isn't reached or when limits are compiled
@@ -3035,20 +3114,58 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
  */
  */
 
 
 void /* PRIVATE */
 void /* PRIVATE */
-png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
+png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name)
 {
 {
    int i;
    int i;
+   png_uint_32 cn=chunk_name;
 
 
    png_debug(1, "in png_check_chunk_name");
    png_debug(1, "in png_check_chunk_name");
 
 
    for (i=1; i<=4; ++i)
    for (i=1; i<=4; ++i)
    {
    {
-      int c = chunk_name & 0xff;
+      int c = cn & 0xff;
 
 
       if (c < 65 || c > 122 || (c > 90 && c < 97))
       if (c < 65 || c > 122 || (c > 90 && c < 97))
          png_chunk_error(png_ptr, "invalid chunk type");
          png_chunk_error(png_ptr, "invalid chunk type");
 
 
-      chunk_name >>= 8;
+      cn >>= 8;
+   }
+}
+
+void /* PRIVATE */
+png_check_chunk_length(png_const_structrp png_ptr, const 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 =
+         (png_ptr->width * 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");
    }
    }
 }
 }
 
 
@@ -3377,7 +3494,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
                 */
                 */
                do
                do
                {
                {
-                  dp[0] = sp[0], dp[1] = sp[1];
+                  dp[0] = sp[0]; dp[1] = sp[1];
 
 
                   if (row_width <= bytes_to_jump)
                   if (row_width <= bytes_to_jump)
                      return;
                      return;
@@ -3398,7 +3515,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
                 */
                 */
                for (;;)
                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)
                   if (row_width <= bytes_to_jump)
                      return;
                      return;
@@ -3887,7 +4004,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
       /* Find the best predictor, the least of pa, pb, pc favoring the earlier
        * ones in the case of a tie.
        * 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;
       if (pc < pa) a = c;
 
 
       /* Calculate the current pixel in a, and move the previous row pixel to c
       /* Calculate the current pixel in a, and move the previous row pixel to c
@@ -3939,7 +4059,10 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
       pc = (p + pc) < 0 ? -(p + pc) : p + pc;
       pc = (p + pc) < 0 ? -(p + pc) : p + pc;
 #endif
 #endif
 
 
-      if (pb < pa) pa = pb, a = b;
+      if (pb < pa)
+      {
+         pa = pb; a = b;
+      }
       if (pc < pa) a = c;
       if (pc < pa) a = c;
 
 
       a += *row;
       a += *row;

+ 57 - 6
libpng.mod/pngset.c

@@ -1,8 +1,8 @@
 
 
 /* pngset.c - storage of image information into info struct
 /* pngset.c - storage of image information into info struct
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -134,6 +134,53 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
 
 
 #endif /* cHRM */
 #endif /* cHRM */
 
 
+#ifdef PNG_eXIf_SUPPORTED
+void PNGAPI
+png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
+    const 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,
+    const png_uint_32 num_exif, const 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
 #ifdef PNG_gAMA_SUPPORTED
 void PNGFAPI
 void PNGFAPI
 png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
 png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
@@ -1102,8 +1149,9 @@ png_set_sPLT(png_const_structrp png_ptr,
       info_ptr->valid |= PNG_INFO_sPLT;
       info_ptr->valid |= PNG_INFO_sPLT;
       ++(info_ptr->splt_palettes_num);
       ++(info_ptr->splt_palettes_num);
       ++np;
       ++np;
+      ++entries;
    }
    }
-   while (++entries, --nentries);
+   while (--nentries);
 
 
    if (nentries > 0)
    if (nentries > 0)
       png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
       png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
@@ -1354,6 +1402,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
       static PNG_CONST png_byte chunks_to_ignore[] = {
       static PNG_CONST png_byte chunks_to_ignore[] = {
          98,  75,  71,  68, '\0',  /* bKGD */
          98,  75,  71,  68, '\0',  /* bKGD */
          99,  72,  82,  77, '\0',  /* cHRM */
          99,  72,  82,  77, '\0',  /* cHRM */
+        101,  88,  73, 102, '\0',  /* eXIf */
         103,  65,  77,  65, '\0',  /* gAMA */
         103,  65,  77,  65, '\0',  /* gAMA */
         104,  73,  83,  84, '\0',  /* hIST */
         104,  73,  83,  84, '\0',  /* hIST */
         105,  67,  67,  80, '\0',  /* iCCP */
         105,  67,  67,  80, '\0',  /* iCCP */
@@ -1696,14 +1745,16 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
       png_byte ch = (png_byte)*key++;
       png_byte ch = (png_byte)*key++;
 
 
       if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
       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)
       else if (space == 0)
       {
       {
          /* A space or an invalid character when one wasn't seen immediately
          /* A space or an invalid character when one wasn't seen immediately
           * before; output just a space.
           * 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 the character was not a space then it is invalid. */
          if (ch != 32)
          if (ch != 32)
@@ -1716,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 */
    if (key_len > 0 && space != 0) /* trailing space */
    {
    {
-      --key_len, --new_key;
+      --key_len; --new_key;
       if (bad_character == 0)
       if (bad_character == 0)
          bad_character = 32;
          bad_character = 32;
    }
    }

+ 3 - 3
libpng.mod/pngstruct.h

@@ -1,8 +1,8 @@
 
 
 /* pngstruct.h - header file for PNG reference library
 /* pngstruct.h - header file for PNG reference library
  *
  *
- * Last changed in libpng 1.6.24 [August 4, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -353,7 +353,7 @@ struct png_struct_def
 
 
 /* Options */
 /* Options */
 #ifdef PNG_SET_OPTION_SUPPORTED
 #ifdef PNG_SET_OPTION_SUPPORTED
-   png_byte options;           /* On/off state (up to 4 options) */
+   png_uint_32 options;           /* On/off state (up to 16 options) */
 #endif
 #endif
 
 
 #if PNG_LIBPNG_VER < 10700
 #if PNG_LIBPNG_VER < 10700

+ 79 - 14
libpng.mod/pngtest.c

@@ -1,8 +1,8 @@
 
 
 /* pngtest.c - a simple test program to test libpng
 /* pngtest.c - a simple test program to test libpng
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -144,6 +144,7 @@ tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t)
 static int verbose = 0;
 static int verbose = 0;
 static int strict = 0;
 static int strict = 0;
 static int relaxed = 0;
 static int relaxed = 0;
+static int xfail = 0;
 static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
 static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
 static int error_count = 0; /* count calls to png_error */
 static int error_count = 0; /* count calls to png_error */
 static int warning_count = 0; /* count calls to png_warning */
 static int warning_count = 0; /* count calls to png_warning */
@@ -463,7 +464,7 @@ pngtest_warning(png_structp png_ptr, png_const_charp message)
    if (test != NULL && test->file_name != NULL)
    if (test != NULL && test->file_name != NULL)
       name = test->file_name;
       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
 /* This is the default error handling function.  Note that replacements for
@@ -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);
       fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
       png_free(read_ptr, row_buf);
       png_free(read_ptr, row_buf);
       row_buf = NULL;
       row_buf = NULL;
+      if (verbose != 0)
+        fprintf(STDERR, "   destroy read structs\n");
       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
       png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
 #ifdef PNG_WRITE_SUPPORTED
 #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_info_struct(write_ptr, &write_end_info_ptr);
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
 #endif
 #endif
@@ -952,11 +957,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
    if (setjmp(png_jmpbuf(write_ptr)))
    if (setjmp(png_jmpbuf(write_ptr)))
    {
    {
       fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
       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);
       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);
       png_destroy_info_struct(write_ptr, &write_end_info_ptr);
-#ifdef PNG_WRITE_SUPPORTED
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
       png_destroy_write_struct(&write_ptr, &write_info_ptr);
-#endif
       FCLOSE(fpin);
       FCLOSE(fpin);
       FCLOSE(fpout);
       FCLOSE(fpout);
       return (1);
       return (1);
@@ -1192,6 +1199,22 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       }
       }
    }
    }
 #endif
 #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
 #ifdef PNG_hIST_SUPPORTED
    {
    {
       png_uint_16p hist;
       png_uint_16p hist;
@@ -1302,10 +1325,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          {
          {
             int i;
             int i;
 
 
-            printf("\n");
+            fprintf(STDERR,"\n");
             for (i=0; i<num_text; i++)
             for (i=0; i<num_text; i++)
             {
             {
-               printf("   Text compression[%d]=%d\n",
+               fprintf(STDERR,"   Text compression[%d]=%d\n",
                    i, text_ptr[i].compression);
                    i, text_ptr[i].compression);
             }
             }
          }
          }
@@ -1398,6 +1421,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
 
 
    write_chunks(write_ptr, before_IDAT); /* after PLTE */
    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
 #ifdef PNG_COMPRESSION_COMPAT
    /* Test the 'compatibility' setting here, if it is available. */
    /* Test the 'compatibility' setting here, if it is available. */
    png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT);
    png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT);
@@ -1518,10 +1545,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
          {
          {
             int i;
             int i;
 
 
-            printf("\n");
+            fprintf(STDERR,"\n");
             for (i=0; i<num_text; i++)
             for (i=0; i<num_text; i++)
             {
             {
-               printf("   Text compression[%d]=%d\n",
+               fprintf(STDERR,"   Text compression[%d]=%d\n",
                    i, text_ptr[i].compression);
                    i, text_ptr[i].compression);
             }
             }
          }
          }
@@ -1530,6 +1557,22 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
       }
       }
    }
    }
 #endif
 #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
 #ifdef PNG_tIME_SUPPORTED
    {
    {
       png_timep mod_time;
       png_timep mod_time;
@@ -1845,6 +1888,7 @@ main(int argc, char *argv[])
          inname = argv[2];
          inname = argv[2];
          strict++;
          strict++;
          relaxed = 0;
          relaxed = 0;
+         multiple=1;
       }
       }
 
 
       else if (strcmp(argv[1], "--relaxed") == 0)
       else if (strcmp(argv[1], "--relaxed") == 0)
@@ -1854,6 +1898,17 @@ main(int argc, char *argv[])
          inname = argv[2];
          inname = argv[2];
          strict = 0;
          strict = 0;
          relaxed++;
          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
       else
@@ -1911,8 +1966,13 @@ main(int argc, char *argv[])
 
 
          else
          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 defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
          if (allocation_now != current_allocation)
          if (allocation_now != current_allocation)
@@ -2000,8 +2060,13 @@ main(int argc, char *argv[])
 #endif
 #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 defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
          if (allocation_now != current_allocation)
          if (allocation_now != current_allocation)
@@ -2088,4 +2153,4 @@ main(void)
 #endif
 #endif
 
 
 /* Generate a compiler error if there is an old png.h in the search path. */
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_27 Your_png_h_is_not_version_1_6_27;
+typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34;

BIN
libpng.mod/pngtest.png


+ 28 - 14
libpng.mod/pngtrans.c

@@ -1,8 +1,8 @@
 
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -514,11 +514,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
          if (at_start != 0) /* Skip initial filler */
          if (at_start != 0) /* Skip initial filler */
             ++sp;
             ++sp;
          else          /* Skip initial channel and, for sp, the filler */
          else          /* Skip initial channel and, for sp, the filler */
-            sp += 2, ++dp;
+         {
+            sp += 2; ++dp;
+         }
 
 
          /* For a 1 pixel wide image there is nothing to do */
          /* For a 1 pixel wide image there is nothing to do */
          while (sp < ep)
          while (sp < ep)
-            *dp++ = *sp, sp += 2;
+         {
+            *dp++ = *sp; sp += 2;
+         }
 
 
          row_info->pixel_depth = 8;
          row_info->pixel_depth = 8;
       }
       }
@@ -528,10 +532,14 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
          if (at_start != 0) /* Skip initial filler */
          if (at_start != 0) /* Skip initial filler */
             sp += 2;
             sp += 2;
          else          /* Skip initial channel and, for sp, the filler */
          else          /* Skip initial channel and, for sp, the filler */
-            sp += 4, dp += 2;
+         {
+            sp += 4; dp += 2;
+         }
 
 
          while (sp < ep)
          while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+         {
+            *dp++ = *sp++; *dp++ = *sp; sp += 3;
+         }
 
 
          row_info->pixel_depth = 16;
          row_info->pixel_depth = 16;
       }
       }
@@ -554,11 +562,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
          if (at_start != 0) /* Skip initial filler */
          if (at_start != 0) /* Skip initial filler */
             ++sp;
             ++sp;
          else          /* Skip initial channels and, for sp, the filler */
          else          /* Skip initial channels and, for sp, the filler */
-            sp += 4, dp += 3;
+         {
+            sp += 4; dp += 3;
+         }
 
 
          /* Note that the loop adds 3 to dp and 4 to sp each time. */
          /* Note that the loop adds 3 to dp and 4 to sp each time. */
          while (sp < ep)
          while (sp < ep)
-            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
+         {
+            *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
+         }
 
 
          row_info->pixel_depth = 24;
          row_info->pixel_depth = 24;
       }
       }
@@ -568,14 +580,16 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
          if (at_start != 0) /* Skip initial filler */
          if (at_start != 0) /* Skip initial filler */
             sp += 2;
             sp += 2;
          else          /* Skip initial channels and, for sp, the filler */
          else          /* Skip initial channels and, for sp, the filler */
-            sp += 8, dp += 6;
+         {
+            sp += 8; dp += 6;
+         }
 
 
          while (sp < ep)
          while (sp < ep)
          {
          {
             /* Copy 6 bytes, skip 2 */
             /* Copy 6 bytes, skip 2 */
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp++;
-            *dp++ = *sp++, *dp++ = *sp, sp += 3;
+            *dp++ = *sp++; *dp++ = *sp++;
+            *dp++ = *sp++; *dp++ = *sp++;
+            *dp++ = *sp++; *dp++ = *sp; sp += 3;
          }
          }
 
 
          row_info->pixel_depth = 48;
          row_info->pixel_depth = 48;
@@ -595,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
       return; /* The filler channel has gone already */
       return; /* The filler channel has gone already */
 
 
    /* Fix the rowbytes value. */
    /* Fix the rowbytes value. */
-   row_info->rowbytes = (unsigned int)(dp-row);
+   row_info->rowbytes = (png_size_t)(dp-row);
 }
 }
 #endif
 #endif
 
 
@@ -694,7 +708,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
        * forms produced on either GCC or MSVC.
        * forms produced on either GCC or MSVC.
        */
        */
       int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
       int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
-      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
+      png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
 
 
       switch (row_info->bit_depth)
       switch (row_info->bit_depth)
       {
       {

+ 17 - 6
libpng.mod/pngwrite.c

@@ -1,8 +1,8 @@
 
 
 /* pngwrite.c - general routines to write a PNG file
 /* pngwrite.c - general routines to write a PNG file
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -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);
       png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
 #endif
 #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
 #ifdef PNG_WRITE_hIST_SUPPORTED
    if ((info_ptr->valid & PNG_INFO_hIST) != 0)
    if ((info_ptr->valid & PNG_INFO_hIST) != 0)
       png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
       png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
@@ -432,6 +437,12 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
          }
          }
       }
       }
 #endif
 #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
 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
       write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
       write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
 #endif
 #endif
@@ -1007,8 +1018,8 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
          case 5:
          case 5:
          case 6:
          case 6:
          case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
          case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
-            /* FALL THROUGH */
 #endif /* WRITE_FILTER */
 #endif /* WRITE_FILTER */
+            /* FALLTHROUGH */
          case PNG_FILTER_VALUE_NONE:
          case PNG_FILTER_VALUE_NONE:
             png_ptr->do_filter = PNG_FILTER_NONE; break;
             png_ptr->do_filter = PNG_FILTER_NONE; break;
 
 
@@ -1875,7 +1886,7 @@ png_image_set_PLTE(png_image_write_control *display)
                tRNS[i] = entry[afirst ? 0 : 3];
                tRNS[i] = entry[afirst ? 0 : 3];
                if (tRNS[i] < 255)
                if (tRNS[i] < 255)
                   num_trans = i+1;
                   num_trans = i+1;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
             case 3:
             case 3:
                palette[i].blue = entry[afirst + (2 ^ bgr)];
                palette[i].blue = entry[afirst + (2 ^ bgr)];
                palette[i].green = entry[afirst + 1];
                palette[i].green = entry[afirst + 1];
@@ -1886,7 +1897,7 @@ png_image_set_PLTE(png_image_write_control *display)
                tRNS[i] = entry[1 ^ afirst];
                tRNS[i] = entry[1 ^ afirst];
                if (tRNS[i] < 255)
                if (tRNS[i] < 255)
                   num_trans = i+1;
                   num_trans = i+1;
-               /* FALL THROUGH */
+               /* FALLTHROUGH */
             case 1:
             case 1:
                palette[i].blue = palette[i].red = palette[i].green =
                palette[i].blue = palette[i].red = palette[i].green =
                   entry[afirst];
                   entry[afirst];
@@ -1929,7 +1940,7 @@ png_image_write_main(png_voidp argument)
    int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
    int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
    int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
    int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
    int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
    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
 #   ifdef PNG_BENIGN_ERRORS_SUPPORTED
       /* Make sure we error out on any bad situation */
       /* Make sure we error out on any bad situation */

+ 40 - 11
libpng.mod/pngwutil.c

@@ -1,8 +1,8 @@
 
 
 /* pngwutil.c - utilities to write a PNG file
 /* pngwutil.c - utilities to write a PNG file
  *
  *
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  *
@@ -675,6 +675,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
     int interlace_type)
     int interlace_type)
 {
 {
    png_byte buf[13]; /* Buffer to store the IHDR info */
    png_byte buf[13]; /* Buffer to store the IHDR info */
+   int is_invalid_depth;
 
 
    png_debug(1, "in png_write_IHDR");
    png_debug(1, "in png_write_IHDR");
 
 
@@ -700,11 +701,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
          break;
          break;
 
 
       case PNG_COLOR_TYPE_RGB:
       case PNG_COLOR_TYPE_RGB:
+         is_invalid_depth = (bit_depth != 8);
 #ifdef PNG_WRITE_16BIT_SUPPORTED
 #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
 #endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for RGB image");
             png_error(png_ptr, "Invalid bit depth for RGB image");
 
 
          png_ptr->channels = 3;
          png_ptr->channels = 3;
@@ -726,18 +727,22 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
          break;
          break;
 
 
       case PNG_COLOR_TYPE_GRAY_ALPHA:
       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_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
 
 
          png_ptr->channels = 2;
          png_ptr->channels = 2;
          break;
          break;
 
 
       case PNG_COLOR_TYPE_RGB_ALPHA:
       case PNG_COLOR_TYPE_RGB_ALPHA:
+         is_invalid_depth = (bit_depth != 8);
 #ifdef PNG_WRITE_16BIT_SUPPORTED
 #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
 #endif
+         if (is_invalid_depth)
             png_error(png_ptr, "Invalid bit depth for RGBA image");
             png_error(png_ptr, "Invalid bit depth for RGBA image");
 
 
          png_ptr->channels = 4;
          png_ptr->channels = 4;
@@ -998,7 +1003,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
                optimize_cmf(data, png_image_size(png_ptr));
                optimize_cmf(data, png_image_size(png_ptr));
 #endif
 #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->mode |= PNG_HAVE_IDAT;
 
 
          png_ptr->zstream.next_out = data;
          png_ptr->zstream.next_out = data;
@@ -1044,7 +1050,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
             optimize_cmf(data, png_image_size(png_ptr));
             optimize_cmf(data, png_image_size(png_ptr));
 #endif
 #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.avail_out = 0;
          png_ptr->zstream.next_out = NULL;
          png_ptr->zstream.next_out = NULL;
          png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
          png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@@ -1466,6 +1473,28 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
 }
 }
 #endif
 #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, (png_size_t)1);
+   }
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
 #ifdef PNG_WRITE_hIST_SUPPORTED
 #ifdef PNG_WRITE_hIST_SUPPORTED
 /* Write the histogram */
 /* Write the histogram */
 void /* PRIVATE */
 void /* PRIVATE */

+ 767 - 0
libpng.mod/powerpc/filter_vsx_intrinsics.c

@@ -0,0 +1,767 @@
+/* filter_vsx_intrinsics.c - PowerPC optimised filter functions
+ *
+ * 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
+ */
+#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;\
+   png_size_t unaligned_top = 16 - (((png_size_t)rp % 16));\
+   png_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)
+{
+   const 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)
+{
+   const 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)
+{
+   const 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)
+{
+  const 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)
+{
+   const 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)
+{
+  const 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 */

+ 125 - 0
libpng.mod/powerpc/powerpc_init.c

@@ -0,0 +1,125 @@
+
+/* powerpc_init.c - POWERPC optimised filter functions
+ *
+ * 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
+ */
+/* 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 */