[master] Imported from libpng-1.6.17.tar
diff --git a/ANNOUNCE b/ANNOUNCE
index c514daf..131e0aa 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,4 +1,4 @@
-Libpng 1.6.16 - December 22, 2014
+Libpng 1.6.17 - March 26, 2015
 
 This is a public release of libpng, intended for use in production codes.
 
@@ -7,30 +7,61 @@
 Source files with LF line endings (for Unix/Linux) and with a
 "configure" script
 
-   libpng-1.6.16.tar.xz (LZMA-compressed, recommended)
-   libpng-1.6.16.tar.gz
+   libpng-1.6.17.tar.xz (LZMA-compressed, recommended)
+   libpng-1.6.17.tar.gz
 
 Source files with CRLF line endings (for Windows), without the
 "configure" script
 
-   lpng1616.7z  (LZMA-compressed, recommended)
-   lpng1616.zip
+   lpng1617.7z  (LZMA-compressed, recommended)
+   lpng1617.zip
 
 Other information:
 
-   libpng-1.6.16-README.txt
-   libpng-1.6.16-LICENSE.txt
-   libpng-1.6.16-*.asc (armored detached GPG signatures)
+   libpng-1.6.17-README.txt
+   libpng-1.6.17-LICENSE.txt
+   libpng-1.6.17-*.asc (armored detached GPG signatures)
 
-Changes since the last public release (1.6.15):
-  Added ".align 2" to arm/filter_neon.S to support old GAS assemblers that
-    don't do alignment correctly.
-  Revised Makefile.am and scripts/*.dfn to work with MinGW/MSYS;
-    renamed scripts/*.dfn to scripts/*.c (Bob Friesenhahn and John Bowler).
-  Quiet a "comparison always true" warning in pngstest.c (John Bowler).
-  Restored a test on width that was removed from png.c at libpng-1.6.9
-    (Bug report by Alex Eubanks).
-  Fixed an overflow in png_combine_row with very wide interlaced images.
+Changes since the last public release (1.6.16):
+
+  Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h
+  Corrected the width limit calculation in png_check_IHDR().
+  Removed user limits from pngfix. Also pass NULL pointers to
+    png_read_row to skip the unnecessary row de-interlace stuff.
+  Added testing of png_set_packing() to pngvalid.c
+  Regenerated configure scripts in the *.tar distributions with libtool-2.4.4
+  Implement previously untested cases of libpng transforms in pngvalid.c
+  Fixed byte order in 2-byte filler, in png_do_read_filler().
+  Made the check for out-of-range values in png_set_tRNS() detect
+    values that are exactly 2^bit_depth, and work on 16-bit platforms.
+  Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47.
+  Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and
+    pngset.c to avoid warnings about dead code.
+  Do not build png_product2() when it is unused.
+  Display user limits in the output from pngtest.
+  Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column
+    and 1-million-row default limits in pnglibconf.dfa, that can be reset
+    by the user at build time or run time.  This provides a more robust
+    defense against DOS and as-yet undiscovered overflows.
+  Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default.
+  Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins).
+  Rebuilt configure scripts with automake-1.15 and libtool-2.4.6
+  Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block
+    of png.h.
+  Avoid runtime checks when converting integer to png_byte with
+    Visual Studio (Sergey Kosarevsky)
+  Removed some comments that the configure script did not handle
+    properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt.
+  Free the unknown_chunks structure even when it contains no data.
+  Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF
+    for consistency, and remove some useless tests (Alexey Petruchik).
+  Remove pnglibconf.h, pnglibconf.c, pnglibconf.pre, pnglibconf.dfn,
+    and pnglibconf.out instead of pnglibconf.* in "make clean" (Cosmin).
+  Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha
+    value was wrong.  It's not clear if this affected the final stored
+    value; in the obvious code path the upper and lower 8-bits of the
+    alpha value were identical and the alpha was truncated to 8-bits
+    rather than dividing by 257 (John Bowler).
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index 68a80a5..1be09e9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2102,7 +2102,7 @@
     png_decompress_chunk(), and remove "chunkdata" from parameter list.
   Put a call to png_check_chunk_name() in png_read_chunk_header().
   Revised png_check_chunk_name() to reject a name with a lowercase 3rd byte.
-  Removed two calls to png_check_chunk_name() occuring later in the process.
+  Removed two calls to png_check_chunk_name() occurring later in the process.
   Define PNG_NO_ERROR_NUMBERS by default in pngconf.h
 
 Version 1.4.0beta25 [July 30, 2008]
@@ -5114,17 +5114,97 @@
 
 Version 1.6.16rc01 [December 21, 2014]
   Restored a test on width that was removed from png.c at libpng-1.6.9
-    (Bug report by Alex Eubanks).
+    (Bug report by Alex Eubanks, CVE-2015-0973).
 
 Version 1.6.16rc02 [December 21, 2014]
   Undid the update to pngrutil.c in 1.6.16rc01.
 
 Version 1.6.16rc03 [December 21, 2014]
-  Fixed an overflow in png_combine_row with very wide interlaced images.
+  Fixed an overflow in png_combine_row() with very wide interlaced images
+    (Bug report and fix by John Bowler, CVE-2014-9495).
 
 Version 1.6.16 [December 22, 2014]
   No changes.
 
+Version 1.6.17beta01 [January 29, 2015]
+  Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h
+  Corrected the width limit calculation in png_check_IHDR().
+  Removed user limits from pngfix. Also pass NULL pointers to
+    png_read_row to skip the unnecessary row de-interlace stuff.
+  Added testing of png_set_packing() to pngvalid.c
+  Regenerated configure scripts in the *.tar distributions with libtool-2.4.4
+  Implement previously untested cases of libpng transforms in pngvalid.c
+  Fixed byte order in 2-byte filler, in png_do_read_filler().
+  Made the check for out-of-range values in png_set_tRNS() detect
+    values that are exactly 2^bit_depth, and work on 16-bit platforms.
+  Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47.
+  Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and
+    pngset.c to avoid warnings about dead code.
+  Added "& 0xff" to many instances of expressions that are typecast
+    to (png_byte), to avoid Coverity gripes.
+
+Version 1.6.17beta02 [February 7, 2015]
+  Work around one more Coverity-scan dead-code warning.
+  Do not build png_product2() when it is unused.
+
+Version 1.6.17beta03 [February 17, 2015]
+  Display user limits in the output from pngtest.
+  Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column
+    and 1-million-row default limits in pnglibconf.dfa, that can be reset
+    by the user at build time or run time.  This provides a more robust
+    defense against DOS and as-yet undiscovered overflows.
+
+Version 1.6.17beta04 [February 21, 2015]
+  Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default.
+  Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins).
+  Rebuilt configure scripts with automake-1.15 and libtool-2.4.6
+
+Version 1.6.17beta05 [February 25, 2015]
+  Restored compiling of png_reciprocal2 with PNG_NO_16BIT.
+
+Version 1.6.17beta06 [February 27, 2015]
+  Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block
+    of png.h.
+  Avoid runtime checks when converting integer to png_byte with
+    Visual Studio (Sergey Kosarevsky)
+
+Version 1.6.17rc01 [March 4, 2015]
+  No changes.
+
+Version 1.6.17rc02 [March 9, 2015]
+  Removed some comments that the configure script did not handle
+    properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt.
+  Free the unknown_chunks structure even when it contains no data.
+
+Version 1.6.17rc03 [March 12, 2015]
+  Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF
+    for consistency, and remove some useless tests (Alexey Petruchik).
+
+Version 1.6.17rc04 [March 16, 2015]
+  Remove pnglibconf.h, pnglibconf.c, and pnglibconf.out instead of
+    pnglibconf.* in "make clean" (Cosmin).
+  Fix bug in calculation of maxbits, in png_write_sBIT, introduced
+    in libpng-1.6.17beta01 (John Bowler).
+
+Version 1.6.17rc05 [March 21, 2015]
+  Define PNG_FILTER_* and PNG_FILTER_VALUE_* in png.h even when WRITE
+    is not supported (John Bowler).  This fixes an error introduced in
+    libpng-1.6.17beta06.
+  Reverted "& 0xff" additions of version 1.6.17beta01. Libpng passes
+    the Coverity scan without them.
+
+Version 1.6.17rc06 [March 23, 2015]
+  Remove pnglibconf.dfn and pnglibconf.pre with "make clean".
+  Reformatted some "&0xff" instances to "& 0xff".
+  Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha
+    value was wrong.  It's not clear if this affected the final stored
+    value; in the obvious code path the upper and lower 8-bits of the
+    alpha value were identical and the alpha was truncated to 8-bits
+    rather than dividing by 257 (John Bowler).
+
+Version 1.6.17 [March 26, 2015]
+  No changes.
+
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 28d1ca7..f062a23 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 # CMakeLists.txt
 
-# Copyright (C) 2007-2014 Glenn Randers-Pehrson
+# Copyright (C) 2007-2015 Glenn Randers-Pehrson
 
 # This code is released under the libpng license.
 # For conditions of distribution and use, see the disclaimer
@@ -16,7 +16,7 @@
 
 set(PNGLIB_MAJOR 1)
 set(PNGLIB_MINOR 6)
-set(PNGLIB_RELEASE 16)
+set(PNGLIB_RELEASE 17)
 set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
 set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
 
@@ -30,8 +30,7 @@
     PATHS /usr/lib /usr/local/lib
   )
   if(NOT M_LIBRARY)
-    message(STATUS
-      "math library 'libm' not found - floating point support disabled")
+    message(STATUS "math lib 'libm' not found; floating point support disabled")
   endif()
 else()
   # not needed on windows
@@ -39,22 +38,14 @@
 endif()
 
 # COMMAND LINE OPTIONS
-if(DEFINED PNG_SHARED)
-  option(PNG_SHARED "Build shared lib" ${PNG_SHARED})
-else()
-  option(PNG_SHARED "Build shared lib" ON)
-endif()
-if(DEFINED PNG_STATIC)
-  option(PNG_STATIC "Build static lib" ${PNG_STATIC})
-else()
-  option(PNG_STATIC "Build static lib" ON)
-endif()
-
-option(PNG_TESTS  "Build libpng tests" YES)
+option(PNG_SHARED "Build shared lib" ON)
+option(PNG_STATIC "Build static lib" ON)
+option(PNG_TESTS  "Build libpng tests" ON)
 
 # Many more configuration options could be added here
-option(PNG_DEBUG         "Build with debug output" NO)
-option(PNGARG            "Disable ANSI-C prototypes" NO)
+option(PNG_FRAMEWORK "Build OS X framework" OFF)
+option(PNG_DEBUG     "Build with debug output" OFF)
+option(PNGARG        "Disable ANSI-C prototypes" OFF)
 
 # SET LIBNAME
 set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
@@ -134,7 +125,7 @@
 endif()
 
 if(PNG_STATIC)
-# does not work without changing name
+  # does not work without changing name
   set(PNG_LIB_NAME_STATIC ${PNG_LIB_NAME}_static)
   add_library(${PNG_LIB_NAME_STATIC} STATIC ${libpng_sources})
   list(APPEND PNG_LIB_TARGETS ${PNG_LIB_NAME_STATIC})
@@ -145,10 +136,27 @@
   target_link_libraries(${PNG_LIB_NAME_STATIC} ${ZLIB_LIBRARY} ${M_LIBRARY})
 endif()
 
+if(PNG_FRAMEWORK)
+  set(PNG_LIB_NAME_FRAMEWORK ${PNG_LIB_NAME}_framework)
+  add_library(${PNG_LIB_NAME_FRAMEWORK} SHARED ${libpng_sources})
+  list(APPEND PNG_LIB_TARGETS ${PNG_LIB_NAME_FRAMEWORK})
+  set_target_properties(${PNG_LIB_NAME_FRAMEWORK} PROPERTIES
+    FRAMEWORK TRUE
+    FRAMEWORK_VERSION ${PNGLIB_VERSION}
+    MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PNGLIB_MAJOR}.${PNGLIB_MINOR}
+    MACOSX_FRAMEWORK_BUNDLE_VERSION ${PNGLIB_VERSION}
+    MACOSX_FRAMEWORK_IDENTIFIER org.libpng.libpng
+    XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
+    PUBLIC_HEADER "${libpng_public_hdrs}"
+    OUTPUT_NAME png)
+  target_link_libraries(${PNG_LIB_NAME_FRAMEWORK} ${ZLIB_LIBRARY} ${M_LIBRARY})
+endif()
+
 if(NOT PNG_LIB_TARGETS)
   message(SEND_ERROR
     "No library variant selected to build. "
-    "Please enable at least one of the following options: PNG_STATIC, PNG_SHARED")
+    "Please enable at least one of the following options: "
+    " PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK")
 endif()
 
 if(PNG_SHARED AND WIN32)
@@ -253,7 +261,7 @@
 # SET UP LINKS
 if(PNG_SHARED)
   set_target_properties(${PNG_LIB_NAME} PROPERTIES
-#   VERSION 16.${PNGLIB_RELEASE}.1.6.16
+#   VERSION 16.${PNGLIB_RELEASE}.1.6.17
     VERSION 16.${PNGLIB_RELEASE}.0
     SOVERSION 16
     CLEAN_DIRECT_OUTPUT 1)
@@ -284,7 +292,8 @@
       ${PNG_EXPORT_RULE}
       RUNTIME DESTINATION bin
       LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
   if(PNG_SHARED)
     # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
diff --git a/INSTALL b/INSTALL
index 61ea591..a294ffe 100644
--- a/INSTALL
+++ b/INSTALL
@@ -17,7 +17,7 @@
  XII. Configuring for compiler xxx:
 XIII. Removing unwanted object code
  XIV. Changes to the build and configuration of libpng in libpng-1.5.x
-  XV. Configuring libpng for multiprocessing
+  XV. Setjmp/longjmp issues
  XVI. Other sources of information about libpng
 
 I. Simple installation
@@ -189,7 +189,7 @@
 VIII. Configuring libpng for 16-bit platforms
 
 You will want to look into zconf.h to tell zlib (and thus libpng) that
-it cannot allocate more then 64K at a time.  Even if you can, the memory
+it cannot allocate more than 64K at a time.  Even if you can, the memory
 won't be accessible.  So limit zlib and libpng to 64K by defining MAXSEG_64K.
 
 IX. Configuring for DOS
@@ -362,7 +362,7 @@
 libpng, because than the settings would not accurately reflect the settings
 that were used to build libpng.
 
-XV. Configuring libpng for multiprocessing
+XV. Setjmp/longjmp issues
 
 Libpng uses setjmp()/longjmp() for error handling.  Unfortunately setjmp()
 is known to be not thread-safe on some platforms and we don't know of
@@ -375,6 +375,11 @@
 
 in your pnglibconf.h or pngusr.h.
 
+Starting with libpng-1.6.0, the library included a "simplified API".
+This requires setjmp/longjmp, so you must either build the library
+with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED
+and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined.
+
 XVI. Other sources of information about libpng:
 
 Further information can be found in the README and libpng-manual.txt
diff --git a/LICENSE b/LICENSE
index f912f6a..eb4a9a9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -10,8 +10,8 @@
 
 This code is released under the libpng license.
 
-libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are
-Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are
+libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are
+Copyright (c) 2004, 2006-2015 Glenn Randers-Pehrson, and are
 distributed according to the same disclaimer and license as libpng-1.2.5
 with the following individual added to the list of Contributing Authors
 
@@ -108,4 +108,4 @@
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-December 22, 2014
+March 26, 2015
diff --git a/Makefile.am b/Makefile.am
index a9e8d3c..ac5f95c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -129,11 +129,12 @@
 	$(TESTS) $(XFAIL_TESTS) tests/pngstest \
 	CMakeLists.txt example.c libpng-manual.txt
 
-SCRIPT_CLEANFILES=scripts/*.out scripts/*.chk scripts/pnglibconf.c
+SCRIPT_CLEANFILES=scripts/*.out scripts/*.chk
 
 CLEANFILES= *.tf? pngout.png libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc \
 	libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config libpng.vers libpng.sym \
-	check.new pnglibconf.* pngprefix.h symbols.new pngtest-log.txt \
+	check.new pnglibconf.h pngprefix.h symbols.new pngtest-log.txt \
+	pnglibconf.out pnglibconf.c pnglibconf.pre pnglibconf.dfn \
 	$(SCRIPT_CLEANFILES)
 
 MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in \
diff --git a/README b/README
index 8c5b0b2..a158ea8 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.16 - December 22, 2014 (shared library 16.0)
+README for libpng version 1.6.17 - March 26, 2015 (shared library 16.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
diff --git a/configure.ac b/configure.ac
index c99a4d9..1c46ca2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,7 +18,7 @@
 
 dnl Version number stuff here:
 
-AC_INIT([libpng],[1.6.16],[png-mng-implement@lists.sourceforge.net])
+AC_INIT([libpng],[1.6.17],[png-mng-implement@lists.sourceforge.net])
 AC_CONFIG_MACRO_DIR([scripts])
 
 # libpng does not follow GNU file name conventions (hence 'foreign')
@@ -39,10 +39,10 @@
 dnl AM_PREREQ([1.11.2])
 dnl stop configure from automagically running automake
 
-PNGLIB_VERSION=1.6.16
+PNGLIB_VERSION=1.6.17
 PNGLIB_MAJOR=1
 PNGLIB_MINOR=6
-PNGLIB_RELEASE=16
+PNGLIB_RELEASE=17
 
 dnl End of version number stuff
 
diff --git a/contrib/libtests/pngunknown.c b/contrib/libtests/pngunknown.c
index b8c4899..309ee60 100644
--- a/contrib/libtests/pngunknown.c
+++ b/contrib/libtests/pngunknown.c
@@ -1242,4 +1242,4 @@
    /* So the test is skipped: */
    return 77;
 }
-#endif /* SET_UNKNOWN_CHUNKS && READ*/
+#endif /* SET_UNKNOWN_CHUNKS && READ */
diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c
index a93fe65..79de125 100644
--- a/contrib/libtests/pngvalid.c
+++ b/contrib/libtests/pngvalid.c
@@ -1,8 +1,8 @@
 
 /* pngvalid.c - validate libpng by constructing then reading png files.
  *
- * Last changed in libpng 1.6.14 [October 23, 2014]
- * Copyright (c) 2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 2014-2015 Glenn Randers-Pehrson
  * Written by John Cunningham Bowler
  *
  * This code is released under the libpng license.
@@ -278,7 +278,8 @@
    return x % max; /* 0 .. max-1 */
 }
 
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+#if (defined PNG_READ_RGB_TO_GRAY_SUPPORTED) ||\
+    (defined PNG_READ_FILLER_SUPPORTED)
 static int
 random_choice(void)
 {
@@ -303,7 +304,7 @@
 #define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))
 #define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))
 #define PALETTE_FROM_ID(id) (((id) >> 8) & 0x1f)
-#define INTERLACE_FROM_ID(id) ((int)(((id) >> 13) & 0x3))
+#define INTERLACE_FROM_ID(id) ((png_byte)(((id) >> 13) & 0x3))
 #define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))
 #define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)
 #define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)
@@ -440,7 +441,7 @@
 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
 static unsigned int
 sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,
-    png_uint_32 x, unsigned int sample_index)
+    png_uint_32 x, unsigned int sample_index, int swap16, int littleendian)
 {
    png_uint_32 bit_index, result;
 
@@ -469,11 +470,23 @@
       return result;
 
    else if (bit_depth > 8)
-      return (result << 8) + *++row;
+   {
+      if (swap16)
+         return (*++row << 8) + result;
+      else
+         return (result << 8) + *++row;
+   }
 
-   /* Less than 8 bits per sample. */
+   /* Less than 8 bits per sample.  By default PNG has the big end of
+    * the egg on the left of the screen, but if littleendian is set
+    * then the big end is on the right.
+    */
    bit_index &= 7;
-   return (result >> (8-bit_index-bit_depth)) & ((1U<<bit_depth)-1);
+
+   if (!littleendian)
+      bit_index = 8-bit_index-bit_depth;
+
+   return (result >> bit_index) & ((1U<<bit_depth)-1);
 }
 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
 
@@ -1565,7 +1578,7 @@
 
          else
 #     endif
-         ps->pwrite = png_create_write_struct(png_get_libpng_ver(NULL),
+         ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,
             ps, store_error, store_warning);
 
       png_set_write_fn(ps->pwrite, ps, store_write, store_flush);
@@ -3172,10 +3185,10 @@
       for (; i<256; ++i)
          tRNS[i] = 24;
 
-#  ifdef PNG_WRITE_tRNS_SUPPORTED
+#     ifdef PNG_WRITE_tRNS_SUPPORTED
          if (j > 0)
             png_set_tRNS(pp, pi, tRNS, j, 0/*color*/);
-#  endif
+#     endif
    }
 }
 
@@ -4263,7 +4276,8 @@
    png_byte    green_sBIT;
    png_byte    blue_sBIT;
    png_byte    alpha_sBIT;
-   int         interlace_type;
+   png_byte    interlace_type;
+   png_byte    filler;         /* Output has a filler */
    png_uint_32 id;             /* Calculated file ID */
    png_uint_32 w;              /* Width of image */
    png_uint_32 h;              /* Height of image */
@@ -4650,8 +4664,16 @@
     png_const_infop pi, int nImages)
 {
    /* Record cbRow now that it can be found. */
-   dp->pixel_size = bit_size(pp, png_get_color_type(pp, pi),
-      png_get_bit_depth(pp, pi));
+   {
+      png_byte ct = png_get_color_type(pp, pi);
+      png_byte bd = png_get_bit_depth(pp, pi);
+
+      if (bd >= 8 && (ct == PNG_COLOR_TYPE_RGB || ct == PNG_COLOR_TYPE_GRAY) &&
+          dp->filler)
+          ct |= 4; /* handle filler as faked alpha channel */
+
+      dp->pixel_size = bit_size(pp, ct, bd);
+   }
    dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size;
    dp->cbRow = png_get_rowbytes(pp, pi);
 
@@ -5291,10 +5313,17 @@
     */
    unsigned int red, green, blue, alpha; /* For non-palette images. */
    unsigned int palette_index;           /* For a palette image. */
-   png_byte colour_type;                 /* As in the spec. */
-   png_byte bit_depth;                   /* Defines bit size in row */
-   png_byte sample_depth;                /* Scale of samples */
-   int      have_tRNS;                   /* tRNS chunk may need processing */
+   png_byte     colour_type;             /* As in the spec. */
+   png_byte     bit_depth;               /* Defines bit size in row */
+   png_byte     sample_depth;            /* Scale of samples */
+   unsigned int have_tRNS :1;            /* tRNS chunk may need processing */
+   unsigned int swap_rgb :1;             /* RGB swapped to BGR */
+   unsigned int alpha_first :1;          /* Alpha at start, not end */
+   unsigned int alpha_inverted :1;       /* Alpha channel inverted */
+   unsigned int mono_inverted :1;        /* Gray channel inverted */
+   unsigned int swap16 :1;               /* Byte swap 16-bit components */
+   unsigned int littleendian :1;         /* High bits on right */
+   unsigned int sig_bits :1;             /* Pixel shifted (sig bits only) */
 
    /* For checking the code calculates double precision floating point values
     * along with an error value, accumulated from the transforms.  Because an
@@ -5302,6 +5331,9 @@
     * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each
     * channel is stored.  This sBIT value is folded in to the stored error value
     * at the end of the application of the transforms to the pixel.
+    *
+    * If sig_bits is set above the red, green, blue and alpha values have been
+    * scaled so they only contain the significant bits of the component values.
     */
    double   redf, greenf, bluef, alphaf;
    double   rede, greene, bluee, alphae;
@@ -5310,26 +5342,27 @@
 
 /* Shared utility function, see below. */
 static void
-image_pixel_setf(image_pixel *this, unsigned int max)
+image_pixel_setf(image_pixel *this, unsigned int rMax, unsigned int gMax,
+        unsigned int bMax, unsigned int aMax)
 {
-   this->redf = this->red / (double)max;
-   this->greenf = this->green / (double)max;
-   this->bluef = this->blue / (double)max;
-   this->alphaf = this->alpha / (double)max;
+   this->redf = this->red / (double)rMax;
+   this->greenf = this->green / (double)gMax;
+   this->bluef = this->blue / (double)bMax;
+   this->alphaf = this->alpha / (double)aMax;
 
-   if (this->red < max)
+   if (this->red < rMax)
       this->rede = this->redf * DBL_EPSILON;
    else
       this->rede = 0;
-   if (this->green < max)
+   if (this->green < gMax)
       this->greene = this->greenf * DBL_EPSILON;
    else
       this->greene = 0;
-   if (this->blue < max)
+   if (this->blue < bMax)
       this->bluee = this->bluef * DBL_EPSILON;
    else
       this->bluee = 0;
-   if (this->alpha < max)
+   if (this->alpha < aMax)
       this->alphae = this->alphaf * DBL_EPSILON;
    else
       this->alphae = 0;
@@ -5341,18 +5374,22 @@
  */
 static void
 image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
-    png_byte bit_depth, png_uint_32 x, store_palette palette)
+    png_byte bit_depth, png_uint_32 x, store_palette palette,
+    PNG_CONST image_pixel *format /*from pngvalid transform of input*/)
 {
    PNG_CONST png_byte sample_depth = (png_byte)(colour_type ==
       PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
    PNG_CONST unsigned int max = (1U<<sample_depth)-1;
+   PNG_CONST int swap16 = (format != 0 && format->swap16);
+   PNG_CONST int littleendian = (format != 0 && format->littleendian);
+   PNG_CONST int sig_bits = (format != 0 && format->sig_bits);
 
    /* Initially just set everything to the same number and the alpha to opaque.
     * Note that this currently assumes a simple palette where entry x has colour
     * rgb(x,x,x)!
     */
    this->palette_index = this->red = this->green = this->blue =
-      sample(row, colour_type, bit_depth, x, 0);
+      sample(row, colour_type, bit_depth, x, 0, swap16, littleendian);
    this->alpha = max;
    this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT =
       sample_depth;
@@ -5376,21 +5413,52 @@
    {
       unsigned int i = 0;
 
+      if ((colour_type & 4) != 0 && format != 0 && format->alpha_first)
+      {
+         this->alpha = this->red;
+         /* This handles the gray case for 'AG' pixels */
+         this->palette_index = this->red = this->green = this->blue =
+            sample(row, colour_type, bit_depth, x, 1, swap16, littleendian);
+         i = 1;
+      }
+
       if (colour_type & 2)
       {
-         this->green = sample(row, colour_type, bit_depth, x, 1);
-         this->blue = sample(row, colour_type, bit_depth, x, 2);
-         i = 2;
+         /* Green is second for both BGR and RGB: */
+         this->green = sample(row, colour_type, bit_depth, x, ++i, swap16,
+                 littleendian);
+
+         if (format != 0 && format->swap_rgb) /* BGR */
+             this->red = sample(row, colour_type, bit_depth, x, ++i, swap16,
+                     littleendian);
+         else
+             this->blue = sample(row, colour_type, bit_depth, x, ++i, swap16,
+                     littleendian);
       }
-      if (colour_type & 4)
-         this->alpha = sample(row, colour_type, bit_depth, x, ++i);
+
+      else /* grayscale */ if (format != 0 && format->mono_inverted)
+         this->red = this->green = this->blue = this->red ^ max;
+
+      if ((colour_type & 4) != 0) /* alpha */
+      {
+         if (format == 0 || !format->alpha_first)
+             this->alpha = sample(row, colour_type, bit_depth, x, ++i, swap16,
+                     littleendian);
+
+         if (format != 0 && format->alpha_inverted)
+            this->alpha ^= max;
+      }
    }
 
    /* Calculate the scaled values, these are simply the values divided by
     * 'max' and the error is initialized to the double precision epsilon value
     * from the header file.
     */
-   image_pixel_setf(this, max);
+   image_pixel_setf(this,
+      sig_bits ? (1U << format->red_sBIT)-1 : max,
+      sig_bits ? (1U << format->green_sBIT)-1 : max,
+      sig_bits ? (1U << format->blue_sBIT)-1 : max,
+      sig_bits ? (1U << format->alpha_sBIT)-1 : max);
 
    /* Store the input information for use in the transforms - these will
     * modify the information.
@@ -5399,6 +5467,13 @@
    this->bit_depth = bit_depth;
    this->sample_depth = sample_depth;
    this->have_tRNS = 0;
+   this->swap_rgb = 0;
+   this->alpha_first = 0;
+   this->alpha_inverted = 0;
+   this->mono_inverted = 0;
+   this->swap16 = 0;
+   this->littleendian = 0;
+   this->sig_bits = 0;
 }
 
 /* Convert a palette image to an rgb image.  This necessarily converts the tRNS
@@ -5560,6 +5635,7 @@
    /* Local variables */
    png_byte output_colour_type;
    png_byte output_bit_depth;
+   png_byte unpacked;
 
    /* Modifications (not necessarily used.) */
    gama_modification gama_mod;
@@ -5635,6 +5711,7 @@
     png_const_structp pp, PNG_CONST transform_display *display)
 {
    PNG_CONST unsigned int scale = (1U<<that->sample_depth)-1;
+   PNG_CONST int sig_bits = that->sig_bits;
 
    UNUSED(this)
    UNUSED(pp)
@@ -5649,6 +5726,13 @@
     */
    that->red = sample_scale(that->redf, scale);
 
+   /* This is a bit bogus; really the above calculation should use the red_sBIT
+    * value, not sample_depth, but because libpng does png_set_shift by just
+    * shifting the bits we get errors if we don't do it the same way.
+    */
+   if (sig_bits && that->red_sBIT < that->sample_depth)
+      that->red >>= that->sample_depth - that->red_sBIT;
+
    /* The error value is increased, at the end, according to the lowest sBIT
     * value seen.  Common sense tells us that the intermediate integer
     * representations are no more accurate than +/- 0.5 in the integral values,
@@ -5664,7 +5748,13 @@
    if (that->colour_type & PNG_COLOR_MASK_COLOR)
    {
       that->green = sample_scale(that->greenf, scale);
+      if (sig_bits && that->green_sBIT < that->sample_depth)
+         that->green >>= that->sample_depth - that->green_sBIT;
+
       that->blue = sample_scale(that->bluef, scale);
+      if (sig_bits && that->blue_sBIT < that->sample_depth)
+         that->blue >>= that->sample_depth - that->blue_sBIT;
+
       that->greene += 1./(2*((1U<<that->green_sBIT)-1));
       that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));
    }
@@ -5684,9 +5774,12 @@
    else
    {
       that->alpha = scale; /* opaque */
-      that->alpha = 1;     /* Override this. */
+      that->alphaf = 1;    /* Override this. */
       that->alphae = 0;    /* It's exact ;-) */
    }
+
+   if (sig_bits && that->alpha_sBIT < that->sample_depth)
+      that->alpha >>= that->sample_depth - that->alpha_sBIT;
 }
 
 /* Static 'end' structure: */
@@ -5724,6 +5817,7 @@
    /* Local variable fields */
    dp->output_colour_type = 255; /* invalid */
    dp->output_bit_depth = 255;  /* invalid */
+   dp->unpacked = 0; /* not unpacked */
 }
 
 static void
@@ -5751,6 +5845,13 @@
    dp->output_colour_type = png_get_color_type(pp, pi);
    dp->output_bit_depth = png_get_bit_depth(pp, pi);
 
+   /* If png_set_filler is in action then fake the output color type to include
+    * an alpha channel where appropriate.
+    */
+   if (dp->output_bit_depth >= 8 && (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
+       dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
+       dp->output_colour_type |= 4;
+
    /* Validate the combination of colour type and bit depth that we are getting
     * out of libpng; the semantics of something not in the PNG spec are, at
     * best, unclear.
@@ -5785,7 +5886,8 @@
    }
 
    /* Use a test pixel to check that the output agrees with what we expect -
-    * this avoids running the whole test if the output is unexpected.
+    * this avoids running the whole test if the output is unexpected.  This also
+    * checks for internal errors.
     */
    {
       image_pixel test_pixel;
@@ -5800,7 +5902,7 @@
       /* Don't need sBIT here, but it must be set to non-zero to avoid
        * arithmetic overflows.
        */
-      test_pixel.have_tRNS = dp->this.is_transparent;
+      test_pixel.have_tRNS = dp->this.is_transparent != 0;
       test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT =
          test_pixel.alpha_sBIT = test_pixel.sample_depth;
 
@@ -5831,22 +5933,41 @@
       }
 
       /* If both bit depth and colour type are correct check the sample depth.
-       * I believe these are both internal errors.
        */
-      if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         if (test_pixel.sample_depth != 8) /* oops - internal error! */
-            png_error(pp, "pngvalid: internal: palette sample depth not 8");
-      }
-      else if (test_pixel.sample_depth != dp->output_bit_depth)
+      if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE &&
+          test_pixel.sample_depth != 8) /* oops - internal error! */
+         png_error(pp, "pngvalid: internal: palette sample depth not 8");
+      else if (dp->unpacked && test_pixel.bit_depth != 8)
+         png_error(pp, "pngvalid: internal: bad unpacked pixel depth");
+      else if (!dp->unpacked && test_pixel.colour_type != PNG_COLOR_TYPE_PALETTE
+              && test_pixel.bit_depth != test_pixel.sample_depth)
       {
          char message[128];
          size_t pos = safecat(message, sizeof message, 0,
             "internal: sample depth ");
 
+         /* Because unless something has set 'unpacked' or the image is palette
+          * mapped we expect the transform to keep sample depth and bit depth
+          * the same.
+          */
+         pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);
+         pos = safecat(message, sizeof message, pos, " expected ");
+         pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
+
+         png_error(pp, message);
+      }
+      else if (test_pixel.bit_depth != dp->output_bit_depth)
+      {
+         /* This could be a libpng error too; libpng has not produced what we
+          * expect for the output bit depth.
+          */
+         char message[128];
+         size_t pos = safecat(message, sizeof message, 0,
+            "internal: bit depth ");
+
          pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
          pos = safecat(message, sizeof message, pos, " expected ");
-         pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);
+         pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
 
          png_error(pp, message);
       }
@@ -5993,13 +6114,14 @@
          unsigned int r, g, b, a;
 
          /* Find out what we think the pixel should be: */
-         image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette);
+         image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette,
+                 NULL);
 
          in_pixel.red_sBIT = red_sBIT;
          in_pixel.green_sBIT = green_sBIT;
          in_pixel.blue_sBIT = blue_sBIT;
          in_pixel.alpha_sBIT = alpha_sBIT;
-         in_pixel.have_tRNS = have_tRNS;
+         in_pixel.have_tRNS = have_tRNS != 0;
 
          /* For error detection, below. */
          r = in_pixel.red;
@@ -6007,12 +6129,18 @@
          b = in_pixel.blue;
          a = in_pixel.alpha;
 
+         /* This applies the transforms to the input date, including output
+          * format operations which must be used when reading the output
+          * pixel that libpng produces.
+          */
          dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp);
 
          /* Read the output pixel and compare it to what we got, we don't
-          * use the error field here, so no need to update sBIT.
+          * use the error field here, so no need to update sBIT.  in_pixel
+          * says whether we expect libpng to change the output format.
           */
-         image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette);
+         image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette,
+                 &in_pixel);
 
          /* We don't expect changes to the index here even if the bit depth is
           * changed.
@@ -6793,14 +6921,14 @@
           *  conversion adds another +/-2 in the 16-bit case and
           *  +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case.
           */
-         that->pm->limit +=
-#        if PNG_MAX_GAMMA_8 < 14
-               pow((that->this.bit_depth == 16 ?
-                  8. : 6. + (1<<(15-PNG_MAX_GAMMA_8)))/65535, data.gamma);
-#        else
-               pow((that->this.bit_depth == 16 ?
-                  8. : 8. + (1<<(15-PNG_MAX_GAMMA_8)))/65535, data.gamma);
-#        endif
+         that->pm->limit += pow(
+#           if PNG_MAX_GAMMA_8 < 14
+               (that->this.bit_depth == 16 ? 8. :
+                  6. + (1<<(15-PNG_MAX_GAMMA_8)))
+#           else
+               8.
+#           endif
+               /65535, data.gamma);
       }
 
       else
@@ -6812,18 +6940,18 @@
           * When DIGITIZE is set because a pre-1.7 version of libpng is being
           * tested allow a bigger slack.
           *
-          * NOTE: this magic number was determined by experiment to be 1.1 (when
-          * using fixed point arithmetic).  There's no great merit to the value
-          * below, however it only affects the limit used for checking for
-          * internal calculation errors, not the actual limit imposed by
-          * pngvalid on the output errors.
+          * NOTE: this magic number was determined by experiment to be 1.25.
+          * There's no great merit to the value below, however it only affects
+          * the limit used for checking for internal calculation errors, not
+          * the actual limit imposed by pngvalid on the output errors.
           */
-         that->pm->limit +=
+         that->pm->limit += pow(
 #        if DIGITIZE
-             pow(1.1 /255, data.gamma);
+            1.25
 #        else
-             pow(1.0 /255, data.gamma);
+            1.0
 #        endif
+            /255, data.gamma);
       }
    }
 
@@ -7306,7 +7434,7 @@
    }
 
    image_pixel_init(&data, random_bytes, colour_type,
-      bit_depth, 0/*x*/, 0/*unused: palette*/);
+      bit_depth, 0/*x*/, 0/*unused: palette*/, NULL/*format*/);
 
    /* Extract the background colour from this image_pixel, but make sure the
     * unused fields of 'back' are garbage.
@@ -7397,6 +7525,598 @@
 #define PT ITSTRUCT(background)
 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
 
+/* png_set_quantize(png_structp, png_colorp palette, int num_palette,
+ *    int maximum_colors, png_const_uint_16p histogram, int full_quantize)
+ *
+ * Very difficult to validate this!
+ */
+/*NOTE: TBD NYI */
+
+/* The data layout transforms are handled by swapping our own channel data,
+ * necessarily these need to happen at the end of the transform list because the
+ * semantic of the channels changes after these are executed.  Some of these,
+ * like set_shift and set_packing, can't be done at present because they change
+ * the layout of the data at the sub-sample level so sample() won't get the
+ * right answer.
+ */
+/* png_set_invert_alpha */
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+/* Invert the alpha channel
+ *
+ *  png_set_invert_alpha(png_structrp png_ptr)
+ */
+static void
+image_transform_png_set_invert_alpha_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_invert_alpha(pp);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_invert_alpha_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->colour_type & 4)
+      that->alpha_inverted = 1;
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_invert_alpha_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(bit_depth)
+
+   this->next = *that;
+   *that = this;
+
+   /* Only has an effect on pixels with alpha: */
+   return (colour_type & 4) != 0;
+}
+
+IT(invert_alpha);
+#undef PT
+#define PT ITSTRUCT(invert_alpha)
+
+#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
+
+/* png_set_bgr */
+#ifdef PNG_READ_BGR_SUPPORTED
+/* Swap R,G,B channels to order B,G,R.
+ *
+ *  png_set_bgr(png_structrp png_ptr)
+ *
+ * This only has an effect on RGB and RGBA pixels.
+ */
+static void
+image_transform_png_set_bgr_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_bgr(pp);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_bgr_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->colour_type == PNG_COLOR_TYPE_RGB ||
+       that->colour_type == PNG_COLOR_TYPE_RGBA)
+       that->swap_rgb = 1;
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_bgr_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(bit_depth)
+
+   this->next = *that;
+   *that = this;
+
+   return colour_type == PNG_COLOR_TYPE_RGB ||
+       colour_type == PNG_COLOR_TYPE_RGBA;
+}
+
+IT(bgr);
+#undef PT
+#define PT ITSTRUCT(bgr)
+
+#endif /* PNG_READ_BGR_SUPPORTED */
+
+/* png_set_swap_alpha */
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+/* Put the alpha channel first.
+ *
+ *  png_set_swap_alpha(png_structrp png_ptr)
+ *
+ * This only has an effect on GA and RGBA pixels.
+ */
+static void
+image_transform_png_set_swap_alpha_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_swap_alpha(pp);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_swap_alpha_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->colour_type == PNG_COLOR_TYPE_GA ||
+       that->colour_type == PNG_COLOR_TYPE_RGBA)
+      that->alpha_first = 1;
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_swap_alpha_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(bit_depth)
+
+   this->next = *that;
+   *that = this;
+
+   return colour_type == PNG_COLOR_TYPE_GA ||
+       colour_type == PNG_COLOR_TYPE_RGBA;
+}
+
+IT(swap_alpha);
+#undef PT
+#define PT ITSTRUCT(swap_alpha)
+
+#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED */
+
+/* png_set_swap */
+#ifdef PNG_READ_SWAP_SUPPORTED
+/* Byte swap 16-bit components.
+ *
+ *  png_set_swap(png_structrp png_ptr)
+ */
+static void
+image_transform_png_set_swap_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_swap(pp);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_swap_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->bit_depth == 16)
+      that->swap16 = 1;
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_swap_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(colour_type)
+
+   this->next = *that;
+   *that = this;
+
+   return bit_depth == 16;
+}
+
+IT(swap);
+#undef PT
+#define PT ITSTRUCT(swap)
+
+#endif /* PNG_READ_SWAP_SUPPORTED */
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images.
+ *
+ *  png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags));
+ *
+ * Flags:
+ *
+ *  PNG_FILLER_BEFORE
+ *  PNG_FILLER_AFTER
+ */
+#define data ITDATA(filler)
+static struct
+{
+   png_uint_32 filler;
+   int         flags;
+} data;
+
+static void
+image_transform_png_set_filler_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   /* Need a random choice for 'before' and 'after' as well as for the
+    * filler.  The 'filler' value has all 32 bits set, but only bit_depth
+    * will be used.  At this point we don't know bit_depth.
+    */
+   RANDOMIZE(data.filler);
+   data.flags = random_choice();
+
+   png_set_filler(pp, data.filler, data.flags);
+
+   /* The standard display handling stuff also needs to know that
+    * there is a filler, so set that here.
+    */
+   that->this.filler = 1;
+
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_filler_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->bit_depth >= 8 &&
+       (that->colour_type == PNG_COLOR_TYPE_RGB ||
+        that->colour_type == PNG_COLOR_TYPE_GRAY))
+   {
+      PNG_CONST unsigned int max = (1U << that->bit_depth)-1;
+      that->alpha = data.filler & max;
+      that->alphaf = ((double)that->alpha) / max;
+      that->alphae = 0;
+
+      /* The filler has been stored in the alpha channel, we must record
+       * that this has been done for the checking later on, the color
+       * type is faked to have an alpha channel, but libpng won't report
+       * this; the app has to know the extra channel is there and this
+       * was recording in standard_display::filler above.
+       */
+      that->colour_type |= 4; /* alpha added */
+      that->alpha_first = data.flags == PNG_FILLER_BEFORE;
+   }
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_filler_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   this->next = *that;
+   *that = this;
+
+   return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||
+           colour_type == PNG_COLOR_TYPE_GRAY);
+}
+
+#undef data
+IT(filler);
+#undef PT
+#define PT ITSTRUCT(filler)
+
+/* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+#define data ITDATA(add_alpha)
+static struct
+{
+   png_uint_32 filler;
+   int         flags;
+} data;
+
+static void
+image_transform_png_set_add_alpha_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   /* Need a random choice for 'before' and 'after' as well as for the
+    * filler.  The 'filler' value has all 32 bits set, but only bit_depth
+    * will be used.  At this point we don't know bit_depth.
+    */
+   RANDOMIZE(data.filler);
+   data.flags = random_choice();
+
+   png_set_add_alpha(pp, data.filler, data.flags);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_add_alpha_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->bit_depth >= 8 &&
+       (that->colour_type == PNG_COLOR_TYPE_RGB ||
+        that->colour_type == PNG_COLOR_TYPE_GRAY))
+   {
+      PNG_CONST unsigned int max = (1U << that->bit_depth)-1;
+      that->alpha = data.filler & max;
+      that->alphaf = ((double)that->alpha) / max;
+      that->alphae = 0;
+
+      that->colour_type |= 4; /* alpha added */
+      that->alpha_first = data.flags == PNG_FILLER_BEFORE;
+   }
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_add_alpha_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   this->next = *that;
+   *that = this;
+
+   return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||
+           colour_type == PNG_COLOR_TYPE_GRAY);
+}
+
+#undef data
+IT(add_alpha);
+#undef PT
+#define PT ITSTRUCT(add_alpha)
+
+#endif /* PNG_READ_FILLER_SUPPORTED */
+
+/* png_set_packing */
+#ifdef PNG_READ_PACK_SUPPORTED
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files.
+ *
+ *  png_set_packing(png_structrp png_ptr)
+ *
+ * This should only affect grayscale and palette images with less than 8 bits
+ * per pixel.
+ */
+static void
+image_transform_png_set_packing_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_packing(pp);
+   that->unpacked = 1;
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_packing_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   /* The general expand case depends on what the colour type is,
+    * low bit-depth pixel values are unpacked into bytes without
+    * scaling, so sample_depth is not changed.
+    */
+   if (that->bit_depth < 8) /* grayscale or palette */
+      that->bit_depth = 8;
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_packing_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(colour_type)
+
+   this->next = *that;
+   *that = this;
+
+   /* Nothing should happen unless the bit depth is less than 8: */
+   return bit_depth < 8;
+}
+
+IT(packing);
+#undef PT
+#define PT ITSTRUCT(packing)
+
+#endif /* PNG_READ_PACK_SUPPORTED */
+
+/* png_set_packswap */
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+/* Swap pixels packed into bytes; reverses the order on screen so that
+ * the high order bits correspond to the rightmost pixels.
+ *
+ *  png_set_packswap(png_structrp png_ptr)
+ */
+static void
+image_transform_png_set_packswap_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_packswap(pp);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_packswap_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->bit_depth < 8)
+      that->littleendian = 1;
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_packswap_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(colour_type)
+
+   this->next = *that;
+   *that = this;
+
+   return bit_depth < 8;
+}
+
+IT(packswap);
+#undef PT
+#define PT ITSTRUCT(packswap)
+
+#endif /* PNG_READ_PACKSWAP_SUPPORTED */
+
+
+/* png_set_invert_mono */
+#ifdef PNG_READ_INVERT_MONO_SUPPORTED
+/* Invert the gray channel
+ *
+ *  png_set_invert_mono(png_structrp png_ptr)
+ */
+static void
+image_transform_png_set_invert_mono_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_invert_mono(pp);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_invert_mono_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   if (that->colour_type & 4)
+      that->mono_inverted = 1;
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_invert_mono_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(bit_depth)
+
+   this->next = *that;
+   *that = this;
+
+   /* Only has an effect on pixels with no colour: */
+   return (colour_type & 2) == 0;
+}
+
+IT(invert_mono);
+#undef PT
+#define PT ITSTRUCT(invert_mono)
+
+#endif /* PNG_READ_INVERT_MONO_SUPPORTED */
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+/* png_set_shift(png_structp, png_const_color_8p true_bits)
+ *
+ * The output pixels will be shifted by the given true_bits
+ * values.
+ */
+#define data ITDATA(shift)
+static png_color_8 data;
+
+static void
+image_transform_png_set_shift_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   /* Get a random set of shifts.  The shifts need to do something
+    * to test the transform, so they are limited to the bit depth
+    * of the input image.  Notice that in the following the 'gray'
+    * field is randomized independently.  This acts as a check that
+    * libpng does use the correct field.
+    */
+   PNG_CONST unsigned int depth = that->this.bit_depth;
+
+   data.red = (png_byte)/*SAFE*/(random_mod(depth)+1);
+   data.green = (png_byte)/*SAFE*/(random_mod(depth)+1);
+   data.blue = (png_byte)/*SAFE*/(random_mod(depth)+1);
+   data.gray = (png_byte)/*SAFE*/(random_mod(depth)+1);
+   data.alpha = (png_byte)/*SAFE*/(random_mod(depth)+1);
+
+   png_set_shift(pp, &data);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_shift_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   /* Copy the correct values into the sBIT fields, libpng does not do
+    * anything to palette data:
+    */
+   if (that->colour_type != PNG_COLOR_TYPE_PALETTE)
+   {
+       that->sig_bits = 1;
+
+       /* The sBIT fields are reset to the values previously sent to
+        * png_set_shift according to the colour type.
+        * does.
+        */
+       if (that->colour_type & 2) /* RGB channels */
+       {
+          that->red_sBIT = data.red;
+          that->green_sBIT = data.green;
+          that->blue_sBIT = data.blue;
+       }
+
+       else /* One grey channel */
+          that->red_sBIT = that->green_sBIT = that->blue_sBIT = data.gray;
+
+       that->alpha_sBIT = data.alpha;
+   }
+
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_shift_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   UNUSED(bit_depth)
+
+   this->next = *that;
+   *that = this;
+
+   return colour_type != PNG_COLOR_TYPE_PALETTE;
+}
+
+IT(shift);
+#undef PT
+#define PT ITSTRUCT(shift)
+
+#endif /* PNG_READ_SHIFT_SUPPORTED */
+
+#ifdef THIS_IS_THE_PROFORMA
+static void
+image_transform_png_set_@_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+{
+   png_set_@(pp);
+   this->next->set(this->next, that, pp, pi);
+}
+
+static void
+image_transform_png_set_@_mod(PNG_CONST image_transform *this,
+    image_pixel *that, png_const_structp pp,
+    PNG_CONST transform_display *display)
+{
+   this->next->mod(this->next, that, pp, display);
+}
+
+static int
+image_transform_png_set_@_add(image_transform *this,
+    PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
+{
+   this->next = *that;
+   *that = this;
+
+   return 1;
+}
+
+IT(@);
+#endif
+
+
 /* This may just be 'end' if all the transforms are disabled! */
 static image_transform *PNG_CONST image_transform_first = &PT;
 
@@ -7574,83 +8294,6 @@
    }
 }
 
-#ifdef THIS_IS_THE_PROFORMA
-static void
-image_transform_png_set_@_set(PNG_CONST image_transform *this,
-    transform_display *that, png_structp pp, png_infop pi)
-{
-   png_set_@(pp);
-   this->next->set(this->next, that, pp, pi);
-}
-
-static void
-image_transform_png_set_@_mod(PNG_CONST image_transform *this,
-    image_pixel *that, png_const_structp pp,
-    PNG_CONST transform_display *display)
-{
-   this->next->mod(this->next, that, pp, display);
-}
-
-static int
-image_transform_png_set_@_add(image_transform *this,
-    PNG_CONST image_transform **that, char *name, size_t sizeof_name,
-    size_t *pos, png_byte colour_type, png_byte bit_depth)
-{
-   this->next = *that;
-   *that = this;
-
-   *pos = safecat(name, sizeof_name, *pos, " +@");
-
-   return 1;
-}
-
-IT(@);
-#endif
-
-/* png_set_quantize(png_structp, png_colorp palette, int num_palette,
- *    int maximum_colors, png_const_uint_16p histogram, int full_quantize)
- *
- * Very difficult to validate this!
- */
-/*NOTE: TBD NYI */
-
-/* The data layout transforms are handled by swapping our own channel data,
- * necessarily these need to happen at the end of the transform list because the
- * semantic of the channels changes after these are executed.  Some of these,
- * like set_shift and set_packing, can't be done at present because they change
- * the layout of the data at the sub-sample level so sample() won't get the
- * right answer.
- */
-/* png_set_invert_alpha */
-/*NOTE: TBD NYI */
-
-/* png_set_bgr */
-/*NOTE: TBD NYI */
-
-/* png_set_swap_alpha */
-/*NOTE: TBD NYI */
-
-/* png_set_swap */
-/*NOTE: TBD NYI */
-
-/* png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags)); */
-/*NOTE: TBD NYI */
-
-/* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */
-/*NOTE: TBD NYI */
-
-/* png_set_packing */
-/*NOTE: TBD NYI */
-
-/* png_set_packswap */
-/*NOTE: TBD NYI */
-
-/* png_set_invert_mono */
-/*NOTE: TBD NYI */
-
-/* png_set_shift(png_structp, png_const_color_8p true_bits) */
-/*NOTE: TBD NYI */
-
 static void
 perform_transform_test(png_modifier *pm)
 {
@@ -8753,9 +9396,9 @@
 
             /* Record the palette index for index images. */
             PNG_CONST unsigned int in_index =
-               in_ct == 3 ? sample(std, 3, in_bd, x, 0) : 256;
+               in_ct == 3 ? sample(std, 3, in_bd, x, 0, 0, 0) : 256;
             PNG_CONST unsigned int out_index =
-               out_ct == 3 ? sample(std, 3, out_bd, x, 0) : 256;
+               out_ct == 3 ? sample(std, 3, out_bd, x, 0, 0, 0) : 256;
 
             /* Handle input alpha - png_set_background will cause the output
              * alpha to disappear so there is nothing to check.
@@ -8765,7 +9408,7 @@
             {
                PNG_CONST unsigned int input_alpha = in_ct == 3 ?
                   dp->this.palette[in_index].alpha :
-                  sample(std, in_ct, in_bd, x, samples_per_pixel);
+                  sample(std, in_ct, in_bd, x, samples_per_pixel, 0, 0);
 
                unsigned int output_alpha = 65536 /* as a flag value */;
 
@@ -8777,7 +9420,7 @@
 
                else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0)
                   output_alpha = sample(pRow, out_ct, out_bd, x,
-                     samples_per_pixel);
+                     samples_per_pixel, 0, 0);
 
                if (output_alpha != 65536)
                   alpha = gamma_component_validate("alpha", &vi, input_alpha,
@@ -8796,30 +9439,30 @@
             /* Handle grayscale or RGB components. */
             if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */
                (void)gamma_component_validate("gray", &vi,
-                  sample(std, in_ct, in_bd, x, 0),
-                  sample(pRow, out_ct, out_bd, x, 0), alpha/*component*/,
-                  vi.background_red);
+                  sample(std, in_ct, in_bd, x, 0, 0, 0),
+                  sample(pRow, out_ct, out_bd, x, 0, 0, 0),
+                  alpha/*component*/, vi.background_red);
             else /* RGB or palette */
             {
                (void)gamma_component_validate("red", &vi,
                   in_ct == 3 ? in_palette[in_index].red :
-                     sample(std, in_ct, in_bd, x, 0),
+                     sample(std, in_ct, in_bd, x, 0, 0, 0),
                   out_ct == 3 ? out_palette[out_index].red :
-                     sample(pRow, out_ct, out_bd, x, 0),
+                     sample(pRow, out_ct, out_bd, x, 0, 0, 0),
                   alpha/*component*/, vi.background_red);
 
                (void)gamma_component_validate("green", &vi,
                   in_ct == 3 ? in_palette[in_index].green :
-                     sample(std, in_ct, in_bd, x, 1),
+                     sample(std, in_ct, in_bd, x, 1, 0, 0),
                   out_ct == 3 ? out_palette[out_index].green :
-                     sample(pRow, out_ct, out_bd, x, 1),
+                     sample(pRow, out_ct, out_bd, x, 1, 0, 0),
                   alpha/*component*/, vi.background_green);
 
                (void)gamma_component_validate("blue", &vi,
                   in_ct == 3 ? in_palette[in_index].blue :
-                     sample(std, in_ct, in_bd, x, 2),
+                     sample(std, in_ct, in_bd, x, 2, 0, 0),
                   out_ct == 3 ? out_palette[out_index].blue :
-                     sample(pRow, out_ct, out_bd, x, 2),
+                     sample(pRow, out_ct, out_bd, x, 2, 0, 0),
                   alpha/*component*/, vi.background_blue);
             }
          }
diff --git a/contrib/tools/pngfix.c b/contrib/tools/pngfix.c
index 65422f6..67bab6a 100644
--- a/contrib/tools/pngfix.c
+++ b/contrib/tools/pngfix.c
@@ -1,8 +1,8 @@
 /* pngfix.c
  *
- * Copyright (c) 2014 John Cunningham Bowler
+ * Copyright (c) 2014-2015 John Cunningham Bowler
  *
- * Last changed in libpng 1.6.14 [October 23, 2014]
+ * Last changed in libpng 1.6.17 [March 26, 2015]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -2138,7 +2138,7 @@
           *
           * z-rc is the zlib failure code; message is the error message with
           * spaces replaced by '-'.  The compressed byte count indicates where
-          * in the zlib stream the error occured.
+          * in the zlib stream the error occurred.
           */
          type_name(zlib->chunk->chunk_type, stdout);
          printf(" SKP %s %d %s ", zlib_flevel(zlib), zlib->file_bits,
@@ -3577,10 +3577,9 @@
 {
    png_structp png_ptr;
    png_infop info_ptr = NULL;
-   volatile png_bytep row = NULL, display = NULL;
    volatile int rc;
 
-   png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), control,
+   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, control,
       error_handler, warning_handler);
 
    if (png_ptr == NULL)
@@ -3594,6 +3593,16 @@
    rc = setjmp(control->file.jmpbuf);
    if (rc == 0)
    {
+#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
+         /* Remove any limits on the size of PNG files that can be read,
+          * without this we may reject files based on built-in safety
+          * limits.
+          */
+         png_set_user_limits(png_ptr, 0x7fffffff, 0x7fffffff);
+         png_set_chunk_cache_max(png_ptr, 0);
+         png_set_chunk_malloc_max(png_ptr, 0);
+#     endif
+
       png_set_read_fn(png_ptr, control, read_callback);
 
       info_ptr = png_create_info_struct(png_ptr);
@@ -3606,32 +3615,22 @@
       png_read_info(png_ptr, info_ptr);
 
       {
-         png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+        png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
+        int passes = png_set_interlace_handling(png_ptr);
+        int pass;
 
-         row = png_voidcast(png_byte*, malloc(rowbytes));
-         display = png_voidcast(png_byte*, malloc(rowbytes));
+        png_start_read_image(png_ptr);
 
-         if (row == NULL || display == NULL)
-            png_error(png_ptr, "OOM allocating row buffers");
+        for (pass = 0; pass < passes; ++pass)
+        {
+           png_uint_32 y = height;
 
-         {
-            png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
-            int passes = png_set_interlace_handling(png_ptr);
-            int pass;
-
-            png_start_read_image(png_ptr);
-
-            for (pass = 0; pass < passes; ++pass)
-            {
-               png_uint_32 y = height;
-
-               /* NOTE: this trashes the row each time; interlace handling won't
-                * work, but this avoids memory thrashing for speed testing.
-                */
-               while (y-- > 0)
-                  png_read_row(png_ptr, row, display);
-            }
-         }
+           /* NOTE: this skips asking libpng to return either version of
+            * the image row, but libpng still reads the rows.
+            */
+           while (y-- > 0)
+              png_read_row(png_ptr, NULL, NULL);
+        }
       }
 
       if (control->file.global->verbose)
@@ -3642,8 +3641,6 @@
    }
 
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-   if (row != NULL) free(row);
-   if (display != NULL) free(display);
    return rc;
 }
 
@@ -3705,21 +3702,21 @@
 "        gAMA, sRGB [all]: These specify the gamma encoding used for the pixel",
 "            values.",
 "        cHRM, iCCP [color]: These specify how colors are encoded.  iCCP also",
-"            specifies the exact encoding of a pixel value however in practice",
-"            most programs will ignore it.",
+"            specifies the exact encoding of a pixel value; however, in",
+"            practice most programs will ignore it.",
 "        bKGD [transform]: This is used by libpng transforms."
 "    --max=<number>:",
 "      Use IDAT chunks sized <number>.  If no number is given the the IDAT",
 "      chunks will be the maximum size permitted; 2^31-1 bytes.  If the option",
 "      is omitted the original chunk sizes will not be changed.  When the",
-"      option is given --strip=unsafe is set automatically, this may be",
+"      option is given --strip=unsafe is set automatically. This may be",
 "      cancelled if you know that all unknown unsafe-to-copy chunks really are",
 "      safe to copy across an IDAT size change.  This is true of all chunks",
 "      that have ever been formally proposed as PNG extensions.",
 "  MESSAGES",
 "      By default the program only outputs summaries for each file.",
 "    --quiet (-q):",
-"      Do not output the summaries except for files which cannot be read. With",
+"      Do not output the summaries except for files that cannot be read. With",
 "      two --quiets these are not output either.",
 "    --errors (-e):",
 "      Output errors from libpng and the program (except too-far-back).",
@@ -3752,7 +3749,7 @@
 "  the following codes.  Notice that the results for each file are combined",
 "  together - check one file at a time to get a meaningful error code!",
 "    0x01: The zlib too-far-back error existed in at least one chunk.",
-"    0x02: At least once chunk had a CRC error.",
+"    0x02: At least one chunk had a CRC error.",
 "    0x04: A chunk length was incorrect.",
 "    0x08: The file was truncated.",
 "  Errors less than 16 are potentially recoverable, for a single file if the",
@@ -3760,7 +3757,7 @@
 "  non-zero code is returned).",
 "    0x10: The file could not be read, even with corrections.",
 "    0x20: The output file could not be written.",
-"    0x40: An unexpected, potentially internal, error occured.",
+"    0x40: An unexpected, potentially internal, error occurred.",
 "  If the command line arguments are incorrect the program exits with exit",
 "  255.  Some older operating systems only support 7-bit exit codes, on those",
 "  systems it is suggested that this program is first tested by supplying",
@@ -3820,7 +3817,7 @@
 "          SKP: The chunk was skipped because of a zlib issue (zlib-rc) with",
 "               explanation 'message'",
 "          ERR: The read of the file was aborted.  The parameters explain why.",
-"$3 status:     For 'ERR' the accumulate status code from 'EXIT CODES' above.",
+"$3 status:     For 'ERR' the accumulated status code from 'EXIT CODES' above.",
 "               This is printed as a 2 digit hexadecimal value",
 "   comp-level: The recorded compression level (FLEVEL) of a zlib stream",
 "               expressed as a string {supfast,stdfast,default,maximum}",
diff --git a/libpng-manual.txt b/libpng-manual.txt
index 3aa1f57..f0dae98 100644
--- a/libpng-manual.txt
+++ b/libpng-manual.txt
@@ -1,9 +1,9 @@
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.16 - December 22, 2014
+ libpng version 1.6.17 - March 26, 2015
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ Copyright (c) 1998-2015 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
@@ -11,9 +11,9 @@
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.16 - December 22, 2014
+ libpng versions 0.97, January 1998, through 1.6.17 - March 26, 2015
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ Copyright (c) 1998-2015 Glenn Randers-Pehrson
 
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
@@ -336,7 +336,7 @@
 
 If you are intending to keep the file pointer open for use in libpng,
 you must ensure you don't read more than 8 bytes from the beginning
-of the file, and you also have to make a call to png_set_sig_bytes_read()
+of the file, and you also have to make a call to png_set_sig_bytes()
 with the number of bytes you read from the beginning.  Libpng will
 then only check the bytes (if any) that your program didn't read.
 
@@ -344,22 +344,23 @@
 to replace them with custom functions.  See the discussion under
 Customizing libpng.
 
-
     FILE *fp = fopen(file_name, "rb");
     if (!fp)
     {
        return (ERROR);
     }
 
-    fread(header, 1, number, fp);
-    is_png = !png_sig_cmp(header, 0, number);
+    if (fread(header, 1, number, fp) != number)
+    {
+       return (ERROR);
+    }
 
+    is_png = !png_sig_cmp(header, 0, number);
     if (!is_png)
     {
        return (NOT_PNG);
     }
 
-
 Next, png_struct and png_info need to be allocated and initialized.  In
 order to ensure that the size of these structures is correct even with a
 dynamically linked libpng, there are functions to initialize and
@@ -649,7 +650,7 @@
 The PNG specification allows the width and height of an image to be as
 large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
 Larger images will be rejected immediately with a png_error() call. If
-you wish to reduce these limits, you can use
+you wish to change these limits, you can use
 
    png_set_user_limits(png_ptr, width_max, height_max);
 
@@ -1264,13 +1265,13 @@
                      the PNG datastream is embedded in
                      a MNG-1.0 datastream)
 
-    Any or all of interlace_type, compression_type, or
-    filter_method can be NULL if you are
-    not interested in their values.
+    Any of width, height, color_type, bit_depth,
+    interlace_type, compression_type, or filter_method can
+    be NULL if you are not interested in their values.
 
     Note that png_get_IHDR() returns 32-bit data into
     the application's width and height variables.
-    This is an unsafe situation if these are 16-bit
+    This is an unsafe situation if these are not png_uint_32
     variables.  In such situations, the
     png_get_image_width() and png_get_image_height()
     functions described below are safer.
@@ -1993,7 +1994,7 @@
       png_set_gamma(png_ptr, screen_gamma, 0.45455);
 
 If you need to reduce an RGB file to a paletted file, or if a paletted
-file has more entries then will fit on your screen, png_set_quantize()
+file has more entries than will fit on your screen, png_set_quantize()
 will do that.  Note that this is a simple match quantization that merely
 finds the closest color available.  This should work fairly well with
 optimized palettes, but fairly badly with linear color cubes.  If you
@@ -2546,7 +2547,7 @@
        64K.  The library seems to run fine with sizes
        of 4K. Although you can give it much less if
        necessary (I assume you can give it chunks of
-       1 byte, I haven't tried less then 256 bytes
+       1 byte, I haven't tried less than 256 bytes
        yet).  When this function returns, you may
        want to display any rows that were generated
        in the row callback if you don't already do
@@ -5031,6 +5032,10 @@
    png_infop became png_inforp or png_const_inforp
 where "rp" indicates a "restricted pointer".
 
+The support for FAR/far types has been eliminated and the definition of
+png_alloc_size_t is now controlled by a flag so that 'small size_t' systems
+can select it if necessary.
+
 Error detection in some chunks has improved; in particular the iCCP chunk
 reader now does pretty complete validation of the basic format.  Some bad
 profiles that were previously accepted are now accepted with a warning or
@@ -5045,7 +5050,7 @@
            PNG_OPTION_ON);
     #endif
 
-It's not a good idea to do this if you are using the new "simplified API",
+It's not a good idea to do this if you are using the "simplified API",
 which needs to be able to recognize sRGB profiles conveyed via the iCCP
 chunk.
 
@@ -5274,13 +5279,13 @@
 
 XVI. Y2K Compliance in libpng
 
-December 22, 2014
+March 26, 2015
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.16 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.17 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 
 Libpng only has two year fields.  One is a 2-byte unsigned integer
diff --git a/libpng.3 b/libpng.3
index bb3c3ca..dfc4484 100644
--- a/libpng.3
+++ b/libpng.3
@@ -1,6 +1,6 @@
-.TH LIBPNG 3 "December 22, 2014"
+.TH LIBPNG 3 "March 26, 2015"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.16
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17
 .SH SYNOPSIS
 \fB
 #include <png.h>\fP
@@ -504,10 +504,10 @@
 .SH LIBPNG.TXT
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.16 - December 22, 2014
+ libpng version 1.6.17 - March 26, 2015
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ Copyright (c) 1998-2015 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
@@ -515,9 +515,9 @@
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.16 - December 22, 2014
+ libpng versions 0.97, January 1998, through 1.6.17 - March 26, 2015
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ Copyright (c) 1998-2015 Glenn Randers-Pehrson
 
  libpng 1.0 beta 6 - version 0.96 - May 28, 1997
  Updated and distributed by Andreas Dilger
@@ -840,7 +840,7 @@
 
 If you are intending to keep the file pointer open for use in libpng,
 you must ensure you don't read more than 8 bytes from the beginning
-of the file, and you also have to make a call to png_set_sig_bytes_read()
+of the file, and you also have to make a call to png_set_sig_bytes()
 with the number of bytes you read from the beginning.  Libpng will
 then only check the bytes (if any) that your program didn't read.
 
@@ -848,22 +848,23 @@
 to replace them with custom functions.  See the discussion under
 Customizing libpng.
 
-
     FILE *fp = fopen(file_name, "rb");
     if (!fp)
     {
        return (ERROR);
     }
 
-    fread(header, 1, number, fp);
-    is_png = !png_sig_cmp(header, 0, number);
+    if (fread(header, 1, number, fp) != number)
+    {
+       return (ERROR);
+    }
 
+    is_png = !png_sig_cmp(header, 0, number);
     if (!is_png)
     {
        return (NOT_PNG);
     }
 
-
 Next, png_struct and png_info need to be allocated and initialized.  In
 order to ensure that the size of these structures is correct even with a
 dynamically linked libpng, there are functions to initialize and
@@ -1153,7 +1154,7 @@
 The PNG specification allows the width and height of an image to be as
 large as 2^(31\-1 (0x7fffffff), or about 2.147 billion rows and columns.
 Larger images will be rejected immediately with a png_error() call. If
-you wish to reduce these limits, you can use
+you wish to change these limits, you can use
 
    png_set_user_limits(png_ptr, width_max, height_max);
 
@@ -1768,13 +1769,13 @@
                      the PNG datastream is embedded in
                      a MNG-1.0 datastream)
 
-    Any or all of interlace_type, compression_type, or
-    filter_method can be NULL if you are
-    not interested in their values.
+    Any of width, height, color_type, bit_depth,
+    interlace_type, compression_type, or filter_method can
+    be NULL if you are not interested in their values.
 
     Note that png_get_IHDR() returns 32-bit data into
     the application's width and height variables.
-    This is an unsafe situation if these are 16-bit
+    This is an unsafe situation if these are not png_uint_32
     variables.  In such situations, the
     png_get_image_width() and png_get_image_height()
     functions described below are safer.
@@ -2497,7 +2498,7 @@
       png_set_gamma(png_ptr, screen_gamma, 0.45455);
 
 If you need to reduce an RGB file to a paletted file, or if a paletted
-file has more entries then will fit on your screen, png_set_quantize()
+file has more entries than will fit on your screen, png_set_quantize()
 will do that.  Note that this is a simple match quantization that merely
 finds the closest color available.  This should work fairly well with
 optimized palettes, but fairly badly with linear color cubes.  If you
@@ -3050,7 +3051,7 @@
        64K.  The library seems to run fine with sizes
        of 4K. Although you can give it much less if
        necessary (I assume you can give it chunks of
-       1 byte, I haven't tried less then 256 bytes
+       1 byte, I haven't tried less than 256 bytes
        yet).  When this function returns, you may
        want to display any rows that were generated
        in the row callback if you don't already do
@@ -5535,6 +5536,10 @@
    png_infop became png_inforp or png_const_inforp
 where "rp" indicates a "restricted pointer".
 
+The support for FAR/far types has been eliminated and the definition of
+png_alloc_size_t is now controlled by a flag so that 'small size_t' systems
+can select it if necessary.
+
 Error detection in some chunks has improved; in particular the iCCP chunk
 reader now does pretty complete validation of the basic format.  Some bad
 profiles that were previously accepted are now accepted with a warning or
@@ -5549,7 +5554,7 @@
            PNG_OPTION_ON);
     #endif
 
-It's not a good idea to do this if you are using the new "simplified API",
+It's not a good idea to do this if you are using the "simplified API",
 which needs to be able to recognize sRGB profiles conveyed via the iCCP
 chunk.
 
@@ -5778,13 +5783,13 @@
 
 .SH XVI. Y2K Compliance in libpng
 
-December 22, 2014
+March 26, 2015
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.16 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.17 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 
 Libpng only has two year fields.  One is a 2-byte unsigned integer
@@ -6036,6 +6041,9 @@
  1.6.16beta01-03     16    10616  16.so.16.16[.0]
  1.6.16rc01-02       16    10616  16.so.16.16[.0]
  1.6.16              16    10616  16.so.16.16[.0]
+ 1.6.17beta01-06     16    10617  16.so.16.17[.0]
+ 1.6.17rc01-06       16    10617  16.so.16.17[.0]
+ 1.6.17              16    10617  16.so.16.17[.0]
 
 Henceforth the source version will match the shared-library minor
 and patch numbers; the shared-library major version number will be
@@ -6092,7 +6100,7 @@
 
 Thanks to Frank J. T. Wojcik for helping with the documentation.
 
-Libpng version 1.6.16 - December 22, 2014:
+Libpng version 1.6.17 - March 26, 2015:
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
 Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
 
@@ -6115,8 +6123,8 @@
 
 This code is released under the libpng license.
 
-libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are
-Copyright (c) 2004,2006-2014 Glenn Randers-Pehrson, and are
+libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are
+Copyright (c) 2004,2006-2015 Glenn Randers-Pehrson, and are
 distributed according to the same disclaimer and license as libpng-1.2.5
 with the following individual added to the list of Contributing Authors
 
@@ -6214,7 +6222,7 @@
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-December 22, 2014
+March 26, 2015
 
 .\" end of man page
 
diff --git a/libpngpf.3 b/libpngpf.3
index 7d48913..d0dd5be 100644
--- a/libpngpf.3
+++ b/libpngpf.3
@@ -1,6 +1,6 @@
-.TH LIBPNGPF 3 "December 22, 2014"
+.TH LIBPNGPF 3 "March 26, 2015"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.6.16
+libpng \- Portable Network Graphics (PNG) Reference Library 1.6.17
 (private functions)
 .SH SYNOPSIS
 \fB#include \fI"pngpriv.h"
diff --git a/png.5 b/png.5
index ff6083c..10c4c3c 100644
--- a/png.5
+++ b/png.5
@@ -1,4 +1,4 @@
-.TH PNG 5 "December 22, 2014"
+.TH PNG 5 "March 26, 2015"
 .SH NAME
 png \- Portable Network Graphics (PNG) format
 .SH DESCRIPTION
diff --git a/png.c b/png.c
index 4d93dfa..7575ede 100644
--- a/png.c
+++ b/png.c
@@ -1,8 +1,8 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * Last changed in libpng 1.6.16 [December 22, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -14,7 +14,7 @@
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16;
+typedef png_libpng_version_1_6_17 Your_png_h_is_not_version_1_6_17;
 
 /* 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
@@ -34,7 +34,7 @@
    if (num_bytes > 8)
       png_error(png_ptr, "Too many bytes for PNG signature");
 
-   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+   png_ptr->sig_bytes = (png_byte)((num_bytes < 0 ? 0 : num_bytes) & 0xff);
 }
 
 /* Checks whether the supplied bytes match the PNG signature.  We allow
@@ -140,8 +140,10 @@
       do
       {
          uInt safe_length = (uInt)length;
+#ifndef __COVERITY__
          if (safe_length == 0)
             safe_length = (uInt)-1; /* evil, but safe */
+#endif
 
          crc = crc32(crc, ptr, safe_length);
 
@@ -476,9 +478,10 @@
    /* Free any tRNS entry */
    if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
    {
+      info_ptr->valid &= ~PNG_INFO_tRNS;
       png_free(png_ptr, info_ptr->trans_alpha);
       info_ptr->trans_alpha = NULL;
-      info_ptr->valid &= ~PNG_INFO_tRNS;
+      info_ptr->num_trans = 0;
    }
 #endif
 
@@ -544,20 +547,17 @@
 
       else
       {
-         if (info_ptr->splt_palettes_num != 0)
+         int i;
+
+         for (i = 0; i < info_ptr->splt_palettes_num; i++)
          {
-            int i;
-
-            for (i = 0; i < info_ptr->splt_palettes_num; i++)
-            {
-               png_free(png_ptr, info_ptr->splt_palettes[i].name);
-               png_free(png_ptr, info_ptr->splt_palettes[i].entries);
-            }
-
-            png_free(png_ptr, info_ptr->splt_palettes);
-            info_ptr->splt_palettes = NULL;
-            info_ptr->splt_palettes_num = 0;
+            png_free(png_ptr, info_ptr->splt_palettes[i].name);
+            png_free(png_ptr, info_ptr->splt_palettes[i].entries);
          }
+
+         png_free(png_ptr, info_ptr->splt_palettes);
+         info_ptr->splt_palettes = NULL;
+         info_ptr->splt_palettes_num = 0;
          info_ptr->valid &= ~PNG_INFO_sPLT;
       }
    }
@@ -577,15 +577,12 @@
       {
          int i;
 
-         if (info_ptr->unknown_chunks_num != 0)
-         {
-            for (i = 0; i < info_ptr->unknown_chunks_num; i++)
-               png_free(png_ptr, info_ptr->unknown_chunks[i].data);
+         for (i = 0; i < info_ptr->unknown_chunks_num; i++)
+            png_free(png_ptr, info_ptr->unknown_chunks[i].data);
 
-            png_free(png_ptr, info_ptr->unknown_chunks);
-            info_ptr->unknown_chunks = NULL;
-            info_ptr->unknown_chunks_num = 0;
-         }
+         png_free(png_ptr, info_ptr->unknown_chunks);
+         info_ptr->unknown_chunks = NULL;
+         info_ptr->unknown_chunks_num = 0;
       }
    }
 #endif
@@ -666,7 +663,7 @@
 }
 #  endif
 
-#ifdef PNG_SAVE_INT_32_SUPPORTED
+#  ifdef PNG_SAVE_INT_32_SUPPORTED
 /* The png_save_int_32 function assumes integers are stored in two's
  * complement format.  If this isn't the case, then this routine needs to
  * be modified to write data in two's complement format.  Note that,
@@ -681,7 +678,7 @@
    buf[2] = (png_byte)((i >> 8) & 0xff);
    buf[3] = (png_byte)(i & 0xff);
 }
-#endif
+#  endif
 
 #  ifdef PNG_TIME_RFC1123_SUPPORTED
 /* Convert the supplied time into an RFC 1123 string suitable for use in
@@ -734,7 +731,7 @@
    return 1;
 }
 
-#     if PNG_LIBPNG_VER < 10700
+#    if PNG_LIBPNG_VER < 10700
 /* To do: remove the following from libpng-1.7 */
 /* Original API that uses a private buffer in png_struct.
  * Deprecated because it causes png_struct to carry a spurious temporary
@@ -755,7 +752,7 @@
 
    return NULL;
 }
-#     endif
+#    endif /* LIBPNG_VER < 10700 */
 #  endif /* TIME_RFC1123 */
 
 #endif /* READ || WRITE */
@@ -769,14 +766,14 @@
 #else
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-     "libpng version 1.6.16 - December 22, 2014" PNG_STRING_NEWLINE \
-     "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+     "libpng version 1.6.17 - March 26, 2015" PNG_STRING_NEWLINE \
+     "Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
      PNG_STRING_NEWLINE;
 #  else
-      return "libpng version 1.6.16 - December 22, 2014\
-      Copyright (c) 1998-2014 Glenn Randers-Pehrson\
+      return "libpng version 1.6.17 - March 26, 2015\
+      Copyright (c) 1998-2015 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
 #  endif
@@ -872,9 +869,9 @@
 
    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
    {
-      palette[i].red = (png_byte)v;
-      palette[i].green = (png_byte)v;
-      palette[i].blue = (png_byte)v;
+      palette[i].red = (png_byte)(v & 0xff);
+      palette[i].green = (png_byte)(v & 0xff);
+      palette[i].blue = (png_byte)(v & 0xff);
    }
 }
 #endif
@@ -947,8 +944,6 @@
    return((png_uint_32)PNG_LIBPNG_VER);
 }
 
-
-
 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
 /* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
  * If it doesn't 'ret' is used to set it to something appropriate, even in cases
@@ -1181,7 +1176,7 @@
    png_colorspace_sync_info(png_ptr, info_ptr);
 }
 #endif
-#endif
+#endif /* GAMMA */
 
 #ifdef PNG_COLORSPACE_SUPPORTED
 /* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
@@ -2166,7 +2161,8 @@
    return 1; /* success, maybe with warnings */
 }
 
-#if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
+#ifdef PNG_sRGB_SUPPORTED
+#if PNG_sRGB_PROFILE_CHECKS >= 0
 /* Information about the known ICC sRGB profiles */
 static const struct
 {
@@ -2324,8 +2320,8 @@
                    */
                   else if (png_sRGB_checks[i].have_md5 == 0)
                   {
-                     png_chunk_report(png_ptr, "out-of-date sRGB profile with"
-                        " no signature",
+                     png_chunk_report(png_ptr,
+                        "out-of-date sRGB profile with no signature",
                         PNG_CHUNK_WARNING);
                   }
 
@@ -2338,8 +2334,8 @@
           * way.  This probably indicates a data error or uninformed hacking.
           * Fall through to "no match".
           */
-         png_chunk_report(png_ptr, "Not recognizing known sRGB profile that"
-             " has been edited", 
+         png_chunk_report(png_ptr,
+             "Not recognizing known sRGB profile that has been edited", 
              PNG_CHUNK_WARNING);
          break;
 # endif
@@ -2349,9 +2345,8 @@
 
    return 0; /* no match */
 }
-#endif
+#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
 
-#ifdef PNG_sRGB_SUPPORTED
 void /* PRIVATE */
 png_icc_set_sRGB(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
@@ -2365,7 +2360,7 @@
       (void)png_colorspace_set_sRGB(png_ptr, colorspace,
          (int)/*already checked*/png_get_uint_32(profile+64));
 }
-#endif /* READ_sRGB */
+#endif /* sRGB */
 
 int /* PRIVATE */
 png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
@@ -2457,7 +2452,7 @@
          png_error(png_ptr, "internal error handling cHRM->XYZ");
    }
 }
-#endif
+#endif /* READ_RGB_TO_GRAY */
 
 #endif /* COLORSPACE */
 
@@ -2486,18 +2481,19 @@
       png_warning(png_ptr, "Image width is zero in IHDR");
       error = 1;
    }
-   else if (width > PNG_UINT_31_MAX)
+
+   if (width > PNG_UINT_31_MAX)
    {
       png_warning(png_ptr, "Invalid image width in IHDR");
       error = 1;
    }
 
-   else if (png_gt(width,
-                   (PNG_SIZE_MAX >> 3) /* 8-byte RGBA pixels */
-                   - 48                /* big_row_buf hack */
-                   - 1                 /* filter byte */
-                   - 7*8               /* rounding width to multiple of 8 pix */
-                   - 8))               /* extra max_pixel_depth pad */
+   if (png_gt(((width + 7) & (~7)),
+       ((PNG_SIZE_MAX
+           - 48        /* big_row_buf hack */
+           - 1)        /* filter byte */
+           / 8)        /* 8-byte RGBA pixels */
+           - 1))       /* extra max_pixel_depth pad */
    {
       /* The size of the row must be within the limits of this architecture.
        * Because the read code can perform arbitrary transformations the
@@ -2513,17 +2509,15 @@
       png_warning(png_ptr, "Image width is too large for this architecture");
       error = 1;
    }
-   else
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (width > png_ptr->user_width_max)
+#else
+   if (width > PNG_USER_WIDTH_MAX)
+#endif
    {
-#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
-      if (width > png_ptr->user_width_max)
-#     else
-      if (width > PNG_USER_WIDTH_MAX)
-#     endif
-      {
-         png_warning(png_ptr, "Image width exceeds user limit in IHDR");
-         error = 1;
-      }
+      png_warning(png_ptr, "Image width exceeds user limit in IHDR");
+      error = 1;
    }
 
    if (height == 0)
@@ -2531,22 +2525,21 @@
       png_warning(png_ptr, "Image height is zero in IHDR");
       error = 1;
    }
-   else if (height > PNG_UINT_31_MAX)
+
+   if (height > PNG_UINT_31_MAX)
    {
       png_warning(png_ptr, "Invalid image height in IHDR");
       error = 1;
    }
-   else
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (height > png_ptr->user_height_max)
+#else
+   if (height > PNG_USER_HEIGHT_MAX)
+#endif
    {
-#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
-      if (height > png_ptr->user_height_max)
-#     else
-      if (height > PNG_USER_HEIGHT_MAX)
-#     endif
-      {
-         png_warning(png_ptr, "Image height exceeds user limit in IHDR");
-         error = 1;
-      }
+      png_warning(png_ptr, "Image height exceeds user limit in IHDR");
+      error = 1;
    }
 
    /* Check other values */
@@ -2585,7 +2578,7 @@
       error = 1;
    }
 
-#  ifdef PNG_MNG_FEATURES_SUPPORTED
+#ifdef PNG_MNG_FEATURES_SUPPORTED
    /* Accept filter_method 64 (intrapixel differencing) only if
     * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
     * 2. Libpng did not read a PNG signature (this filter_method is only
@@ -2618,13 +2611,13 @@
       }
    }
 
-#  else
+#else
    if (filter_type != PNG_FILTER_TYPE_BASE)
    {
       png_warning(png_ptr, "Unknown filter method in IHDR");
       error = 1;
    }
-#  endif
+#endif
 
    if (error == 1)
       png_error(png_ptr, "Invalid IHDR data");
@@ -3041,7 +3034,7 @@
             /* Check for an exponent, if we don't need one we are
              * done and just need to terminate the string.  At
              * this point exp_b10==(-1) is effectively if flag - it got
-             * to '-1' because of the decrement after outputing
+             * to '-1' because of the decrement after outputting
              * the decimal point above (the exponent required is
              * *not* -1!)
              */
@@ -3049,7 +3042,7 @@
             {
                /* The following only happens if we didn't output the
                 * leading zeros above for negative exponent, so this
-                * doest add to the digit requirement.  Note that the
+                * doesn't add to the digit requirement.  Note that the
                 * two zeros here can only be output if the two leading
                 * zeros were *not* output, so this doesn't increase
                 * the output count.
@@ -3206,7 +3199,7 @@
    png_error(png_ptr, "ASCII conversion buffer too small");
 }
 #   endif /* FIXED_POINT */
-#endif /* READ_SCAL */
+#endif /* SCAL */
 
 #if defined(PNG_FLOATING_POINT_SUPPORTED) && \
    !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
@@ -3224,7 +3217,7 @@
       png_fixed_error(png_ptr, text);
 
 #  ifndef PNG_ERROR_TEXT_SUPPORTED
-      PNG_UNUSED(text)
+   PNG_UNUSED(text)
 #  endif
 
    return (png_fixed_point)r;
@@ -3405,29 +3398,29 @@
 #endif
 
 #ifdef PNG_READ_GAMMA_SUPPORTED
-#if defined(PNG_16BIT_SUPPORTED) || !defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
+#ifdef PNG_16BIT_SUPPORTED
 /* A local convenience routine. */
 static png_fixed_point
 png_product2(png_fixed_point a, png_fixed_point b)
 {
    /* The required result is 1/a * 1/b; the following preserves accuracy. */
-#    ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    double r = a * 1E-5;
    r *= b;
    r = floor(r+.5);
 
    if (r <= 2147483647. && r >= -2147483648.)
       return (png_fixed_point)r;
-#    else
+#else
    png_fixed_point res;
 
    if (png_muldiv(&res, a, b, 100000) != 0)
       return res;
-#    endif
+#endif
 
    return 0; /* overflow */
 }
-#endif /* 16BIT || !FLOATING_ARITHMETIC */
+#endif /* 16BIT */
 
 /* The inverse of the above. */
 png_fixed_point
@@ -3435,12 +3428,15 @@
 {
    /* The required result is 1/a * 1/b; the following preserves accuracy. */
 #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
-   double r = 1E15/a;
-   r /= b;
-   r = floor(r+.5);
+   if (a != 0 && b != 0)
+   {
+      double r = 1E15/a;
+      r /= b;
+      r = floor(r+.5);
 
-   if (r <= 2147483647. && r >= -2147483648.)
-      return (png_fixed_point)r;
+      if (r <= 2147483647. && r >= -2147483648.)
+         return (png_fixed_point)r;
+   }
 #else
    /* This may overflow because the range of png_fixed_point isn't symmetric,
     * but this API is only used for the product of file and screen gamma so it
@@ -3731,7 +3727,7 @@
     * step.
     */
    x -= x >> 8;
-   return (png_byte)((x + 0x7fffffU) >> 24);
+   return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
 }
 
 #ifdef PNG_16BIT_SUPPORTED
@@ -3792,7 +3788,7 @@
 #     endif
    }
 
-   return (png_byte)value;
+   return (png_byte)(value & 0xff);
 }
 
 #ifdef PNG_16BIT_SUPPORTED
@@ -4014,7 +4010,7 @@
 
    else
       for (i=0; i<256; ++i)
-         table[i] = (png_byte)i;
+         table[i] = (png_byte)(i & 0xff);
 }
 
 /* Used from png_read_destroy and below to release the memory used by the gamma
@@ -4154,7 +4150,8 @@
       *
       */
      if (sig_bit > 0 && sig_bit < 16U)
-        shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
+        /* shift == insignificant bits */
+        shift = (png_byte)((16U - sig_bit) & 0xff);
 
      else
         shift = 0; /* keep all 16 bits */
@@ -4223,7 +4220,7 @@
       int setting = (2 + (onoff != 0)) << option;
       int current = png_ptr->options;
 
-      png_ptr->options = (png_byte)((current & ~mask) | setting);
+      png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff);
 
       return (current & mask) >> option;
    }
diff --git a/png.h b/png.h
index 997130d..372599b 100644
--- a/png.h
+++ b/png.h
@@ -1,8 +1,9 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.6.16, December 22, 2014
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * libpng version 1.6.17, March 26, 2015
+ *
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -11,7 +12,7 @@
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.6.16, December 22, 2014: Glenn
+ *   libpng versions 0.97, January 1998, through 1.6.17, March 26, 2015: Glenn
  *   See also "Contributing Authors", below.
  *
  * Note about libpng version numbers:
@@ -212,6 +213,9 @@
  *    1.6.16beta01-03         16    10616  16.so.16.16[.0]
  *    1.6.16rc01-02           16    10616  16.so.16.16[.0]
  *    1.6.16                  16    10616  16.so.16.16[.0]
+ *    1.6.17beta01-06         16    10617  16.so.16.17[.0]
+ *    1.6.17rc01-06           16    10617  16.so.16.17[.0]
+ *    1.6.17                  16    10617  16.so.16.17[.0]
  *
  *   Henceforth the source version will match the shared-library major
  *   and minor numbers; the shared-library major version number will be
@@ -243,8 +247,8 @@
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.2.6, August 15, 2004, through 1.6.16, December 22, 2014, are
- * Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.17, March 26, 2015, are
+ * Copyright (c) 2004, 2006-2015 Glenn Randers-Pehrson, and are
  * distributed according to the same disclaimer and license as libpng-1.2.5
  * with the following individual added to the list of Contributing Authors:
  *
@@ -355,13 +359,13 @@
  * Y2K compliance in libpng:
  * =========================
  *
- *    December 22, 2014
+ *    March 26, 2015
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
  *
  *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.6.16 are Y2K compliant.  It is my belief that
+ *    upward through 1.6.17 are Y2K compliant.  It is my belief that
  *    earlier versions were also Y2K compliant.
  *
  *    Libpng only has two year fields.  One is a 2-byte unsigned integer
@@ -423,9 +427,9 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.16"
+#define PNG_LIBPNG_VER_STRING "1.6.17"
 #define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.6.16 - December 22, 2014\n"
+     " libpng version 1.6.17 - March 26, 2015\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
@@ -433,7 +437,7 @@
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 16
+#define PNG_LIBPNG_VER_RELEASE 17
 
 /* This should match the numeric part of the final component of
  * PNG_LIBPNG_VER_STRING, omitting any leading zero:
@@ -464,7 +468,7 @@
  * 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
  */
-#define PNG_LIBPNG_VER 10616 /* 1.6.16 */
+#define PNG_LIBPNG_VER 10617 /* 1.6.17 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
@@ -569,7 +573,7 @@
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  */
-typedef char* png_libpng_version_1_6_16;
+typedef char* png_libpng_version_1_6_17;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
@@ -1578,6 +1582,7 @@
 #define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
 #define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
 
+#ifdef PNG_WRITE_SUPPORTED
 /* These functions give the user control over the scan-line filtering in
  * libpng and the compression methods used by zlib.  These functions are
  * mainly useful for testing, as the defaults should work with most users.
@@ -1591,6 +1596,7 @@
  */
 PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
     int filters));
+#endif /* WRITE */
 
 /* Flags for png_set_filter() to say which filters to use.  The flags
  * are chosen so that they don't conflict with real filter types
@@ -1616,6 +1622,7 @@
 #define PNG_FILTER_VALUE_PAETH 4
 #define PNG_FILTER_VALUE_LAST  5
 
+#ifdef PNG_WRITE_SUPPORTED
 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */
 /* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
  * defines, either the default (minimum-sum-of-absolute-differences), or
@@ -1662,7 +1669,6 @@
 #define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
 #define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
 
-#ifdef PNG_WRITE_SUPPORTED
 /* Set the library compression level.  Currently, valid values range from
  * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
  * (0 - no compression, 9 - "maximal" compression).  Note that tests have
@@ -1670,6 +1676,7 @@
  * for PNG images, and do considerably fewer caclulations.  In the future,
  * these values may not correspond directly to the zlib compression levels.
  */
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
 PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,
     int level));
 
@@ -1687,7 +1694,7 @@
 
 PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
     int method));
-#endif
+#endif /* WRITE_CUSTOMIZE_COMPRESSION */
 
 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
 /* Also set zlib parameters for compressing non-IDAT chunks */
@@ -1709,6 +1716,7 @@
 PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
     int method));
 #endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+#endif /* WRITE */
 
 /* These next functions are called for input/output, memory, and error
  * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
@@ -1819,7 +1827,7 @@
  *
  * The integer return from the callback function is interpreted thus:
  *
- * negative: An error occured, png_chunk_error will be called.
+ * negative: An error occurred; png_chunk_error will be called.
  *     zero: The chunk was not handled, the chunk will be saved. A critical
  *           chunk will cause an error at this point unless it is to be saved.
  * positive: The chunk was handled, libpng will ignore/discard it.
@@ -2664,26 +2672,28 @@
            * (png_uint_16)(alpha)                         \
            + (png_uint_16)(bg)*(png_uint_16)(255          \
            - (png_uint_16)(alpha)) + 128);                \
-       (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+       (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); }
 
 #  define png_composite_16(composite, fg, alpha, bg)       \
      { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg)  \
            * (png_uint_32)(alpha)                          \
            + (png_uint_32)(bg)*(65535                      \
            - (png_uint_32)(alpha)) + 32768);               \
-       (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+       (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); }
 
 #else  /* Standard method using integer division */
 
-#  define png_composite(composite, fg, alpha, bg)                          \
-     (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
-     (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) +       \
-     127) / 255)
+#  define png_composite(composite, fg, alpha, bg)                        \
+     (composite) =                                                       \
+         (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
+         (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+         127) / 255))
 
 #  define png_composite_16(composite, fg, alpha, bg)                         \
-     (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
-     (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +         \
-     32767) / 65535)
+     (composite) =                                                           \
+         (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+         (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
+         32767) / 65535))
 #endif /* READ_COMPOSITE_NODIV */
 
 #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
diff --git a/pngconf.h b/pngconf.h
index 03615f0..3f9493e 100644
--- a/pngconf.h
+++ b/pngconf.h
@@ -1,9 +1,9 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.6.16,December 22, 2014
+ * libpng version 1.6.17, March 26, 2015
  *
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -11,9 +11,7 @@
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
- */
-
-/* Any machine specific code is near the front of this file, so if you
+ * Any machine specific code is near the front of this file, so if you
  * are configuring libpng for a machine, you may want to read the section
  * starting here down to where it starts to typedef png_color, png_text,
  * and png_info.
@@ -22,26 +20,6 @@
 #ifndef PNGCONF_H
 #define PNGCONF_H
 
-/* To do: Do all of this in scripts/pnglibconf.dfa */
-#ifdef PNG_SAFE_LIMITS_SUPPORTED
-#  ifdef PNG_USER_WIDTH_MAX
-#    undef PNG_USER_WIDTH_MAX
-#    define PNG_USER_WIDTH_MAX 1000000L
-#  endif
-#  ifdef PNG_USER_HEIGHT_MAX
-#    undef PNG_USER_HEIGHT_MAX
-#    define PNG_USER_HEIGHT_MAX 1000000L
-#  endif
-#  ifdef PNG_USER_CHUNK_MALLOC_MAX
-#    undef PNG_USER_CHUNK_MALLOC_MAX
-#    define PNG_USER_CHUNK_MALLOC_MAX 4000000L
-#  endif
-#  ifdef PNG_USER_CHUNK_CACHE_MAX
-#    undef PNG_USER_CHUNK_CACHE_MAX
-#    define PNG_USER_CHUNK_CACHE_MAX 128
-#  endif
-#endif
-
 #ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
 
 /* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
diff --git a/pngdebug.h b/pngdebug.h
index b43c59c..6a01b10 100644
--- a/pngdebug.h
+++ b/pngdebug.h
@@ -1,12 +1,11 @@
 
 /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
  *
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng 1.6.8 [December 19, 2013]
- *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
diff --git a/pngget.c b/pngget.c
index fce126c..743a6a9 100644
--- a/pngget.c
+++ b/pngget.c
@@ -1,8 +1,8 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -799,14 +799,20 @@
 {
    png_debug1(1, "in %s retrieval function", "IHDR");
 
-   if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
-       height == NULL || bit_depth == NULL || color_type == NULL)
+   if (png_ptr == NULL || info_ptr == NULL)
       return (0);
 
-   *width = info_ptr->width;
-   *height = info_ptr->height;
-   *bit_depth = info_ptr->bit_depth;
-   *color_type = info_ptr->color_type;
+   if (width != NULL)
+       *width = info_ptr->width;
+
+   if (height != NULL)
+       *height = info_ptr->height;
+
+   if (bit_depth != NULL)
+       *bit_depth = info_ptr->bit_depth;
+
+   if (color_type != NULL)
+       *color_type = info_ptr->color_type;
 
    if (compression_type != NULL)
       *compression_type = info_ptr->compression_type;
@@ -1135,21 +1141,21 @@
    if (png_ptr == NULL)
       return 0;
 
-#  ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_SUPPORTED
       if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
-#  endif
+#endif
    {
-#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
          return png_ptr->IDAT_read_size;
-#     else
+#else
          return PNG_IDAT_READ_SIZE;
-#     endif
+#endif
    }
 
-#  ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_SUPPORTED
       else
          return png_ptr->zbuffer_size;
-#  endif
+#endif
 }
 
 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
diff --git a/pnginfo.h b/pnginfo.h
index 122a90a..c8c874d 100644
--- a/pnginfo.h
+++ b/pnginfo.h
@@ -1,12 +1,11 @@
 
 /* pnginfo.h - header file for PNG reference library
  *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng 1.6.1 [March 28, 2013]
- *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
diff --git a/pngmem.c b/pngmem.c
index d6caf27..8b157e5 100644
--- a/pngmem.c
+++ b/pngmem.c
@@ -41,7 +41,7 @@
 }
 
 /* Allocate memory.  For reasonable files, size should never exceed
- * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * 64K.  However, zlib may allocate more than 64K if you don't tell
  * it not to.  See zconf.h and png.h for more information.  zlib does
  * need to allocate exactly 64K, so whatever you call here must
  * have the ability to do that.
diff --git a/pngpread.c b/pngpread.c
index fb40e7d..823dcad 100644
--- a/pngpread.c
+++ b/pngpread.c
@@ -1,8 +1,8 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -726,7 +726,7 @@
     * or the stream marked as finished.
     */
    while (png_ptr->zstream.avail_in > 0 &&
-      !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+      (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
    {
       int ret;
 
@@ -1036,6 +1036,7 @@
       }
    }
    else
+#endif
    {
       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       png_read_push_finish_row(png_ptr);
@@ -1045,6 +1046,7 @@
 void /* PRIVATE */
 png_read_push_finish_row(png_structrp png_ptr)
 {
+#ifdef PNG_READ_INTERLACING_SUPPORTED
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
    /* Start of interlace block */
@@ -1069,6 +1071,7 @@
    if (png_ptr->row_number < png_ptr->num_rows)
       return;
 
+#ifdef PNG_READ_INTERLACING_SUPPORTED
    if (png_ptr->interlaced != 0)
    {
       png_ptr->row_number = 0;
@@ -1103,6 +1106,7 @@
 
       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
    }
+#endif /* READ_INTERLACING */
 }
 
 void /* PRIVATE */
@@ -1127,6 +1131,7 @@
          (int)png_ptr->pass);
 }
 
+#ifdef PNG_READ_INTERLACING_SUPPORTED
 void PNGAPI
 png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
     png_const_bytep new_row)
@@ -1141,6 +1146,7 @@
    if (new_row != NULL)
       png_combine_row(png_ptr, old_row, 1/*blocky display*/);
 }
+#endif /* READ_INTERLACING */
 
 void PNGAPI
 png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
diff --git a/pngpriv.h b/pngpriv.h
index cbd66de..5980a3f 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -1,13 +1,11 @@
 
 /* pngpriv.h - private declarations for use inside libpng
  *
- * For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng 1.6.10 [March 6, 1014]]
- *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
@@ -300,46 +298,9 @@
 
 /* SECURITY and SAFETY:
  *
- * By default libpng is built without any internal limits on image size,
- * individual heap (png_malloc) allocations or the total amount of memory used.
- * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used
- * (unless individually overridden).  These limits are believed to be fairly
- * safe, but builders of secure systems should verify the values against the
- * real system capabilities.
- */
-#ifdef PNG_SAFE_LIMITS_SUPPORTED
-   /* 'safe' limits */
-#  ifndef PNG_USER_WIDTH_MAX
-#     define PNG_USER_WIDTH_MAX 1000000
-#  endif
-#  ifndef PNG_USER_HEIGHT_MAX
-#     define PNG_USER_HEIGHT_MAX 1000000
-#  endif
-#  ifndef PNG_USER_CHUNK_CACHE_MAX
-#     define PNG_USER_CHUNK_CACHE_MAX 128
-#  endif
-#  ifndef PNG_USER_CHUNK_MALLOC_MAX
-#     define PNG_USER_CHUNK_MALLOC_MAX 8000000
-#  endif
-#else
-   /* values for no limits */
-#  ifndef PNG_USER_WIDTH_MAX
-#     define PNG_USER_WIDTH_MAX 0x7fffffff
-#  endif
-#  ifndef PNG_USER_HEIGHT_MAX
-#     define PNG_USER_HEIGHT_MAX 0x7fffffff
-#  endif
-#  ifndef PNG_USER_CHUNK_CACHE_MAX
-#     define PNG_USER_CHUNK_CACHE_MAX 0
-#  endif
-#  ifndef PNG_USER_CHUNK_MALLOC_MAX
-#     define PNG_USER_CHUNK_MALLOC_MAX 0
-#  endif
-#endif
-
-/* Moved to pngpriv.h at libpng-1.5.0 */
-/* NOTE: some of these may have been used in external applications as
- * these definitions were exposed in pngconf.h prior to 1.5.
+ * libpng is built with support for internal limits on image dimensions and
+ * memory usage.  These are documented in scripts/pnglibconf.dfa of the
+ * source and recorded in the machine generated header file pnglibconf.h.
  */
 
 /* If you are running on a machine where you cannot allocate more
@@ -582,13 +543,13 @@
 #define PNG_RGB_TO_GRAY_WARN  0x400000
 #define PNG_RGB_TO_GRAY       0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
 #define PNG_ENCODE_ALPHA      0x800000 /* Added to libpng-1.5.4 */
-#define PNG_ADD_ALPHA         0x1000000 /* Added to libpng-1.2.7 */
-#define PNG_EXPAND_tRNS       0x2000000 /* Added to libpng-1.2.9 */
-#define PNG_SCALE_16_TO_8     0x4000000 /* Added to libpng-1.5.4 */
-                       /*   0x8000000 unused */
-                       /*  0x10000000 unused */
-                       /*  0x20000000 unused */
-                       /*  0x40000000 unused */
+#define PNG_ADD_ALPHA        0x1000000 /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS      0x2000000 /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8    0x4000000 /* Added to libpng-1.5.4 */
+                       /*    0x8000000 unused */
+                       /*   0x10000000 unused */
+                       /*   0x20000000 unused */
+                       /*   0x40000000 unused */
 /* Flags for png_create_struct */
 #define PNG_STRUCT_PNG   0x0001
 #define PNG_STRUCT_INFO  0x0002
@@ -780,15 +741,17 @@
  * macro will fail on top-bit-set values because of the sign extension.
  */
 #define PNG_CHUNK_FROM_STRING(s)\
-   PNG_U32(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
+   PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3])
 
 /* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
  * signed and the argument is a (char[])  This macro will fail miserably on
  * systems where (char) is more than 8 bits.
  */
 #define PNG_STRING_FROM_CHUNK(s,c)\
-   (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\
-   ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c)))
+   (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \
+   ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\
+   ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \
+   ((char*)(s))[3]=(char)((c & 0xff)))
 
 /* Do the same but terminate with a null character. */
 #define PNG_CSTRING_FROM_CHUNK(s,c)\
@@ -850,8 +813,9 @@
 PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]);
 PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]);
 
-#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\
-   ((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))
+#define PNG_sRGB_FROM_LINEAR(linear) \
+  ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \
+   + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)))
    /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
     * encoded value with maximum error 0.646365.  Note that the input is not a
     * 16-bit value; it has been multiplied by 255! */
@@ -910,7 +874,7 @@
 #if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
    defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
 /* Internal array allocator, outputs no error or warning messages on failure,
- * just returns NULL.  
+ * just returns NULL.
  */
 PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,
    int nelements, size_t element_size),PNG_ALLOCATED);
diff --git a/pngread.c b/pngread.c
index 87a7891..6764dbe 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1,8 +1,8 @@
 
 /* pngread.c - read a PNG file
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -814,8 +814,7 @@
          /* Zero length IDATs are legal after the last IDAT has been
           * read, but not after other chunks have been read.
           */
-         if ((length > 0) ||
-             (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
             png_benign_error(png_ptr, "Too many IDATs found");
 
          png_crc_finish(png_ptr, length);
@@ -1824,6 +1823,7 @@
             y = (y + 128) >> 8;
             y *= 255;
             y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
+            alpha = PNG_DIV257(alpha);
             encoding = P_sRGB;
          }
 
@@ -2286,8 +2286,14 @@
                      output_processing = PNG_CMAP_NONE;
                      break;
                   }
-
+#ifdef __COVERITY__
+                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
+                  * here.
+                  */
+                  back_alpha = 255;
+#else
                   back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
+#endif
                }
 
                /* output_processing means that the libpng-processed row will be
@@ -2412,7 +2418,14 @@
                 */
                background_index = i;
                png_create_colormap_entry(display, i++, back_r, back_g, back_b,
-                  output_encoding == P_LINEAR ? 65535U : 255U, output_encoding);
+#ifdef __COVERITY__
+                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
+                  * here.
+                  */ 255U,
+#else
+                  output_encoding == P_LINEAR ? 65535U : 255U,
+#endif
+                  output_encoding);
 
                /* For non-opaque input composite on the sRGB background - this
                 * requires inverting the encoding for each component.  The input
@@ -3246,7 +3259,7 @@
       png_uint_32  width = image->width;
       ptrdiff_t    step_row = display->row_bytes;
       unsigned int channels =
-         (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+          (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
       int pass;
 
       for (pass = 0; pass < passes; ++pass)
diff --git a/pngrio.c b/pngrio.c
index 1e98395..bb5c825 100644
--- a/pngrio.c
+++ b/pngrio.c
@@ -1,8 +1,8 @@
 
 /* pngrio.c - functions for data input
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -26,7 +26,7 @@
  * reads from a file pointer.  Note that this routine sometimes gets called
  * with very small lengths, so you should implement some kind of simple
  * buffering if you are using unbuffered reads.  This should never be asked
- * to read more then 64K on a 16 bit machine.
+ * to read more than 64K on a 16 bit machine.
  */
 void /* PRIVATE */
 png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
diff --git a/pngrtran.c b/pngrtran.c
index e6fe9fd..cad7a8d 100644
--- a/pngrtran.c
+++ b/pngrtran.c
@@ -1,8 +1,8 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -394,7 +394,7 @@
 /* Dither file to 8-bit.  Supply a palette, the current number
  * of elements in the palette, the maximum number of elements
  * allowed, and a histogram if possible.  If the current number
- * of colors is greater then the maximum number, the palette will be
+ * of colors is greater than the maximum number, the palette will be
  * modified to fit in the maximum number.  "full_quantize" indicates
  * whether we need a quantizing cube set up for RGB images, or if we
  * simply are reducing the number of colors in a paletted image.
@@ -2357,7 +2357,7 @@
                if (++channel >= channels)
                   channel = 0;
                *bp++ = (png_byte)(value >> 8);
-               *bp++ = (png_byte)(value & 0xff);
+               *bp++ = (png_byte)value;
             }
             break;
          }
@@ -2662,9 +2662,9 @@
    png_uint_32 row_width = row_info->width;
 
 #ifdef PNG_READ_16BIT_SUPPORTED
-   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+   png_byte hi_filler = (png_byte)(filler>>8);
 #endif
-   png_byte lo_filler = (png_byte)(filler & 0xff);
+   png_byte lo_filler = (png_byte)filler;
 
    png_debug(1, "in png_do_read_filler");
 
@@ -2715,13 +2715,13 @@
             png_bytep dp = sp  + (png_size_t)row_width * 2;
             for (i = 1; i < row_width; i++)
             {
-               *(--dp) = hi_filler;
                *(--dp) = lo_filler;
+               *(--dp) = hi_filler;
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
             }
-            *(--dp) = hi_filler;
             *(--dp) = lo_filler;
+            *(--dp) = hi_filler;
             row_info->channels = 2;
             row_info->pixel_depth = 32;
             row_info->rowbytes = row_width * 4;
@@ -2736,8 +2736,8 @@
             {
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
-               *(--dp) = hi_filler;
                *(--dp) = lo_filler;
+               *(--dp) = hi_filler;
             }
             row_info->channels = 2;
             row_info->pixel_depth = 32;
@@ -2796,8 +2796,8 @@
             png_bytep dp = sp  + (png_size_t)row_width * 2;
             for (i = 1; i < row_width; i++)
             {
-               *(--dp) = hi_filler;
                *(--dp) = lo_filler;
+               *(--dp) = hi_filler;
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
@@ -2805,8 +2805,8 @@
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
             }
-            *(--dp) = hi_filler;
             *(--dp) = lo_filler;
+            *(--dp) = hi_filler;
             row_info->channels = 4;
             row_info->pixel_depth = 64;
             row_info->rowbytes = row_width * 8;
@@ -2825,8 +2825,8 @@
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
                *(--dp) = *(--sp);
-               *(--dp) = hi_filler;
                *(--dp) = lo_filler;
+               *(--dp) = hi_filler;
             }
 
             row_info->channels = 4;
@@ -3087,10 +3087,11 @@
             for (i = 0; i < row_width; i++)
             {
                png_uint_16 red, green, blue, w;
+               png_byte hi,lo;
 
-               red   = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
-               green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
-               blue  = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
+               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
+               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
 
                if (red == green && red == blue)
                {
@@ -3104,16 +3105,16 @@
 
                else
                {
-                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff)
+                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red & 0xff)
                       >> png_ptr->gamma_shift][red>>8];
                   png_uint_16 green_1 =
-                      png_ptr->gamma_16_to_1[(green&0xff) >>
+                      png_ptr->gamma_16_to_1[(green & 0xff) >>
                       png_ptr->gamma_shift][green>>8];
-                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff)
+                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue & 0xff)
                       >> png_ptr->gamma_shift][blue>>8];
                   png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
                       + bc*blue_1 + 16384)>>15);
-                  w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+                  w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
                       png_ptr->gamma_shift][gray16 >> 8];
                   rgb_error |= 1;
                }
@@ -3138,10 +3139,11 @@
             for (i = 0; i < row_width; i++)
             {
                png_uint_16 red, green, blue, gray16;
+               png_byte hi,lo;
 
-               red   = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
-               green = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
-               blue  = (png_uint_16)(((*(sp)) << 8) | *(sp + 1)); sp += 2;
+               hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
+               hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
+               hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
 
                if (red != green || red != blue)
                   rgb_error |= 1;
@@ -3667,7 +3669,8 @@
                         if (optimize != 0)
                            w = v;
                         else
-                           w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+                           w = gamma_16_from_1[(v & 0xff) >>
+                               gamma_shift][v >> 8];
                         *sp = (png_byte)((w >> 8) & 0xff);
                         *(sp + 1) = (png_byte)(w & 0xff);
                      }
@@ -3831,7 +3834,7 @@
                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
                         png_composite_16(w, v, a, png_ptr->background_1.red);
                         if (optimize == 0)
-                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
                                 8];
                         *sp = (png_byte)((w >> 8) & 0xff);
                         *(sp + 1) = (png_byte)(w & 0xff);
@@ -3839,7 +3842,7 @@
                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
                         png_composite_16(w, v, a, png_ptr->background_1.green);
                         if (optimize == 0)
-                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
                                 8];
 
                         *(sp + 2) = (png_byte)((w >> 8) & 0xff);
@@ -3848,7 +3851,7 @@
                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
                         png_composite_16(w, v, a, png_ptr->background_1.blue);
                         if (optimize == 0)
-                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+                           w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
                                 8];
 
                         *(sp + 4) = (png_byte)((w >> 8) & 0xff);
@@ -4837,7 +4840,7 @@
       /* Because PNG_COMPOSE does the gamma transform if there is something to
        * do (if there is an alpha channel or transparency.)
        */
-       !((png_ptr->transformations & PNG_COMPOSE) &&
+       !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
        ((png_ptr->num_trans != 0) ||
        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
 #endif
diff --git a/pngrutil.c b/pngrutil.c
index 4c26be4..6c5c375 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -1,8 +1,8 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -1515,8 +1515,10 @@
                                  else if (size > 0)
                                     errmsg = "truncated";
 
+#ifndef __COVERITY__
                                  else
                                     errmsg = png_ptr->zstream.msg;
+#endif
                               }
 
                               /* else png_icc_check_tag_table output an error */
@@ -2804,7 +2806,7 @@
                &png_ptr->unknown_chunk);
 
             /* ret is:
-             * negative: An error occured, png_chunk_error will be called.
+             * negative: An error occurred; png_chunk_error will be called.
              *     zero: The chunk was not handled, the chunk will be discarded
              *           unless png_set_keep_unknown_chunks has been used to set
              *           a 'keep' behavior for this particular chunk, in which
diff --git a/pngset.c b/pngset.c
index 2f1f550..fce3039 100644
--- a/pngset.c
+++ b/pngset.c
@@ -1,8 +1,8 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -190,6 +190,7 @@
    if (info_ptr->hist == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for hIST chunk data");
+
       return;
    }
 
@@ -271,7 +272,7 @@
    png_debug1(1, "in %s storage function", "pCAL");
 
    if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
-      || (nparams > 0 && params == NULL))
+       || (nparams > 0 && params == NULL))
       return;
 
    length = strlen(purpose) + 1;
@@ -301,6 +302,7 @@
    if (info_ptr->pcal_purpose == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for pCAL purpose");
+
       return;
    }
 
@@ -322,6 +324,7 @@
    if (info_ptr->pcal_units == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for pCAL units");
+
       return;
    }
 
@@ -333,6 +336,7 @@
    if (info_ptr->pcal_params == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for pCAL params");
+
       return;
    }
 
@@ -349,6 +353,7 @@
       if (info_ptr->pcal_params[i] == NULL)
       {
          png_warning(png_ptr, "Insufficient memory for pCAL parameter");
+
          return;
       }
 
@@ -398,6 +403,7 @@
    if (info_ptr->scal_s_width == NULL)
    {
       png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+
       return;
    }
 
@@ -416,6 +422,7 @@
       info_ptr->scal_s_width = NULL;
 
       png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+
       return;
    }
 
@@ -519,6 +526,7 @@
       else
       {
          png_warning(png_ptr, "Invalid palette length");
+
          return;
       }
    }
@@ -531,7 +539,6 @@
       ))
    {
       png_error(png_ptr, "Invalid palette");
-      return;
    }
 
    /* It may not actually be necessary to set png_ptr->palette here;
@@ -655,6 +662,7 @@
    if (new_iccp_name == NULL)
    {
       png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
+
       return;
    }
 
@@ -668,6 +676,7 @@
       new_iccp_name = NULL;
       png_benign_error(png_ptr,
           "Insufficient memory to process iCCP profile");
+
       return;
    }
 
@@ -743,6 +752,7 @@
       {
          png_chunk_report(png_ptr, "too many text chunks",
             PNG_CHUNK_WRITE_ERROR);
+
          return 1;
       }
 
@@ -798,7 +808,7 @@
          else
             lang_key_len = 0;
       }
-#  else /* PNG_iTXt_SUPPORTED */
+#  else /* iTXt */
       {
          png_chunk_report(png_ptr, "iTXt chunk not supported",
             PNG_CHUNK_WRITE_ERROR);
@@ -831,6 +841,7 @@
       {
          png_chunk_report(png_ptr, "text chunk: out of memory",
                PNG_CHUNK_WRITE_ERROR);
+
          return 1;
       }
 
@@ -904,6 +915,7 @@
        mod_time->second > 60)
    {
       png_warning(png_ptr, "Ignoring invalid time value");
+
       return;
    }
 
@@ -920,6 +932,7 @@
    png_debug1(1, "in %s storage function", "tRNS");
 
    if (png_ptr == NULL || info_ptr == NULL)
+
       return;
 
    if (trans_alpha != NULL)
@@ -945,16 +958,21 @@
 
    if (trans_color != NULL)
    {
-      int sample_max = (1 << info_ptr->bit_depth);
+#ifdef PNG_WARNINGS_SUPPORTED
+      if (info_ptr->bit_depth < 16)
+      {
+         int sample_max = (1 << info_ptr->bit_depth) - 1;
 
-      if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
-          trans_color->gray > sample_max) ||
-          (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
-          (trans_color->red > sample_max ||
-          trans_color->green > sample_max ||
-          trans_color->blue > sample_max)))
-         png_warning(png_ptr,
-            "tRNS chunk has out-of-range samples for bit_depth");
+         if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
+             trans_color->gray > sample_max) ||
+             (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+             (trans_color->red > sample_max ||
+             trans_color->green > sample_max ||
+             trans_color->blue > sample_max)))
+            png_warning(png_ptr,
+               "tRNS chunk has out-of-range samples for bit_depth");
+      }
+#endif
 
       info_ptr->trans_color = *trans_color;
 
@@ -1001,6 +1019,7 @@
    {
       /* Out of memory or too many chunks */
       png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
+
       return;
    }
 
@@ -1116,7 +1135,7 @@
    png_unknown_chunkp np;
 
    if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
-      unknowns == NULL)
+       unknowns == NULL)
       return;
 
    /* Check for the failure cases where support has been disabled at compile
@@ -1130,6 +1149,7 @@
       if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
       {
          png_app_error(png_ptr, "no unknown chunk support on read");
+
          return;
       }
 #  endif
@@ -1138,6 +1158,7 @@
       if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
       {
          png_app_error(png_ptr, "no unknown chunk support on write");
+
          return;
       }
 #  endif
@@ -1155,6 +1176,7 @@
    {
       png_chunk_report(png_ptr, "too many unknown chunks",
          PNG_CHUNK_WRITE_ERROR);
+
       return;
    }
 
@@ -1232,8 +1254,7 @@
          check_location(png_ptr, location);
    }
 }
-#endif
-
+#endif /* STORE_UNKNOWN_CHUNKS */
 
 #ifdef PNG_MNG_FEATURES_SUPPORTED
 png_uint_32 PNGAPI
@@ -1264,6 +1285,7 @@
       if (memcmp(list, add, 4) == 0)
       {
          list[4] = (png_byte)keep;
+
          return count;
       }
    }
@@ -1291,6 +1313,7 @@
    if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
    {
       png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
+
       return;
    }
 
@@ -1340,6 +1363,7 @@
           * which can be switched off.
           */
          png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
+
          return;
       }
 
@@ -1355,6 +1379,7 @@
    if (num_chunks + old_num_chunks > UINT_MAX/5)
    {
       png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
+
       return;
    }
 
@@ -1492,23 +1517,27 @@
          {
             png_warning(png_ptr,
               "Compression buffer size cannot be changed because it is in use");
+
             return;
          }
 
+#ifndef __COVERITY__
          if (size > ZLIB_IO_MAX)
          {
             png_warning(png_ptr,
                "Compression buffer size limited to system maximum");
             size = ZLIB_IO_MAX; /* must fit */
          }
+#endif
 
-         else if (size < 6)
+         if (size < 6)
          {
             /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
              * if this is permitted.
              */
             png_warning(png_ptr,
                "Compression buffer size cannot be reduced below 6");
+
             return;
          }
 
@@ -1550,8 +1579,8 @@
 void PNGAPI
 png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
 {
-    if (png_ptr != NULL)
-       png_ptr->user_chunk_cache_max = user_chunk_cache_max;
+   if (png_ptr != NULL)
+      png_ptr->user_chunk_cache_max = user_chunk_cache_max;
 }
 
 /* This function was added to libpng 1.4.1 */
diff --git a/pngstruct.h b/pngstruct.h
index c1dd026..8420d09 100644
--- a/pngstruct.h
+++ b/pngstruct.h
@@ -1,12 +1,11 @@
 
 /* pngstruct.h - header file for PNG reference library
  *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng 1.6.1 [March 28, 2013]
- *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
@@ -101,7 +100,7 @@
 #endif /* COLORSPACE */
 
 #if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
-/* A colorspace is all the above plus, potentially, profile information,
+/* A colorspace is all the above plus, potentially, profile information;
  * however at present libpng does not use the profile internally so it is only
  * stored in the png_info struct (if iCCP is supported.)  The rendering intent
  * is retained here and is checked.
diff --git a/pngtest.c b/pngtest.c
index 2e8cb8a..2c3e04d 100644
--- a/pngtest.c
+++ b/pngtest.c
@@ -1,8 +1,8 @@
 
 /* pngtest.c - a simple test program to test libpng
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -469,7 +469,7 @@
 #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
 
 /* Allocate memory.  For reasonable files, size should never exceed
- * 64K.  However, zlib may allocate more then 64K if you don't tell
+ * 64K.  However, zlib may allocate more than 64K if you don't tell
  * it not to.  See zconf.h and png.h for more information.  zlib does
  * need to allocate exactly 64K, so whatever you call here must
  * have the ability to do that.
@@ -1701,6 +1701,8 @@
    int multiple = 0;
    int ierror = 0;
 
+   png_structp dummy_ptr;
+
    fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
    fprintf(STDERR, "   with zlib   version %s\n", ZLIB_VERSION);
    fprintf(STDERR, "%s", png_get_copyright(NULL));
@@ -1994,6 +1996,24 @@
    else
       fprintf(STDERR, " libpng FAILS test\n");
 
+   dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+   fprintf(STDERR, " Default limits:\n");
+   fprintf(STDERR, "  width_max  = %lu\n",
+      (unsigned long) png_get_user_width_max(dummy_ptr));
+   fprintf(STDERR, "  height_max = %lu\n",
+      (unsigned long) png_get_user_height_max(dummy_ptr));
+   if (png_get_chunk_cache_max(dummy_ptr) == 0)
+      fprintf(STDERR, "  cache_max  = unlimited\n");
+   else
+      fprintf(STDERR, "  cache_max  = %lu\n",
+         (unsigned long) png_get_chunk_cache_max(dummy_ptr));
+   if (png_get_chunk_malloc_max(dummy_ptr) == 0)
+      fprintf(STDERR, "  malloc_max = unlimited\n");
+   else
+      fprintf(STDERR, "  malloc_max = %lu\n",
+         (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
+   png_destroy_read_struct(&dummy_ptr, NULL, NULL);
+
    return (int)(ierror != 0);
 }
 #else
@@ -2008,4 +2028,4 @@
 #endif
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_16 Your_png_h_is_not_version_1_6_16;
+typedef png_libpng_version_1_6_17 Your_png_h_is_not_version_1_6_17;
diff --git a/pngtrans.c b/pngtrans.c
index 56856b4..cd3a79b 100644
--- a/pngtrans.c
+++ b/pngtrans.c
@@ -1,8 +1,8 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
diff --git a/pngusr.dfa b/pngusr.dfa
index 9d39564..83067c3 100644
--- a/pngusr.dfa
+++ b/pngusr.dfa
@@ -8,7 +8,7 @@
 # here by entering the appropriate values as #defines preceded by '@' (to cause,
 # them to be passed through to the build of pnglibconf.h), for example:
 #
-# @# define PNG_USER_WIDTH_MAX 1000000
-# @# define PNG_USER_HEIGHT_MAX 1000000
-# @# define PNG_USER_CHUNK_CACHE_MAX 128
-# @# define PNG_USER_CHUNK_MALLOC_MAX 8000000
+# @# define PNG_USER_WIDTH_MAX 65535
+# @# define PNG_USER_HEIGHT_MAX 65535
+# @# define PNG_USER_CHUNK_CACHE_MAX 256
+# @# define PNG_USER_CHUNK_MALLOC_MAX 640000
diff --git a/pngwrite.c b/pngwrite.c
index 9454887..e3c2034 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -1,8 +1,8 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -638,8 +638,8 @@
 
          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
          {
-            *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
-            *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
+            *(rp)     = (png_byte)(*rp       - *(rp + 1));
+            *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1));
          }
       }
 
@@ -665,10 +665,10 @@
             png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
             png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
             png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
-            *(rp    ) = (png_byte)((red >> 8) & 0xff);
-            *(rp + 1) = (png_byte)(red & 0xff);
-            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
-            *(rp + 5) = (png_byte)(blue & 0xff);
+            *(rp    ) = (png_byte)(red >> 8);
+            *(rp + 1) = (png_byte)red;
+            *(rp + 4) = (png_byte)(blue >> 8);
+            *(rp + 5) = (png_byte)blue;
          }
       }
 #endif /* WRITE_16BIT */
@@ -1050,8 +1050,8 @@
        * it is too late to start using the filters that need it, since we
        * will be missing the data in the previous row.  If an application
        * wants to start and stop using particular filters during compression,
-       * it should start out with all of the filters, and then add and
-       * remove them after the start of compression.
+       * it should start out with all of the filters, and then remove them
+       * or add them back after the start of compression.
        */
       if (png_ptr->row_buf != NULL)
       {
@@ -1372,6 +1372,7 @@
 #endif /* FIXED_POINT */
 #endif /* WRITE_WEIGHTED_FILTER */
 
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
 void PNGAPI
 png_set_compression_level(png_structrp png_ptr, int level)
 {
@@ -1417,8 +1418,8 @@
    if (png_ptr == NULL)
       return;
 
-   /* Prior to 1.6.0 this would warn but then set the window_bits value, this
-    * meant that negative window bits values could be selected which would cause
+   /* Prior to 1.6.0 this would warn but then set the window_bits value. This
+    * meant that negative window bits values could be selected that would cause
     * libpng to write a non-standard PNG file with raw deflate or gzip
     * compressed IDAT or ancillary chunks.  Such files can be read and there is
     * no warning on read, so this seems like a very bad idea.
@@ -1454,6 +1455,7 @@
 
    png_ptr->zlib_method = method;
 }
+#endif /* WRITE_CUSTOMIZE_COMPRESSION */
 
 /* The following were added to libpng-1.5.4 */
 #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
@@ -2287,7 +2289,9 @@
        * it about 50 times.  The speed-up in pngstest was about 10-20% of the
        * total (user) time on a heavily loaded system.
        */
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
       png_set_compression_level(png_ptr, 3);
+#endif
    }
 
    /* Check for the cases that currently require a pre-transform on the row
diff --git a/pngwtran.c b/pngwtran.c
index 09562a7..db82e27 100644
--- a/pngwtran.c
+++ b/pngwtran.c
@@ -1,8 +1,8 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
diff --git a/pngwutil.c b/pngwutil.c
index 10c1edf..b289671 100644
--- a/pngwutil.c
+++ b/pngwutil.c
@@ -1,8 +1,8 @@
 
 /* pngwutil.c - utilities to write a PNG file
  *
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.17 [March 26, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -23,10 +23,10 @@
 void PNGAPI
 png_save_uint_32(png_bytep buf, png_uint_32 i)
 {
-   buf[0] = (png_byte)((i >> 24) & 0xff);
-   buf[1] = (png_byte)((i >> 16) & 0xff);
-   buf[2] = (png_byte)((i >> 8) & 0xff);
-   buf[3] = (png_byte)(i & 0xff);
+   buf[0] = (png_byte)(i >> 24);
+   buf[1] = (png_byte)(i >> 16);
+   buf[2] = (png_byte)(i >> 8);
+   buf[3] = (png_byte)(i     );
 }
 
 /* Place a 16-bit number into a buffer in PNG byte order.
@@ -36,8 +36,8 @@
 void PNGAPI
 png_save_uint_16(png_bytep buf, unsigned int i)
 {
-   buf[0] = (png_byte)((i >> 8) & 0xff);
-   buf[1] = (png_byte)(i & 0xff);
+   buf[0] = (png_byte)(i >> 8);
+   buf[1] = (png_byte)(i     );
 }
 #endif
 
@@ -695,7 +695,7 @@
 
    while (*key && key_len < 79)
    {
-      png_byte ch = (png_byte)(0xff & *key++);
+      png_byte ch = (png_byte)*key++;
 
       if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
          *new_key++ = ch, ++key_len, space = 0;
@@ -871,7 +871,7 @@
    interlace_type=PNG_INTERLACE_NONE;
 #endif
 
-   /* Save the relevent information */
+   /* Save the relevant information */
    png_ptr->bit_depth = (png_byte)bit_depth;
    png_ptr->color_type = (png_byte)color_type;
    png_ptr->interlaced = (png_byte)interlace_type;
@@ -1765,7 +1765,7 @@
       png_write_compressed_data_out(png_ptr, &comp);
 
    else
-      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len);
+      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len);
 
    png_write_chunk_end(png_ptr);
 }
@@ -2314,7 +2314,7 @@
  * been specified by the application, and then writes the row out with the
  * chosen filter.
  */
-static void
+static void /* PRIVATE */
 png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
    png_size_t row_bytes);
 
@@ -2453,7 +2453,7 @@
       for (lp = row_buf + 1; i < row_bytes;
          i++, rp++, lp++, dp++)
       {
-         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+         *dp = (png_byte)((int)*rp - (int)*lp);
       }
 
       best_row = png_ptr->sub_row;
@@ -2515,7 +2515,7 @@
       for (lp = row_buf + 1; i < row_bytes;
          i++, rp++, lp++, dp++)
       {
-         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+         v = *dp = (png_byte)((int)*rp - (int)*lp);
 
          sum += (v < 128) ? v : 256 - v;
 
@@ -2574,7 +2574,7 @@
           pp = prev_row + 1; i < row_bytes;
           i++, rp++, pp++, dp++)
       {
-         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+         *dp = (png_byte)((int)*rp - (int)*pp);
       }
 
       best_row = png_ptr->up_row;
@@ -2625,7 +2625,7 @@
       for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
           pp = prev_row + 1; i < row_bytes; i++)
       {
-         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+         v = *dp++ = (png_byte)((int)*rp++ - (int)*pp++);
 
          sum += (v < 128) ? v : 256 - v;
 
@@ -2683,13 +2683,13 @@
       for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
            pp = prev_row + 1; i < bpp; i++)
       {
-         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+         *dp++ = (png_byte)((int)*rp++ - ((int)*pp++ / 2));
       }
 
       for (lp = row_buf + 1; i < row_bytes; i++)
       {
-         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
-                 & 0xff);
+         *dp++ =
+             (png_byte)((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2));
       }
       best_row = png_ptr->avg_row;
    }
@@ -2738,7 +2738,7 @@
       for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
            pp = prev_row + 1; i < bpp; i++)
       {
-         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+         v = *dp++ = (png_byte)((int)*rp++ - ((int)*pp++ / 2));
 
          sum += (v < 128) ? v : 256 - v;
       }
@@ -2746,7 +2746,7 @@
       for (lp = row_buf + 1; i < row_bytes; i++)
       {
          v = *dp++ =
-             (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+             (png_byte)(((int)*rp++ - ((int)*pp++ + (int)*lp++) / 2));
 
          sum += (v < 128) ? v : 256 - v;
 
@@ -2804,7 +2804,7 @@
       for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
           pp = prev_row + 1; i < bpp; i++)
       {
-         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+         *dp++ = (png_byte)((int)*rp++ - (int)*pp++);
       }
 
       for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
@@ -2830,7 +2830,7 @@
 
          p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
 
-         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+         *dp++ = (png_byte)((int)*rp++ - p);
       }
       best_row = png_ptr->paeth_row;
    }
@@ -2879,7 +2879,7 @@
       for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
           pp = prev_row + 1; i < bpp; i++)
       {
-         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+         v = *dp++ = (png_byte)((int)*rp++ - (int)*pp++);
 
          sum += (v < 128) ? v : 256 - v;
       }
@@ -2921,7 +2921,7 @@
             p = c;
 #endif /* SLOW_PAETH */
 
-         v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+         v = *dp++ = (png_byte)((int)*rp++ - p);
 
          sum += (v < 128) ? v : 256 - v;
 
@@ -3003,6 +3003,7 @@
 
    png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
 
+#ifdef PNG_WRITE_FILTER_SUPPORTED
    /* Swap the current and previous rows */
    if (png_ptr->prev_row != NULL)
    {
@@ -3012,6 +3013,7 @@
       png_ptr->prev_row = png_ptr->row_buf;
       png_ptr->row_buf = tptr;
    }
+#endif /* WRITE_FILTER */
 
    /* Finish row - updates counters and flushes zlib if last row */
    png_write_finish_row(png_ptr);
diff --git a/projects/vstudio/readme.txt b/projects/vstudio/readme.txt
index e7a02d8..a2521f2 100644
--- a/projects/vstudio/readme.txt
+++ b/projects/vstudio/readme.txt
@@ -1,7 +1,7 @@
 
 VisualStudio instructions
 
-libpng version 1.6.16 - December 22, 2014
+libpng version 1.6.17 - March 26, 2015
 
 Copyright (c) 1998-2010 Glenn Randers-Pehrson
 
diff --git a/projects/vstudio/zlib.props b/projects/vstudio/zlib.props
index adbfea8..5d6d69b 100644
--- a/projects/vstudio/zlib.props
+++ b/projects/vstudio/zlib.props
@@ -2,7 +2,7 @@
 <!--
  * zlib.props - location of zlib source
  *
- * libpng version 1.6.16 - December 22, 2014
+ * libpng version 1.6.17 - March 26, 2015
  *
  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
  *
diff --git a/scripts/README.txt b/scripts/README.txt
index b689f81..f6a9cf3 100644
--- a/scripts/README.txt
+++ b/scripts/README.txt
@@ -1,9 +1,9 @@
 
-Makefiles for  libpng version 1.6.16 - December 22, 2014
+Makefiles for  libpng version 1.6.17 - March 26, 2015
 
 pnglibconf.h.prebuilt       =>  Stores configuration settings
  makefile.linux    =>  Linux/ELF makefile
-                       (gcc, creates libpng16.so.16.1.6.16)
+                       (gcc, creates libpng16.so.16.1.6.17)
  makefile.gcc      =>  Generic makefile (gcc, creates static libpng.a)
  makefile.knr      =>  Archaic UNIX Makefile that converts files with
                        ansi2knr (Requires ansi2knr.c from
@@ -33,12 +33,12 @@
  makefile.os2      =>  OS/2 Makefile (gcc and emx, requires libpng.def)
  makefile.sco      =>  For SCO OSr5  ELF and Unixware 7 with Native cc
  makefile.sggcc    =>  Silicon Graphics (gcc,
-                       creates libpng16.so.16.1.6.16)
+                       creates libpng16.so.16.1.6.17)
  makefile.sgi      =>  Silicon Graphics IRIX makefile (cc, creates static lib)
  makefile.solaris  =>  Solaris 2.X makefile (gcc,
-                       creates libpng16.so.16.1.6.16)
+                       creates libpng16.so.16.1.6.17)
  makefile.so9      =>  Solaris 9 makefile (gcc,
-                       creates libpng16.so.16.1.6.16)
+                       creates libpng16.so.16.1.6.17)
  makefile.std      =>  Generic UNIX makefile (cc, creates static libpng.a)
  makefile.sunos    =>  Sun makefile
  makefile.32sunu   =>  Sun Ultra 32-bit makefile
diff --git a/scripts/def.c b/scripts/def.c
index 19b796d..9c88f77 100644
--- a/scripts/def.c
+++ b/scripts/def.c
@@ -21,7 +21,7 @@
 PNG_DFN "OS2 CODE PRELOAD MOVEABLE DISCARDABLE"
 PNG_DFN ""
 PNG_DFN "EXPORTS"
-PNG_DFN ";Version 1.6.16"
+PNG_DFN ";Version 1.6.17"
 
 #define PNG_EXPORTA(ordinal, type, name, args, attributes)\
         PNG_DFN "@" SYMBOL_PREFIX "@@" name "@"
diff --git a/scripts/dfn.awk b/scripts/dfn.awk
index 675829d..346b9db 100755
--- a/scripts/dfn.awk
+++ b/scripts/dfn.awk
Binary files differ
diff --git a/scripts/libpng-config-head.in b/scripts/libpng-config-head.in
index 0d96b65..d19010d 100644
--- a/scripts/libpng-config-head.in
+++ b/scripts/libpng-config-head.in
@@ -11,7 +11,7 @@
 
 # Modeled after libxml-config.
 
-version=1.6.16
+version=1.6.17
 prefix=""
 libdir=""
 libs=""
diff --git a/scripts/libpng.pc.in b/scripts/libpng.pc.in
index 2c26539..ce61a3e 100644
--- a/scripts/libpng.pc.in
+++ b/scripts/libpng.pc.in
@@ -5,6 +5,6 @@
 
 Name: libpng
 Description: Loads and saves PNG files
-Version: 1.6.16
+Version: 1.6.17
 Libs: -L${libdir} -lpng16
 Cflags: -I${includedir}
diff --git a/scripts/makefile.cegcc b/scripts/makefile.cegcc
index 06515fd..cc56297 100644
--- a/scripts/makefile.cegcc
+++ b/scripts/makefile.cegcc
@@ -23,7 +23,7 @@
 
 VERMAJ = 1
 VERMIN = 6
-VERMIC = 16
+VERMIC = 17
 VER = $(VERMAJ).$(VERMIN).$(VERMIC)
 NAME = libpng
 PACKAGE = $(NAME)-$(VER)
diff --git a/scripts/makefile.linux b/scripts/makefile.linux
index 06f773a..86a397f 100644
--- a/scripts/makefile.linux
+++ b/scripts/makefile.linux
@@ -10,7 +10,7 @@
 # Library name:
 LIBNAME = libpng16
 PNGMAJ = 16
-RELEASE = 16
+RELEASE = 17
 
 # Shared library names:
 LIBSO=$(LIBNAME).so
diff --git a/scripts/makefile.msys b/scripts/makefile.msys
index 106fb8a..30595a0 100644
--- a/scripts/makefile.msys
+++ b/scripts/makefile.msys
@@ -18,7 +18,7 @@
 # Library name:
 LIBNAME = libpng16
 PNGMAJ = 16
-RELEASE = 16
+RELEASE = 17
 
 # Shared library names:
 LIBSO=$(LIBNAME).dll
diff --git a/scripts/makefile.ne12bsd b/scripts/makefile.ne12bsd
index e3b7baa..d5be81c 100644
--- a/scripts/makefile.ne12bsd
+++ b/scripts/makefile.ne12bsd
@@ -17,7 +17,7 @@
 
 LIB=	png16
 SHLIB_MAJOR=	0
-SHLIB_MINOR=	1.6.16
+SHLIB_MINOR=	1.6.17
 SRCS=	png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
 	pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
 	pngwtran.c pngmem.c pngerror.c pngpread.c
diff --git a/scripts/makefile.netbsd b/scripts/makefile.netbsd
index 2cc7a17..58c4884 100644
--- a/scripts/makefile.netbsd
+++ b/scripts/makefile.netbsd
@@ -17,7 +17,7 @@
 
 LIB=	png
 SHLIB_MAJOR=	16
-SHLIB_MINOR=	1.6.16
+SHLIB_MINOR=	1.6.17
 SRCS=	png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
 	pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
 	pngwtran.c pngmem.c pngerror.c pngpread.c
diff --git a/scripts/makefile.openbsd b/scripts/makefile.openbsd
index debc2a2..0ef62a4 100644
--- a/scripts/makefile.openbsd
+++ b/scripts/makefile.openbsd
@@ -11,7 +11,7 @@
 MANDIR= ${PREFIX}/man/cat
 
 SHLIB_MAJOR=	16
-SHLIB_MINOR=	1.6.16
+SHLIB_MINOR=	1.6.17
 
 LIB=	png
 SRCS=	png.c pngerror.c pngget.c pngmem.c pngpread.c \
diff --git a/scripts/makefile.std b/scripts/makefile.std
index 75bb2de..ee6a868 100644
--- a/scripts/makefile.std
+++ b/scripts/makefile.std
@@ -106,7 +106,8 @@
 	chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a
 
 clean:
-	$(RM_F) *.o libpng.a pngtest pngout.png pnglibconf.*
+	$(RM_F) *.o libpng.a pngtest pngout.png pnglibconf.h pnglibconf.c \
+	pnglibconf.out
 
 DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
 writelock:
diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa
index d98d274..e9a82f3 100644
--- a/scripts/pnglibconf.dfa
+++ b/scripts/pnglibconf.dfa
@@ -350,36 +350,15 @@
 
 option IO_STATE
 
-# This is only for PowerPC big-endian and 680x0 systems
-# some testing, not enabled by default.
-# NO LONGER USED
-
-#option READ_BIG_ENDIAN disabled
-
-# Allow users to control limits on what the READ code will
-# read:
-
-# Added at libpng-1.2.43; adds limit fields to png_struct,
-# allows some usages of these fields
-
-option USER_LIMITS
-
-# Added at libpng-1.2.6; adds setting APIs, allows additional
-# usage of this field (UTSL)
-
-option SET_USER_LIMITS requires USER_LIMITS
-
-# Feature added at libpng-1.4.0, this flag added at 1.4.1
-option SET_USER_LIMITS enables SET_CHUNK_CACHE_LIMIT
-# Feature added at libpng-1.4.1, this flag added at 1.4.1
-
-option SET_USER_LIMITS enables SET_CHUNK_MALLOC_LIMIT
-
-# Libpng limits.
+# Libpng limits: limit the size of images and data on read.
 #
-# If these settings are *not* set libpng will not limit the size of
-# images or the size of data in ancilliary chunks.  This does lead to
-# security issues if PNG files come from untrusted sources.  Settings have the
+# If this option is disabled all the limit checking code will be disabled:
+
+option USER_LIMITS requires READ
+
+# The default settings given below for the limits mean that libpng will
+# limit the size of images or the size of data in ancilliary chunks to less
+# than the specification or implementation limits. Settings have the
 # following interpretations:
 #
 # USER_WIDTH_MAX: maximum width of an image that will be read
@@ -388,18 +367,18 @@
 # USER_CHUNK_CACHE_MAX: maximum number of chunks to be cached
 #
 # Only chunks that are variable in number are counted towards the
-# USER_CHUNK_CACHE_MAX limit
-setting USER_WIDTH_MAX
-setting USER_HEIGHT_MAX
-setting USER_CHUNK_CACHE_MAX
-setting USER_CHUNK_MALLOC_MAX
 
-# To default all these settings to values that are large but probably
-# safe turn the SAFE_LIMITS option on; this will cause the value in
-# pngpriv.h to be used.  Individual values can also be set, simply set
-# them in pngusr.dfa with '@#define PNG_setting value' lines.
-option SAFE_LIMITS enables USER_LIMITS disabled
-= SAFE_LIMITS SAFE_LIMITS
+# Use 0x7fffffff for unlimited
+setting USER_WIDTH_MAX default        1000000
+setting USER_HEIGHT_MAX default       1000000
+
+# Use 0 for unlimited
+setting USER_CHUNK_CACHE_MAX default     1000
+setting USER_CHUNK_MALLOC_MAX default 8000000
+
+# If this option is enabled APIs to set the above limits at run time are added;
+# without this the hardwired (compile time) limits will be used.
+option SET_USER_LIMITS requires USER_LIMITS
 
 # All of the following options relate to code capabilities for
 # processing image data before creating a PNG or after reading one.
@@ -541,6 +520,7 @@
 # non-IDAT chunks (zTXt, iTXt, iCCP, and unknown chunks).  This feature
 # was added at libpng-1.5.3.
 option WRITE_CUSTOMIZE_ZTXT_COMPRESSION requires WRITE
+option WRITE_CUSTOMIZE_COMPRESSION requires WRITE
 
 # Any chunks you are not interested in, you can undef here.  The
 # ones that allocate memory may be expecially important (hIST,
@@ -666,7 +646,7 @@
 # are only interested in 8 bits anyway.  Increasing this value
 # results in more memory being used, and more pow() functions
 # being called to fill in the gamma tables.  Don't set this value
-# less then 8, and even that may not work (I haven't tested it).
+# less than 8, and even that may not work (I haven't tested it).
 
 setting MAX_GAMMA_8 default 11
 
diff --git a/scripts/pnglibconf.h.prebuilt b/scripts/pnglibconf.h.prebuilt
index da3b229..b4ec3c3 100644
--- a/scripts/pnglibconf.h.prebuilt
+++ b/scripts/pnglibconf.h.prebuilt
@@ -1,8 +1,8 @@
-/* libpng 1.6.16 STANDARD API DEFINITION */
+/* libpng 1.6.17 STANDARD API DEFINITION */
 
 /* pnglibconf.h - library build configuration */
 
-/* Libpng version 1.6.16 - December 22, 2014 */
+/* Libpng version 1.6.17 - March 26, 2015 */
 
 /* Copyright (c) 1998-2014 Glenn Randers-Pehrson */
 
@@ -97,7 +97,6 @@
 #define PNG_READ_tIME_SUPPORTED
 #define PNG_READ_tRNS_SUPPORTED
 #define PNG_READ_zTXt_SUPPORTED
-/*#undef PNG_SAFE_LIMITS_SUPPORTED*/
 #define PNG_SAVE_INT_32_SUPPORTED
 #define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SEQUENTIAL_READ_SUPPORTED
@@ -129,6 +128,7 @@
 #define PNG_WRITE_BGR_SUPPORTED
 #define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
 #define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
 #define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
 #define PNG_WRITE_FILLER_SUPPORTED
 #define PNG_WRITE_FILTER_SUPPORTED
@@ -198,6 +198,10 @@
 #define PNG_QUANTIZE_RED_BITS 5
 #define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
 #define PNG_TEXT_Z_DEFAULT_STRATEGY 0
+#define PNG_USER_CHUNK_CACHE_MAX 1000
+#define PNG_USER_CHUNK_MALLOC_MAX 8000000
+#define PNG_USER_HEIGHT_MAX 1000000
+#define PNG_USER_WIDTH_MAX 1000000
 #define PNG_WEIGHT_SHIFT 8
 #define PNG_ZBUF_SIZE 8192
 #define PNG_ZLIB_VERNUM 0 /* unknown */
diff --git a/scripts/pnglibconf.mak b/scripts/pnglibconf.mak
index c7117dd..c125ca2 100755
--- a/scripts/pnglibconf.mak
+++ b/scripts/pnglibconf.mak
@@ -49,6 +49,7 @@
 	$(MOVE) pnglibconf.tmp $@
 
 clean-pnglibconf:
-	$(DELETE) pnglibconf.*
+	$(DELETE) pnglibconf.h pnglibconf.c pnglibconf.out pnglibconf.pre \
+	pnglibconf.dfn
 
 clean: clean-pnglibconf
diff --git a/scripts/symbols.def b/scripts/symbols.def
index 1283743..5bdcef2 100644
--- a/scripts/symbols.def
+++ b/scripts/symbols.def
@@ -1,4 +1,4 @@
-;Version 1.6.16
+;Version 1.6.17
 ;--------------------------------------------------------------
 ; LIBPNG symbol list as a Win32 DEF file
 ; Contains all the symbols that can be exported from libpng