Bug 886499 - Update libpng to version 1.5.17. r=joe
authorGlenn Randers-Pehrson <glennrp+bmo@gmail.com>
Tue, 02 Jul 2013 10:32:43 -0400
changeset 137160 28298b00b5cbd95cb57fc8d566e8051d1aba9a45
parent 137159 06ebc153d958ff23da8f07631dd11b7bb8e049c8
child 137161 c7174efdf93b024577676cd44b5925161d4fcd81
push id24909
push userkhuey@mozilla.com
push dateTue, 02 Jul 2013 16:45:38 +0000
treeherdermozilla-central@23ce4eab8fb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs886499
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 886499 - Update libpng to version 1.5.17. r=joe
configure.in
media/libpng/CHANGES
media/libpng/LICENSE
media/libpng/MOZCHANGES
media/libpng/README
media/libpng/apng.patch
media/libpng/arm/arm_init.c
media/libpng/arm/filter_neon.S
media/libpng/png.c
media/libpng/png.h
media/libpng/pngconf.h
media/libpng/pngget.c
media/libpng/pngpread.c
media/libpng/pngpriv.h
media/libpng/pngread.c
media/libpng/pngrutil.c
media/libpng/pngset.c
media/libpng/pngwrite.c
media/libpng/pngwutil.c
--- a/configure.in
+++ b/configure.in
@@ -46,17 +46,17 @@ dnl ====================================
 _SUBDIR_HOST_CFLAGS="$HOST_CFLAGS"
 _SUBDIR_HOST_CXXFLAGS="$HOST_CXXFLAGS"
 _SUBDIR_HOST_LDFLAGS="$HOST_LDFLAGS"
 _SUBDIR_CONFIG_ARGS="$ac_configure_args"
 
 dnl Set the version number of the libs included with mozilla
 dnl ========================================================
 MOZJPEG=62
-MOZPNG=10516
+MOZPNG=10517
 NSPR_VERSION=4
 NSS_VERSION=3
 
 dnl Set the minimum version of toolkit libs used by mozilla
 dnl ========================================================
 GLIB_VERSION=1.2.0
 PERL_VERSION=5.006
 CAIRO_VERSION=1.10
--- a/media/libpng/CHANGES
+++ b/media/libpng/CHANGES
@@ -4106,16 +4106,54 @@ Version 1.5.16beta06 [May 12, 2013]
     to generate pnglibconf.h with the right zlib header files.
   Ported contrib/pngminus/pnm2png.c changes back from libpng-1.6.3beta06,
     to use unsigned long, not png_uint_32 arguments to sscanf().
 
 Version 1.5.16rc01 [May 16, 2013]
   No changes.
 
 Version 1.5.16 [May 23, 2013]
+  No changes.
+
+Version 1.5.17beta01 [June 8, 2013]
+  Removed a redundant test from png_set_IHDR().
+  Added set(CMAKE_CONFIGURATION_TYPES ...) to CMakeLists.txt (Andrew Hundt)
+  Deleted set(CMAKE_BUILD_TYPE) block from CMakeLists.txt
+  Make ARM NEON support work at compile time (not just configure time).
+    This moves the test on __ARM_NEON__ into pngconf.h to avoid issues when
+    using a compiler that compiles for multiple architectures at one time.
+  Removed PNG_FILTER_OPTIMIZATIONS and PNG_ARM_NEON_SUPPORTED from
+    pnglibconf.h, allowing more of the decisions to be made internally
+    (pngpriv.h) during the compile.  Without this, symbol prefixing is broken
+    under certain circumstances on ARM platforms.  Now only the API parts of
+    the optimizations ('check' vs 'api') are exposed in the public header files
+    except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the
+    decision about whether or not to use the optimizations.
+  Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage.
+    Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test
+    on __ARM_NEON__ from configure time to compile time.  This breaks symbol
+    prefixing because the definition of the special png_init_filter_functions
+    call was hidden at configure time if the relevant compiler arguments are
+    passed in CFLAGS as opposed to CC.  This change attempts to avoid all
+    the confusion that would result by declaring the init function even when
+    it is not used, so that it will always get prefixed.
+
+Version 1.5.17rc01 [June 17, 2013]
+  No changes.
+
+Version 1.5.17rc02 [June 18, 2013]
+  Revised libpng.3 so that "doclifter" can process it.
+
+Version 1.5.17rc03 [June 25, 2013]
+  Revised example.c to illustrate use of PNG_DEFAULT_sRGB and PNG_GAMMA_MAC_18
+    as parameters for png_set_gamma().  These have been available since
+    libpng-1.5.4.
+
+Version 1.5.17 [June 27, 2013]
+  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
 to subscribe)
 or to glennrp at users.sourceforge.net
 
 Glenn R-P
--- a/media/libpng/LICENSE
+++ b/media/libpng/LICENSE
@@ -5,17 +5,17 @@ included in the libpng distribution, the
 
 COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
 
 If you modify libpng you may insert additional notices immediately following
 this sentence.
 
 This code is released under the libpng license.
 
-libpng versions 1.2.6, August 15, 2004, through 1.5.16, May 23, 2013, are
+libpng versions 1.2.6, August 15, 2004, through 1.5.17, June 27, 2013, are
 Copyright (c) 2004, 2006-2012 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
 
    Cosmin Truta
 
 libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
 Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
@@ -103,9 +103,9 @@ boxes and the like:
 Also, the PNG logo (in PNG format, of course) is supplied in the
 files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
 
 Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
 certification mark of the Open Source Initiative.
 
 Glenn Randers-Pehrson
 glennrp at users.sourceforge.net
-May 23, 2013
+June 27, 2013
--- a/media/libpng/MOZCHANGES
+++ b/media/libpng/MOZCHANGES
@@ -1,11 +1,13 @@
 
 Changes made to pristine png source by mozilla.org developers.
 
+2013/06/29  -- Synced with libpng-1.5.17 (bug #886499).
+
 2013/06/06  -- Synced with libpng-1.5.16 (bug #873001).
 
 2013/04/11  -- Synced with libpng-1.5.15 (bug #858578).
 
 2013/01/24  -- Synced with libpng-1.5.14 (bug #832487).
 
 2013/01/23  -- Disabled TEXT support in mozpngconf.h (bug #833594).
 
--- a/media/libpng/README
+++ b/media/libpng/README
@@ -1,16 +1,17 @@
-README for libpng version 1.5.16 - May 23, 2013 (shared library 15.0)
+README for libpng version 1.5.17 - June 27, 2013 (shared library 15.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
 
 Libpng comes in several distribution formats.  Get libpng-*.tar.gz,
 libpng-*.tar.xz or libpng-*.tar.bz2 if you want UNIX-style line endings
-in the text files, or lpng*.zip if you want DOS-style line endings.
+in the text files, or lpng*.7z or lpng*.zip if you want DOS-style line
+endings.
 
 Version 0.89 was the first official release of libpng.  Don't let the
 fact that it's the first release fool you.  The libpng library has been in
 extensive use and testing since mid-1995.  By late 1997 it had
 finally gotten to the stage where there hadn't been significant
 changes to the API in some time, and people have a bad feeling about
 libraries with versions < 1.0.  Version 1.0.0 was released in
 March 1998.
@@ -72,27 +73,25 @@ versions as old as zlib 0.95.  Even so, 
 versions which can cause the output of invalid compression streams for
 some images.  You will definitely need zlib 1.0.4 or later if you are
 taking advantage of the MS-DOS "far" structure allocation for the small
 and medium memory models.  You should also note that zlib is a
 compression library that is useful for more things than just PNG files.
 You can use zlib as a drop-in replacement for fread() and fwrite() if
 you are so inclined.
 
-zlib should be available at the same place that libpng is, or at.
-ftp://ftp.info-zip.org/pub/infozip/zlib
+zlib should be available at the same place that libpng is, or at zlib.net.
 
 You may also want a copy of the PNG specification.  It is available
 as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
 these at http://www.libpng.org/pub/png/documents/
 
 This code is currently being archived at libpng.sf.net in the
-[DOWNLOAD] area, and on CompuServe, Lib 20 (PNG SUPPORT)
-at GO GRAPHSUP.  If you can't find it in any of those places,
-e-mail me, and I'll help you find it.
+[DOWNLOAD] area, and at ftp://ftp.simplesystems.org.  If you can't find it
+in any of those places, e-mail me, and I'll help you find it.
 
 If you have any code changes, requests, problems, etc., please e-mail
 them to me.  Also, I'd appreciate any make files or project files,
 and any modifications you needed to make to get libpng to compile,
 along with a #define variable to tell what compiler/system you are on.
 If you needed to add transformations to libpng, or wish libpng would
 provide the image in a different way, drop me a note (and code, if
 possible), so I can consider supporting the transformation.
@@ -100,17 +99,17 @@ Finally, if you get any warning messages
 (note: not zlib), and they are easy to fix, I'd appreciate the
 fix.  Please mention "libpng" somewhere in the subject line.  Thanks.
 
 This release was created and will be supported by myself (of course
 based in a large way on Guy's and Andreas' earlier work), and the PNG
 development group.
 
 Send comments/corrections/commendations to png-mng-implement at
-lists.sourceforge.net (subscription required; visit 
+lists.sourceforge.net (subscription required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
 to subscribe) or to glennrp at users.sourceforge.net
 
 You can't reach Guy, the original libpng author, at the addresses
 given in previous versions of this document.  He and Andreas will
 read mail addressed to the png-implement list, however.
 
 Please do not send general questions about PNG.  Send them to
@@ -118,17 +117,17 @@ png-mng-misc at lists.sf.net (subscripti
 https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
 subscribe).  If you have a question about something
 in the PNG specification that is related to using libpng, send it
 to me.  Send me any questions that start with "I was using libpng,
 and ...".  If in doubt, send questions to me.  I'll bounce them
 to others, if necessary.
 
 Please do not send suggestions on how to change PNG.  We have
-been discussing PNG for sixteen years now, and it is official and
+been discussing PNG for eighteen years now, and it is official and
 finished.  If you have suggestions for libpng, however, I'll
 gladly listen.  Even if your suggestion is not used immediately,
 it may be used later.
 
 Files in this distribution:
 
       ANNOUNCE      =>  Announcement of this version, with recent changes
       CHANGES       =>  Description of changes between libpng versions
@@ -162,33 +161,33 @@ Files in this distribution:
       pngset.c      =>  Functions for storing data into the info_struct
       pngtest.c     =>  Library test program
       pngtest.png   =>  Library test sample image
       pngtrans.c    =>  Common data transformation functions
       pngwio.c      =>  Lowest-level write I/O functions
       pngwrite.c    =>  High-level write functions
       pngwtran.c    =>  Write data transformations
       pngwutil.c    =>  Write utility functions
+      arm           =>  Contains optimized code for the ARM platform
       contrib       =>  Contributions
        gregbook         =>  source code for PNG reading and writing, from
                             Greg Roelofs' "PNG: The Definitive Guide",
                             O'Reilly, 1999
-       msvctest     =>  Builds and runs pngtest using a MSVC workspace
-       pngminus     =>  Simple pnm2png and png2pnm programs
-       pngsuite     =>  Test images
-       visupng      =>  Contains a MSVC workspace for VisualPng
+       libtests         =>  Contains the pngvalid.c test program
+       pngminim         =>  Minimal decoder, encoder, and progressive decoder
+                            programs demonstrating use of pngusr.dfa
+       pngminus         =>  Simple pnm2png and png2pnm programs
+       pngsuite         =>  Test images
+       visupng          =>  Contains a MSVC workspace for VisualPng
       projects      =>  Contains project files and workspaces for
                         building a DLL
-       cbuilder5        =>  Contains a Borland workspace for building
-                            libpng and zlib
-       visualc6         =>  Contains a Microsoft Visual C++ (MSVC)
-                            workspace for building libpng and zlib
+       owatcom          =>  Contains a WATCOM project for building libpng
        visualc71        =>  Contains a Microsoft Visual C++ (MSVC)
                             workspace for building libpng and zlib
-       xcode            =>  Contains an Apple xcode
+       vstudio          =>  Contains a Microsoft Visual C++ (MSVC)
                             workspace for building libpng and zlib
       scripts       =>  Directory containing scripts for building libpng:
                             (see scripts/README.txt for the list of scripts)
 
 Good luck, and happy coding.
 
 -Glenn Randers-Pehrson (current maintainer, since 1998)
  Internet: glennrp at users.sourceforge.net
--- a/media/libpng/apng.patch
+++ b/media/libpng/apng.patch
@@ -1,17 +1,176 @@
-diff --git libpng-1.5.16-orig/pngget.c libpng-1.5.16-sf/pngget.c
---- libpng-1.5.16-orig/pngget.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngget.c	2013-06-23 14:46:09.000000000 -0400
-@@ -1135,9 +1135,171 @@ png_get_palette_max(png_const_structp pn
-    if (png_ptr != NULL && info_ptr != NULL)
-       return png_ptr->num_palette_max;
+Index: pngread.c
+===================================================================
+--- pngread.c
++++ pngread.c
+@@ -240,6 +240,9 @@
+              !(png_ptr->mode & PNG_HAVE_PLTE))
+             png_error(png_ptr, "Missing PLTE before IDAT");
+ 
++#ifdef PNG_READ_APNG_SUPPORTED
++         png_have_info(png_ptr, info_ptr);
++#endif
+          png_ptr->idat_size = length;
+          png_ptr->mode |= PNG_HAVE_IDAT;
+          break;
+@@ -330,12 +333,91 @@
+          png_handle_iTXt(png_ptr, info_ptr, length);
+ #endif
+ 
++#ifdef PNG_READ_APNG_SUPPORTED
++      else if (chunk_name == png_acTL)
++         png_handle_acTL(png_ptr, info_ptr, length);
++
++      else if (chunk_name == png_fcTL)
++         png_handle_fcTL(png_ptr, info_ptr, length);
++
++      else if (chunk_name == png_fdAT)
++         png_handle_fdAT(png_ptr, info_ptr, length);
++#endif
++
+       else
+          png_handle_unknown(png_ptr, info_ptr, length);
+    }
+ }
+ #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  
-    return (-1);
- }
++#ifdef PNG_READ_APNG_SUPPORTED
++void PNGAPI
++png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
++{
++    png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
++
++    png_debug(0, "Reading frame head");
++
++    if (!(png_ptr->mode & PNG_HAVE_acTL))
++        png_error(png_ptr, "attempt to png_read_frame_head() but "
++                           "no acTL present");
++
++    /* do nothing for the main IDAT */
++    if (png_ptr->num_frames_read == 0)
++        return;
++
++    png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
++
++    png_read_reset(png_ptr);
++    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
++    png_ptr->mode &= ~PNG_HAVE_fcTL;
++
++    have_chunk_after_DAT = 0;
++    for (;;)
++    {
++        png_uint_32 length = png_read_chunk_header(png_ptr);
++
++        if (png_ptr->chunk_name == png_IDAT)
++        {
++            /* discard trailing IDATs for the first frame */
++            if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
++                png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
++            png_crc_finish(png_ptr, length);
++        }
++
++        else if (png_ptr->chunk_name == png_fcTL)
++        {
++            png_handle_fcTL(png_ptr, info_ptr, length);
++            have_chunk_after_DAT = 1;
++        }
++
++        else if (png_ptr->chunk_name == png_fdAT)
++        {
++            png_ensure_sequence_number(png_ptr, length);
++
++            /* discard trailing fdATs for frames other than the first */
++            if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
++                png_crc_finish(png_ptr, length - 4);
++            else if(png_ptr->mode & PNG_HAVE_fcTL)
++            {
++                png_ptr->idat_size = length - 4;
++                png_ptr->mode |= PNG_HAVE_IDAT;
++
++                break;
++            }
++            else
++                png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
++        }
++        else
++        {
++            png_warning(png_ptr, "Skipped (ignored) a chunk "
++                                 "between APNG chunks");
++            png_crc_finish(png_ptr, length);
++        }
++    }
++}
++#endif /* PNG_READ_APNG_SUPPORTED */
++
+ /* Optional call to update the users info_ptr structure */
+ void PNGAPI
+ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
+@@ -537,6 +619,38 @@
+    {
+       if (!(png_ptr->zstream.avail_in))
+       {
++#ifdef PNG_READ_APNG_SUPPORTED
++         png_uint_32 bytes_to_skip = 0;
++
++         while (!png_ptr->idat_size || bytes_to_skip != 0)
++         {
++            png_crc_finish(png_ptr, bytes_to_skip);
++            bytes_to_skip = 0;
++
++            png_ptr->idat_size = png_read_chunk_header(png_ptr);
++            if (png_ptr->num_frames_read == 0)
++            {
++               if (png_ptr->chunk_name != png_IDAT)
++                  png_error(png_ptr, "Not enough image data");
++            }
++            else
++            {
++               if (png_ptr->chunk_name == png_IEND)
++                  png_error(png_ptr, "Not enough image data");
++               if (png_ptr->chunk_name != png_fdAT)
++               {
++                  png_warning(png_ptr, "Skipped (ignored) a chunk "
++                                       "between APNG chunks");
++                  bytes_to_skip = png_ptr->idat_size;
++                  continue;
++               }
++
++               png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
++
++               png_ptr->idat_size -= 4;
++            }
++         }
++#else
+          while (!png_ptr->idat_size)
+          {
+             png_crc_finish(png_ptr, 0);
+@@ -545,6 +659,7 @@
+             if (png_ptr->chunk_name != png_IDAT)
+                png_error(png_ptr, "Not enough image data");
+          }
++#endif
+          png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+          png_ptr->zstream.next_in = png_ptr->zbuf;
+          if (png_ptr->zbuf_size > png_ptr->idat_size)
+@@ -563,6 +678,9 @@
+             png_benign_error(png_ptr, "Extra compressed data");
+          png_ptr->mode |= PNG_AFTER_IDAT;
+          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
++#ifdef PNG_READ_APNG_SUPPORTED
++         png_ptr->num_frames_read++;
++#endif
+          break;
+       }
+ 
+Index: pngget.c
+===================================================================
+--- pngget.c
++++ pngget.c
+@@ -1140,4 +1140,167 @@
  #  endif
  #endif
  
 +#ifdef PNG_APNG_SUPPORTED
 +png_uint_32 PNGAPI
 +png_get_acTL(png_structp png_ptr, png_infop info_ptr,
 +             png_uint_32 *num_frames, png_uint_32 *num_plays)
 +{
@@ -167,47 +326,34 @@ diff --git libpng-1.5.16-orig/pngget.c l
 +    if (png_ptr != NULL)
 +       return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
 +
 +    PNG_UNUSED(info_ptr)
 +
 +    return 0;
 +}
 +#endif /* PNG_APNG_SUPPORTED */
++
  #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
-diff --git libpng-1.5.16-orig/png.h libpng-1.5.16-sf/png.h
---- libpng-1.5.16-orig/png.h	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/png.h	2013-06-23 14:46:09.000000000 -0400
-@@ -446,16 +446,20 @@
-  */
- #ifndef PNGLCONF_H
-     /* If pnglibconf.h is missing, you can
-      * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
-      */
+Index: png.h
+===================================================================
+--- png.h
++++ png.h
+@@ -454,6 +454,10 @@
  #   include "pnglibconf.h"
  #endif
  
 +#define PNG_APNG_SUPPORTED
 +#define PNG_READ_APNG_SUPPORTED
 +#define PNG_WRITE_APNG_SUPPORTED
 +
  #ifndef PNG_VERSION_INFO_ONLY
  #  ifndef PNG_BUILDING_SYMBOL_TABLE
    /*
-    *   Standard header files (not needed for the version info or while
-    *   building symbol table -- see scripts/pnglibconf.dfa)
-    */
- #    ifdef PNG_SETJMP_SUPPORTED
- #      include <setjmp.h>
-@@ -553,16 +557,27 @@ extern "C" {
-  * Otherwise the calls are mapped to png_error.
-  */
- 
- /* Section 2: type definitions, including structures and compile time
-  * constants.
+@@ -561,6 +565,17 @@
   * See pngconf.h for base types that vary by machine/system
   */
  
 +#ifdef PNG_APNG_SUPPORTED
 +/* dispose_op flags from inside fcTL */
 +#define PNG_DISPOSE_OP_NONE        0x00
 +#define PNG_DISPOSE_OP_BACKGROUND  0x01
 +#define PNG_DISPOSE_OP_PREVIOUS    0x02
@@ -215,72 +361,42 @@ diff --git libpng-1.5.16-orig/png.h libp
 +/* blend_op flags from inside fcTL */
 +#define PNG_BLEND_OP_SOURCE        0x00
 +#define PNG_BLEND_OP_OVER          0x01
 +#endif /* PNG_APNG_SUPPORTED */
 +
  /* 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_5_16;
- 
- /* Three color definitions.  The order of the red, green, and blue, (and the
-  * exact size) is not important, although the size of the fields need to
-  * be png_byte or png_uint_16 (as defined below).
-@@ -836,16 +851,20 @@ typedef png_info FAR * FAR * png_infopp;
- #define PNG_INFO_oFFs 0x0100
- #define PNG_INFO_tIME 0x0200
- #define PNG_INFO_pCAL 0x0400
- #define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
- #define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
+@@ -844,6 +859,10 @@
  #define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
  #define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
  #define PNG_INFO_IDAT 0x8000   /* ESR, 1.0.6 */
 +#ifdef PNG_APNG_SUPPORTED
 +#define PNG_INFO_acTL 0x10000
 +#define PNG_INFO_fcTL 0x20000
 +#endif
  
  /* This is used for the transformation routines, as some of them
   * change these values for the row.  It also should enable using
-  * the routines for other purposes.
-  */
- typedef struct png_row_info_struct
- {
-    png_uint_32 width;    /* width of row */
-@@ -881,16 +900,20 @@ typedef PNG_CALLBACK(void, *png_flush_pt
- typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
-     int));
- typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
-     int));
- 
+@@ -889,6 +908,10 @@
  #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
  typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
 +#ifdef PNG_APNG_SUPPORTED
 +typedef PNG_CALLBACK(void, *png_progressive_frame_ptr, (png_structp,
 +    png_uint_32));
 +#endif
  
  /* The following callback receives png_uint_32 row_number, int pass for the
   * png_bytep data of the row.  When transforming an interlaced image the
-  * row number is the row number within the sub-image of the interlace pass, so
-  * the value will increase to the height of the sub-image (not the full image)
-  * then reset to 0 for the next pass.
-  *
-  * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
-@@ -2700,27 +2723,99 @@ PNG_EXPORT(235, int, png_get_palette_max
- 
- PNG_EXPORT(236, int, png_set_option, (png_structp png_ptr, int option,
-    int onoff));
- #endif
- 
- /*******************************************************************************
+@@ -2709,6 +2732,75 @@
   *  END OF HARDWARE OPTIONS
   ******************************************************************************/
+ 
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_EXPORT(237, png_uint_32, png_get_acTL, (png_structp png_ptr,
 +   png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
 +
 +PNG_EXPORT(238, png_uint_32, png_set_acTL, (png_structp png_ptr,
 +   png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
 +
 +PNG_EXPORT(239, png_uint_32, png_get_num_frames, (png_structp png_ptr,
@@ -339,48 +455,115 @@ diff --git libpng-1.5.16-orig/png.h libp
 +   png_uint_32 x_offset, png_uint_32 y_offset,
 +   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
 +   png_byte blend_op));
 +
 +PNG_EXPORT(256, void, png_write_frame_tail, (png_structp png_ptr,
 +   png_infop info_ptr));
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +#endif /* PNG_APNG_SUPPORTED */
- 
++
  /* Maintainer: Put new public prototypes here ^, in libpng.3, and project
   * defs
   */
- 
- /* The last ordinal number (this is the *last* one already used; the next
-  * one to use is one more than this.)  Maintainer, remember to add an entry to
+@@ -2718,7 +2810,11 @@
   * scripts/symbols.def as well.
   */
  #ifdef PNG_EXPORT_LAST_ORDINAL
 +#ifdef PNG_APNG_SUPPORTED
 +  PNG_EXPORT_LAST_ORDINAL(256);
 +#else
    PNG_EXPORT_LAST_ORDINAL(236);
 +#endif /* PNG_APNG_SUPPORTED */
  #endif
  
  #ifdef __cplusplus
- }
+Index: pngpriv.h
+===================================================================
+--- pngpriv.h
++++ pngpriv.h
+@@ -501,6 +501,10 @@
+ #define PNG_HAVE_PNG_SIGNATURE    0x1000
+ #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
+ #define PNG_HAVE_iCCP             0x4000
++#ifdef PNG_APNG_SUPPORTED
++#define PNG_HAVE_acTL             0x8000
++#define PNG_HAVE_fcTL            0x10000
++#endif
+ 
+ /* Flags for the transformations the PNG library does on the image data */
+ #define PNG_BGR                 0x0001
+@@ -698,6 +702,16 @@
+ #define png_tRNS PNG_CHUNK(116,  82,  78,  83)
+ #define png_zTXt PNG_CHUNK(122,  84,  88, 116)
+ 
++#ifdef PNG_APNG_SUPPORTED
++#define png_acTL PNG_CHUNK( 97,  99,  84,  76)
++#define png_fcTL PNG_CHUNK(102,  99,  84,  76)
++#define png_fdAT PNG_CHUNK(102, 100,  65,  84)
++
++/* For png_struct.apng_flags: */
++#define PNG_FIRST_FRAME_HIDDEN       0x0001
++#define PNG_APNG_APP                 0x0002
++#endif
++
+ /* The following will work on (signed char*) strings, whereas the get_uint_32
+  * macro will fail on top-bit-set values because of the sign extension.
+  */
+@@ -1389,6 +1403,45 @@
+     png_bytep row));
  #endif
  
- #endif /* PNG_VERSION_INFO_ONLY */
- /* Do not put anything past this line */
-diff --git libpng-1.5.16-orig/pnginfo.h libpng-1.5.16-sf/pnginfo.h
---- libpng-1.5.16-orig/pnginfo.h	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pnginfo.h	2013-06-23 14:46:09.000000000 -0400
-@@ -260,10 +260,23 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
- 
- #ifdef PNG_INFO_IMAGE_SUPPORTED
-    /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
-       non-zero */
-    /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
++#ifdef PNG_APNG_SUPPORTED
++PNG_EXTERN void png_ensure_fcTL_is_valid PNGARG((png_structp png_ptr,
++   png_uint_32 width, png_uint_32 height,
++   png_uint_32 x_offset, png_uint_32 y_offset,
++   png_uint_16 delay_num, png_uint_16 delay_den,
++   png_byte dispose_op, png_byte blend_op));
++
++#ifdef PNG_READ_APNG_SUPPORTED
++PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr,
++   png_uint_32 length));
++PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr,
++   png_uint_32 length));
++PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr,
++   png_uint_32 length));
++PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr));
++PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr,
++   png_uint_32 length));
++PNG_EXTERN void png_read_reset PNGARG((png_structp png_ptr));
++PNG_EXTERN void png_read_reinit PNGARG((png_structp png_ptr,
++   png_infop info_ptr));
++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
++PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr));
++#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
++#endif /* PNG_READ_APNG_SUPPORTED */
++
++#ifdef PNG_WRITE_APNG_SUPPORTED
++PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
++   png_uint_32 num_frames, png_uint_32 num_plays));
++PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
++   png_uint_32 width, png_uint_32 height,
++   png_uint_32 x_offset, png_uint_32 y_offset,
++   png_uint_16 delay_num, png_uint_16 delay_den,
++   png_byte dispose_op, png_byte blend_op));
++PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr));
++PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr,
++   png_infop info_ptr, png_uint_32 width, png_uint_32 height));
++#endif /* PNG_WRITE_APNG_SUPPORTED */
++#endif /* PNG_APNG_SUPPORTED */
++
+ /* Added at libpng version 1.4.0 */
+ #ifdef PNG_CHECK_cHRM_SUPPORTED
+ PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
+Index: pnginfo.h
+===================================================================
+--- pnginfo.h
++++ pnginfo.h
+@@ -265,5 +265,18 @@
     png_bytepp row_pointers;        /* the image bits */
  #endif
  
 +#ifdef PNG_APNG_SUPPORTED
 +   png_uint_32 num_frames; /* including default image */
 +   png_uint_32 num_plays;
 +   png_uint_32 next_frame_width;
 +   png_uint_32 next_frame_height;
@@ -389,25 +572,123 @@ diff --git libpng-1.5.16-orig/pnginfo.h 
 +   png_uint_16 next_frame_delay_num;
 +   png_uint_16 next_frame_delay_den;
 +   png_byte next_frame_dispose_op;
 +   png_byte next_frame_blend_op;
 +#endif
 +
  };
  #endif /* PNGINFO_H */
-diff --git libpng-1.5.16-orig/pngpread.c libpng-1.5.16-sf/pngpread.c
---- libpng-1.5.16-orig/pngpread.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngpread.c	2013-06-23 14:46:09.000000000 -0400
-@@ -210,16 +210,119 @@ png_push_read_chunk(png_structp png_ptr,
-       png_crc_read(png_ptr, chunk_tag, 4);
-       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
-       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
-    }
+Index: pngstruct.h
+===================================================================
+--- pngstruct.h
++++ pngstruct.h
+@@ -293,6 +293,27 @@
+    png_byte filter_type;
+ #endif
+ 
++#ifdef PNG_APNG_SUPPORTED
++   png_uint_32 apng_flags;
++   png_uint_32 next_seq_num;         /* next fcTL/fdAT chunk sequence number */
++   png_uint_32 first_frame_width;
++   png_uint_32 first_frame_height;
++
++#ifdef PNG_READ_APNG_SUPPORTED
++   png_uint_32 num_frames_read;      /* incremented after all image data of */
++                                     /* a frame is read */
++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
++   png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
++   png_progressive_frame_ptr frame_end_fn;  /* frame data read callback */
++#endif
++#endif
++
++#ifdef PNG_WRITE_APNG_SUPPORTED
++   png_uint_32 num_frames_to_write;
++   png_uint_32 num_frames_written;
++#endif
++#endif /* PNG_APNG_SUPPORTED */
++
+ /* New members added in libpng-1.2.0 */
+ 
+ /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+Index: pngwrite.c
+===================================================================
+--- pngwrite.c
++++ pngwrite.c
+@@ -58,6 +58,10 @@
+    /* The rest of these check to see if the valid field has the appropriate
+     * flag set, and if it does, writes the chunk.
+     */
++#ifdef PNG_WRITE_APNG_SUPPORTED
++   if (info_ptr->valid & PNG_INFO_acTL)
++      png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
++#endif
+ #ifdef PNG_WRITE_gAMA_SUPPORTED
+    if (info_ptr->valid & PNG_INFO_gAMA)
+       png_write_gAMA_fixed(png_ptr, info_ptr->gamma);
+@@ -310,6 +314,11 @@
+       png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
+ #endif
+ 
++#ifdef PNG_WRITE_APNG_SUPPORTED
++   if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
++      png_error(png_ptr, "Not enough frames written");
++#endif
++
+    /* See if user wants us to write information chunks */
+    if (info_ptr != NULL)
+    {
+@@ -1667,4 +1676,42 @@
+    PNG_UNUSED(params)
+ }
+ #endif
++
++#ifdef PNG_WRITE_APNG_SUPPORTED
++void PNGAPI
++png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
++    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
++    png_uint_32 x_offset, png_uint_32 y_offset,
++    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
++    png_byte blend_op)
++{
++    png_debug(1, "in png_write_frame_head");
++
++    /* there is a chance this has been set after png_write_info was called,
++    * so it would be set but not written. is there a way to be sure? */
++    if (!(info_ptr->valid & PNG_INFO_acTL))
++        png_error(png_ptr, "png_write_frame_head(): acTL not set");
++
++    png_write_reset(png_ptr);
++
++    png_write_reinit(png_ptr, info_ptr, width, height);
++
++    if ( !(png_ptr->num_frames_written == 0 &&
++           (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
++        png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
++                       delay_num, delay_den, dispose_op, blend_op);
++
++    PNG_UNUSED(row_pointers)
++}
++
++void PNGAPI
++png_write_frame_tail(png_structp png_ptr, png_infop info_ptr)
++{
++    png_debug(1, "in png_write_frame_tail");
++
++    png_ptr->num_frames_written++;
++
++    PNG_UNUSED(info_ptr)
++}
++#endif /* PNG_WRITE_APNG_SUPPORTED */
+ #endif /* PNG_WRITE_SUPPORTED */
+Index: pngpread.c
+===================================================================
+--- pngpread.c
++++ pngpread.c
+@@ -215,6 +215,109 @@
  
     chunk_name = png_ptr->chunk_name;
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +   if (png_ptr->num_frames_read > 0 &&
 +       png_ptr->num_frames_read < info_ptr->num_frames)
 +   {
 +      if (chunk_name == png_IDAT)
@@ -507,51 +788,31 @@ diff --git libpng-1.5.16-orig/pngpread.c
 +
 +      return;
 +   }
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
     if (chunk_name == png_IDAT)
     {
        /* This is here above the if/else case statement below because if the
-        * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
-        * completely skipped.
-        *
-        * TODO: there must be a better way of doing this.
-        */
-@@ -313,16 +416,20 @@ png_push_read_chunk(png_structp png_ptr,
-          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
-             if (png_ptr->push_length == 0)
-                return;
- 
-          if (png_ptr->mode & PNG_AFTER_IDAT)
+@@ -318,6 +421,10 @@
              png_benign_error(png_ptr, "Too many IDATs found");
        }
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +      png_have_info(png_ptr, info_ptr);
 +#endif
 +
        png_ptr->idat_size = png_ptr->push_length;
        png_ptr->mode |= PNG_HAVE_IDAT;
        png_ptr->process_mode = PNG_READ_IDAT_MODE;
-       png_push_have_info(png_ptr, info_ptr);
-       png_ptr->zstream.avail_out =
-           (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
-           png_ptr->iwidth) + 1;
-       png_ptr->zstream.next_out = png_ptr->row_buf;
-@@ -546,16 +653,38 @@ png_push_read_chunk(png_structp png_ptr,
-          return;
-       }
- 
-       png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+@@ -550,6 +657,27 @@
     }
  
  #endif
- 
 +#ifdef PNG_READ_APNG_SUPPORTED
 +   else if (chunk_name == png_acTL)
 +   {
 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 +      {
 +         png_push_save_buffer(png_ptr);
 +         return;
 +      }
@@ -563,48 +824,32 @@ diff --git libpng-1.5.16-orig/pngpread.c
 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
 +      {
 +         png_push_save_buffer(png_ptr);
 +         return;
 +      }
 +      png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
 +   }
 +#endif /* PNG_READ_APNG_SUPPORTED */
-+
+ 
     else
     {
-       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-       {
-          png_push_save_buffer(png_ptr);
-          return;
-       }
-       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
-@@ -753,40 +882,91 @@ void /* PRIVATE */
- png_push_read_IDAT(png_structp png_ptr)
- {
-    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
-    {
-       png_byte chunk_length[4];
+@@ -758,7 +886,11 @@
        png_byte chunk_tag[4];
  
        /* TODO: this code can be commoned up with the same code in push_read */
 +#ifdef PNG_READ_APNG_SUPPORTED
 +      if (png_ptr->buffer_size < 12)
 +#else
        if (png_ptr->buffer_size < 8)
 +#endif
        {
           png_push_save_buffer(png_ptr);
           return;
-       }
- 
-       png_push_fill_buffer(png_ptr, chunk_length, 4);
-       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
-       png_reset_crc(png_ptr);
-       png_crc_read(png_ptr, chunk_tag, 4);
+@@ -771,17 +903,64 @@
        png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
        png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +      if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
 +      {
 +          if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)
 +          {
@@ -659,53 +904,33 @@ diff --git libpng-1.5.16-orig/pngpread.c
 +      {
 +         png_ensure_sequence_number(png_ptr, 4);
 +         png_ptr->idat_size -= 4;
 +      }
 +#endif
     }
  
     if (png_ptr->idat_size && png_ptr->save_buffer_size)
-    {
-       png_size_t save_size = png_ptr->save_buffer_size;
-       png_uint_32 idat_size = png_ptr->idat_size;
- 
-       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
-@@ -854,16 +1034,25 @@ png_push_read_IDAT(png_structp png_ptr)
- void /* PRIVATE */
- png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
-    png_size_t buffer_length)
- {
-    /* The caller checks for a non-zero buffer length. */
+@@ -859,6 +1038,15 @@
     if (!(buffer_length > 0) || buffer == NULL)
        png_error(png_ptr, "No IDAT data (internal error)");
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +   /* If the app is not APNG-aware, decode only the first frame */
 +   if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
 +   {
 +     png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
 +     return;
 +   }
 +#endif
 +
     /* This routine must process all the data it has been given
      * before returning, calling the row callback as required to
      * handle the uncompressed results.
-     */
-    png_ptr->zstream.next_in = buffer;
-    png_ptr->zstream.avail_in = (uInt)buffer_length;
- 
-    /* Keep going until the decompressed data is all processed
-@@ -1299,16 +1488,28 @@ png_set_progressive_read_fn(png_structp
- 
-    png_ptr->info_fn = info_fn;
-    png_ptr->row_fn = row_fn;
-    png_ptr->end_fn = end_fn;
- 
+@@ -1304,6 +1492,18 @@
     png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  }
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +void PNGAPI
 +png_set_progressive_frame_fn(png_structp png_ptr,
 +   png_progressive_frame_ptr frame_info_fn,
 +   png_progressive_frame_ptr frame_end_fn)
@@ -714,361 +939,197 @@ diff --git libpng-1.5.16-orig/pngpread.c
 +   png_ptr->frame_end_fn = frame_end_fn;
 +   png_ptr->apng_flags |= PNG_APNG_APP;
 +}
 +#endif
 +
  png_voidp PNGAPI
  png_get_progressive_ptr(png_const_structp png_ptr)
  {
-    if (png_ptr == NULL)
-       return (NULL);
+Index: pngset.c
+===================================================================
+--- pngset.c
++++ pngset.c
+@@ -253,6 +253,11 @@
+    info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
  
-    return png_ptr->io_ptr;
- }
-diff --git libpng-1.5.16-orig/pngpriv.h libpng-1.5.16-sf/pngpriv.h
---- libpng-1.5.16-orig/pngpriv.h	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngpriv.h	2013-06-23 14:46:09.000000000 -0400
-@@ -456,16 +456,20 @@
- #define PNG_HAVE_sRGB               0x80
- #define PNG_HAVE_CHUNK_HEADER      0x100
- #define PNG_WROTE_tIME             0x200
- #define PNG_WROTE_INFO_BEFORE_PLTE 0x400
- #define PNG_BACKGROUND_IS_GRAY     0x800
- #define PNG_HAVE_PNG_SIGNATURE    0x1000
- #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
- #define PNG_HAVE_iCCP             0x4000
+    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
++
 +#ifdef PNG_APNG_SUPPORTED
-+#define PNG_HAVE_acTL             0x8000
-+#define PNG_HAVE_fcTL            0x10000
++   /* for non-animated png. this may be overwritten from an acTL chunk later */
++   info_ptr->num_frames = 1;
 +#endif
+ }
  
- /* Flags for the transformations the PNG library does on the image data */
- #define PNG_BGR                 0x0001
- #define PNG_INTERLACE           0x0002
- #define PNG_PACK                0x0004
- #define PNG_SHIFT               0x0008
- #define PNG_SWAP_BYTES          0x0010
- #define PNG_INVERT_MONO         0x0020
-@@ -653,16 +657,26 @@ PNG_EXTERN png_fixed_point png_fixed PNG
- #define png_sPLT PNG_CHUNK(115,  80,  76,  84)
- #define png_sRGB PNG_CHUNK(115,  82,  71,  66)
- #define png_sTER PNG_CHUNK(115,  84,  69,  82)
- #define png_tEXt PNG_CHUNK(116,  69,  88, 116)
- #define png_tIME PNG_CHUNK(116,  73,  77,  69)
- #define png_tRNS PNG_CHUNK(116,  82,  78,  83)
- #define png_zTXt PNG_CHUNK(122,  84,  88, 116)
+ #ifdef PNG_oFFs_SUPPORTED
+@@ -1039,6 +1044,147 @@
+ }
+ #endif /* PNG_sPLT_SUPPORTED */
  
 +#ifdef PNG_APNG_SUPPORTED
-+#define png_acTL PNG_CHUNK( 97,  99,  84,  76)
-+#define png_fcTL PNG_CHUNK(102,  99,  84,  76)
-+#define png_fdAT PNG_CHUNK(102, 100,  65,  84)
++png_uint_32 PNGAPI
++png_set_acTL(png_structp png_ptr, png_infop info_ptr,
++    png_uint_32 num_frames, png_uint_32 num_plays)
++{
++    png_debug1(1, "in %s storage function", "acTL");
 +
-+/* For png_struct.apng_flags: */
-+#define PNG_FIRST_FRAME_HIDDEN       0x0001
-+#define PNG_APNG_APP                 0x0002
-+#endif
++    if (png_ptr == NULL || info_ptr == NULL)
++    {
++        png_warning(png_ptr,
++                    "Call to png_set_acTL() with NULL png_ptr "
++                    "or info_ptr ignored");
++        return (0);
++    }
++    if (num_frames == 0)
++    {
++        png_warning(png_ptr,
++                    "Ignoring attempt to set acTL with num_frames zero");
++        return (0);
++    }
++    if (num_frames > PNG_UINT_31_MAX)
++    {
++        png_warning(png_ptr,
++                    "Ignoring attempt to set acTL with num_frames > 2^31-1");
++        return (0);
++    }
++    if (num_plays > PNG_UINT_31_MAX)
++    {
++        png_warning(png_ptr,
++                    "Ignoring attempt to set acTL with num_plays "
++                    "> 2^31-1");
++        return (0);
++    }
++
++    info_ptr->num_frames = num_frames;
++    info_ptr->num_plays = num_plays;
++
++    info_ptr->valid |= PNG_INFO_acTL;
++
++    return (1);
++}
++
++/* delay_num and delay_den can hold any 16-bit values including zero */
++png_uint_32 PNGAPI
++png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
++    png_uint_32 width, png_uint_32 height,
++    png_uint_32 x_offset, png_uint_32 y_offset,
++    png_uint_16 delay_num, png_uint_16 delay_den,
++    png_byte dispose_op, png_byte blend_op)
++{
++    png_debug1(1, "in %s storage function", "fcTL");
++
++    if (png_ptr == NULL || info_ptr == NULL)
++    {
++        png_warning(png_ptr,
++                    "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
++                    "ignored");
++        return (0);
++    }
++
++    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
++                             delay_num, delay_den, dispose_op, blend_op);
 +
- /* The following will work on (signed char*) strings, whereas the get_uint_32
-  * macro will fail on top-bit-set values because of the sign extension.
-  */
- #define PNG_CHUNK_FROM_STRING(s)\
-    PNG_CHUNK(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
-@@ -1344,16 +1358,55 @@ PNG_EXTERN void png_push_read_iTXt PNGAR
- 
- #ifdef PNG_MNG_FEATURES_SUPPORTED
- PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
-     png_bytep row));
- PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
-     png_bytep row));
- #endif
- 
-+#ifdef PNG_APNG_SUPPORTED
-+PNG_EXTERN void png_ensure_fcTL_is_valid PNGARG((png_structp png_ptr,
-+   png_uint_32 width, png_uint_32 height,
-+   png_uint_32 x_offset, png_uint_32 y_offset,
-+   png_uint_16 delay_num, png_uint_16 delay_den,
-+   png_byte dispose_op, png_byte blend_op));
++    if (blend_op == PNG_BLEND_OP_OVER)
++    {
++        if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
++            !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
++        {
++          png_warning(png_ptr, "PNG_BLEND_OP_OVER is meaningless "
++                               "and wasteful for opaque images, ignored");
++          blend_op = PNG_BLEND_OP_SOURCE;
++        }
++    }
++
++    info_ptr->next_frame_width = width;
++    info_ptr->next_frame_height = height;
++    info_ptr->next_frame_x_offset = x_offset;
++    info_ptr->next_frame_y_offset = y_offset;
++    info_ptr->next_frame_delay_num = delay_num;
++    info_ptr->next_frame_delay_den = delay_den;
++    info_ptr->next_frame_dispose_op = dispose_op;
++    info_ptr->next_frame_blend_op = blend_op;
++
++    info_ptr->valid |= PNG_INFO_fcTL;
++
++    return (1);
++}
 +
-+#ifdef PNG_READ_APNG_SUPPORTED
-+PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr,
-+   png_uint_32 length));
-+PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr,
-+   png_uint_32 length));
-+PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr,
-+   png_uint_32 length));
-+PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr));
-+PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr,
-+   png_uint_32 length));
-+PNG_EXTERN void png_read_reset PNGARG((png_structp png_ptr));
-+PNG_EXTERN void png_read_reinit PNGARG((png_structp png_ptr,
-+   png_infop info_ptr));
-+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-+PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr));
-+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-+#endif /* PNG_READ_APNG_SUPPORTED */
++void /* PRIVATE */
++png_ensure_fcTL_is_valid(png_structp png_ptr,
++    png_uint_32 width, png_uint_32 height,
++    png_uint_32 x_offset, png_uint_32 y_offset,
++    png_uint_16 delay_num, png_uint_16 delay_den,
++    png_byte dispose_op, png_byte blend_op)
++{
++    if (width > PNG_UINT_31_MAX)
++        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
++    if (height > PNG_UINT_31_MAX)
++        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
++    if (x_offset > PNG_UINT_31_MAX)
++        png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
++    if (y_offset > PNG_UINT_31_MAX)
++        png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
++    if (width + x_offset > png_ptr->first_frame_width ||
++        height + y_offset > png_ptr->first_frame_height)
++        png_error(png_ptr, "dimensions of a frame are greater than"
++                           "the ones in IHDR");
++
++    if (dispose_op != PNG_DISPOSE_OP_NONE &&
++        dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
++        dispose_op != PNG_DISPOSE_OP_PREVIOUS)
++        png_error(png_ptr, "invalid dispose_op in fcTL");
 +
-+#ifdef PNG_WRITE_APNG_SUPPORTED
-+PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
-+   png_uint_32 num_frames, png_uint_32 num_plays));
-+PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
-+   png_uint_32 width, png_uint_32 height,
-+   png_uint_32 x_offset, png_uint_32 y_offset,
-+   png_uint_16 delay_num, png_uint_16 delay_den,
-+   png_byte dispose_op, png_byte blend_op));
-+PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr));
-+PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr,
-+   png_infop info_ptr, png_uint_32 width, png_uint_32 height));
-+#endif /* PNG_WRITE_APNG_SUPPORTED */
++    if (blend_op != PNG_BLEND_OP_SOURCE &&
++        blend_op != PNG_BLEND_OP_OVER)
++        png_error(png_ptr, "invalid blend_op in fcTL");
++
++    PNG_UNUSED(delay_num)
++    PNG_UNUSED(delay_den)
++}
++
++png_uint_32 PNGAPI
++png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
++                              png_byte is_hidden)
++{
++    png_debug(1, "in png_first_frame_is_hidden()");
++
++    if (png_ptr == NULL)
++        return 0;
++
++    if (is_hidden)
++        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
++    else
++        png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
++
++    PNG_UNUSED(info_ptr)
++
++    return 1;
++}
 +#endif /* PNG_APNG_SUPPORTED */
 +
- /* Added at libpng version 1.4.0 */
- #ifdef PNG_CHECK_cHRM_SUPPORTED
- PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
-     png_fixed_point int_white_x, png_fixed_point int_white_y,
-     png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
-     int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
-     png_fixed_point int_blue_y));
- #endif
-diff --git libpng-1.5.16-orig/pngread.c libpng-1.5.16-sf/pngread.c
---- libpng-1.5.16-orig/pngread.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngread.c	2013-06-23 14:46:09.000000000 -0400
-@@ -235,16 +235,19 @@ png_read_info(png_structp png_ptr, png_i
-       {
-          if (!(png_ptr->mode & PNG_HAVE_IHDR))
-             png_error(png_ptr, "Missing IHDR before IDAT");
- 
-          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
-              !(png_ptr->mode & PNG_HAVE_PLTE))
-             png_error(png_ptr, "Missing PLTE before IDAT");
- 
-+#ifdef PNG_READ_APNG_SUPPORTED
-+         png_have_info(png_ptr, info_ptr);
-+#endif
-          png_ptr->idat_size = length;
-          png_ptr->mode |= PNG_HAVE_IDAT;
-          break;
-       }
- 
- #ifdef PNG_READ_bKGD_SUPPORTED
-       else if (chunk_name == png_bKGD)
-          png_handle_bKGD(png_ptr, info_ptr, length);
-@@ -325,22 +328,100 @@ png_read_info(png_structp png_ptr, png_i
-          png_handle_zTXt(png_ptr, info_ptr, length);
- #endif
- 
- #ifdef PNG_READ_iTXt_SUPPORTED
-       else if (chunk_name == png_iTXt)
-          png_handle_iTXt(png_ptr, info_ptr, length);
- #endif
- 
-+#ifdef PNG_READ_APNG_SUPPORTED
-+      else if (chunk_name == png_acTL)
-+         png_handle_acTL(png_ptr, info_ptr, length);
-+
-+      else if (chunk_name == png_fcTL)
-+         png_handle_fcTL(png_ptr, info_ptr, length);
-+
-+      else if (chunk_name == png_fdAT)
-+         png_handle_fdAT(png_ptr, info_ptr, length);
-+#endif
-+
-       else
-          png_handle_unknown(png_ptr, info_ptr, length);
-    }
- }
- #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
- 
-+#ifdef PNG_READ_APNG_SUPPORTED
-+void PNGAPI
-+png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
-+{
-+    png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
-+
-+    png_debug(0, "Reading frame head");
-+
-+    if (!(png_ptr->mode & PNG_HAVE_acTL))
-+        png_error(png_ptr, "attempt to png_read_frame_head() but "
-+                           "no acTL present");
-+
-+    /* do nothing for the main IDAT */
-+    if (png_ptr->num_frames_read == 0)
-+        return;
-+
-+    png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
-+
-+    png_read_reset(png_ptr);
-+    png_ptr->mode &= ~PNG_HAVE_fcTL;
-+
-+    have_chunk_after_DAT = 0;
-+    for (;;)
-+    {
-+        png_uint_32 length = png_read_chunk_header(png_ptr);
-+
-+        if (png_ptr->chunk_name == png_IDAT)
-+        {
-+            /* discard trailing IDATs for the first frame */
-+            if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
-+                png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
-+            png_crc_finish(png_ptr, length);
-+        }
-+
-+        else if (png_ptr->chunk_name == png_fcTL)
-+        {
-+            png_handle_fcTL(png_ptr, info_ptr, length);
-+            have_chunk_after_DAT = 1;
-+        }
-+
-+        else if (png_ptr->chunk_name == png_fdAT)
-+        {
-+            png_ensure_sequence_number(png_ptr, length);
-+
-+            /* discard trailing fdATs for frames other than the first */
-+            if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
-+                png_crc_finish(png_ptr, length - 4);
-+            else if(png_ptr->mode & PNG_HAVE_fcTL)
-+            {
-+                png_ptr->idat_size = length - 4;
-+                png_ptr->mode |= PNG_HAVE_IDAT;
-+
-+                break;
-+            }
-+            else
-+                png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
-+        }
-+        else
-+        {
-+            png_warning(png_ptr, "Skipped (ignored) a chunk "
-+                                 "between APNG chunks");
-+            png_crc_finish(png_ptr, length);
-+        }
-+    }
-+}
-+#endif /* PNG_READ_APNG_SUPPORTED */
-+
- /* Optional call to update the users info_ptr structure */
+ #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
  void PNGAPI
- png_read_update_info(png_structp png_ptr, png_infop info_ptr)
- {
-    png_debug(1, "in png_read_update_info");
- 
-    if (png_ptr == NULL)
-       return;
-@@ -532,24 +613,57 @@ png_read_row(png_structp png_ptr, png_by
-    png_ptr->zstream.avail_out =
-        (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
-        png_ptr->iwidth) + 1);
- 
-    do
-    {
-       if (!(png_ptr->zstream.avail_in))
-       {
-+#ifdef PNG_READ_APNG_SUPPORTED
-+         png_uint_32 bytes_to_skip = 0;
-+
-+         while (!png_ptr->idat_size || bytes_to_skip != 0)
-+         {
-+            png_crc_finish(png_ptr, bytes_to_skip);
-+            bytes_to_skip = 0;
-+
-+            png_ptr->idat_size = png_read_chunk_header(png_ptr);
-+            if (png_ptr->num_frames_read == 0)
-+            {
-+               if (png_ptr->chunk_name != png_IDAT)
-+                  png_error(png_ptr, "Not enough image data");
-+            }
-+            else
-+            {
-+               if (png_ptr->chunk_name == png_IEND)
-+                  png_error(png_ptr, "Not enough image data");
-+               if (png_ptr->chunk_name != png_fdAT)
-+               {
-+                  png_warning(png_ptr, "Skipped (ignored) a chunk "
-+                                       "between APNG chunks");
-+                  bytes_to_skip = png_ptr->idat_size;
-+                  continue;
-+               }
-+
-+               png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
-+
-+               png_ptr->idat_size -= 4;
-+            }
-+         }
-+#else
-          while (!png_ptr->idat_size)
-          {
-             png_crc_finish(png_ptr, 0);
- 
-             png_ptr->idat_size = png_read_chunk_header(png_ptr);
-             if (png_ptr->chunk_name != png_IDAT)
-                png_error(png_ptr, "Not enough image data");
-          }
-+#endif
-          png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
-          png_ptr->zstream.next_in = png_ptr->zbuf;
-          if (png_ptr->zbuf_size > png_ptr->idat_size)
-             png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
-          png_crc_read(png_ptr, png_ptr->zbuf,
-              (png_size_t)png_ptr->zstream.avail_in);
-          png_ptr->idat_size -= png_ptr->zstream.avail_in;
-       }
-@@ -558,16 +672,19 @@ png_read_row(png_structp png_ptr, png_by
- 
-       if (ret == Z_STREAM_END)
-       {
-          if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
-             png_ptr->idat_size)
-             png_benign_error(png_ptr, "Extra compressed data");
-          png_ptr->mode |= PNG_AFTER_IDAT;
-          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-+#ifdef PNG_READ_APNG_SUPPORTED
-+         png_ptr->num_frames_read++;
-+#endif
-          break;
-       }
- 
-       if (ret != Z_OK)
-          png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
-              "Decompression error");
- 
-    } while (png_ptr->zstream.avail_out);
-diff --git libpng-1.5.16-orig/pngrutil.c libpng-1.5.16-sf/pngrutil.c
---- libpng-1.5.16-orig/pngrutil.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngrutil.c	2013-06-23 14:46:09.000000000 -0400
-@@ -540,16 +540,21 @@ png_handle_IHDR(png_structp png_ptr, png
-    width = png_get_uint_31(png_ptr, buf);
-    height = png_get_uint_31(png_ptr, buf + 4);
-    bit_depth = buf[8];
-    color_type = buf[9];
-    compression_type = buf[10];
+ png_set_unknown_chunks(png_structp png_ptr,
+Index: pngrutil.c
+===================================================================
+--- pngrutil.c
++++ pngrutil.c
+@@ -545,6 +545,11 @@
     filter_type = buf[11];
     interlace_type = buf[12];
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +   png_ptr->first_frame_width = width;
 +   png_ptr->first_frame_height = height;
 +#endif
 +
     /* Set internal variables */
     png_ptr->width = width;
     png_ptr->height = height;
-    png_ptr->bit_depth = (png_byte)bit_depth;
-    png_ptr->interlaced = (png_byte)interlace_type;
-    png_ptr->color_type = (png_byte)color_type;
- #ifdef PNG_MNG_FEATURES_SUPPORTED
-    png_ptr->filter_type = (png_byte)filter_type;
-@@ -2617,16 +2622,189 @@ png_handle_iTXt(png_structp png_ptr, png
-    png_free(png_ptr, png_ptr->chunkdata);
-    png_ptr->chunkdata = NULL;
- 
-    if (ret)
-       png_error(png_ptr, "Insufficient memory to store iTXt chunk");
+@@ -2622,6 +2627,179 @@
  }
  #endif
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +void /* PRIVATE */
 +png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 +{
 +    png_byte data[8];
@@ -1238,43 +1299,32 @@ diff --git libpng-1.5.16-orig/pngrutil.c
 +
 +    png_ptr->next_seq_num++;
 +}
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
  /* This function is called when we haven't found a handler for a
   * chunk.  If there isn't a problem with the chunk itself (ie bad
   * chunk name, CRC, or a critical chunk), the chunk is silently ignored
-  * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
-  * case it will be saved away to be written out later.
-  */
- void /* PRIVATE */
- png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
-@@ -4107,9 +4285,86 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED
-    png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
-    png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
-    png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
-    png_debug1(3, "irowbytes = %lu",
-        (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
+@@ -4112,4 +4290,80 @@
  
     png_ptr->flags |= PNG_FLAG_ROW_INIT;
  }
 +
 +#ifdef PNG_READ_APNG_SUPPORTED
 +/* This function is to be called after the main IDAT set has been read and
 + * before a new IDAT is read. It resets some parts of png_ptr
 + * to make them usable by the read functions again */
 +void /* PRIVATE */
 +png_read_reset(png_structp png_ptr)
 +{
 +    png_ptr->mode &= ~PNG_HAVE_IDAT;
 +    png_ptr->mode &= ~PNG_AFTER_IDAT;
 +    png_ptr->row_number = 0;
 +    png_ptr->pass = 0;
-+    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 +}
 +
 +void /* PRIVATE */
 +png_read_reinit(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_ptr->width = info_ptr->next_frame_width;
 +    png_ptr->height = info_ptr->next_frame_height;
 +    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
@@ -1330,559 +1380,62 @@ diff --git libpng-1.5.16-orig/pngrutil.c
 +    png_ptr->zstream.next_in = 0;
 +    png_ptr->zstream.next_out = png_ptr->row_buf;
 +    png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
 +        png_ptr->iwidth) + 1;
 +}
 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 +#endif /* PNG_READ_APNG_SUPPORTED */
  #endif /* PNG_READ_SUPPORTED */
-diff --git libpng-1.5.16-orig/pngset.c libpng-1.5.16-sf/pngset.c
---- libpng-1.5.16-orig/pngset.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngset.c	2013-06-23 14:46:09.000000000 -0400
-@@ -257,16 +257,21 @@ png_set_IHDR(png_structp png_ptr, png_in
-        (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
-        - 48       /* bigrowbuf hack */
-        - 1        /* filter byte */
-        - 7*8      /* rounding of width to multiple of 8 pixels */
-        - 8)       /* extra max_pixel_depth pad */
-       info_ptr->rowbytes = 0;
-    else
-       info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
-+
-+#ifdef PNG_APNG_SUPPORTED
-+   /* for non-animated png. this may be overwritten from an acTL chunk later */
-+   info_ptr->num_frames = 1;
-+#endif
- }
- 
- #ifdef PNG_oFFs_SUPPORTED
- void PNGAPI
- png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
-     png_int_32 offset_x, png_int_32 offset_y, int unit_type)
- {
-    png_debug1(1, "in %s storage function", "oFFs");
-@@ -1043,16 +1048,157 @@ png_set_sPLT(png_structp png_ptr,
- 
-    info_ptr->splt_palettes = np;
-    info_ptr->splt_palettes_num += nentries;
-    info_ptr->valid |= PNG_INFO_sPLT;
-    info_ptr->free_me |= PNG_FREE_SPLT;
- }
- #endif /* PNG_sPLT_SUPPORTED */
- 
-+#ifdef PNG_APNG_SUPPORTED
-+png_uint_32 PNGAPI
-+png_set_acTL(png_structp png_ptr, png_infop info_ptr,
-+    png_uint_32 num_frames, png_uint_32 num_plays)
-+{
-+    png_debug1(1, "in %s storage function", "acTL");
-+
-+    if (png_ptr == NULL || info_ptr == NULL)
-+    {
-+        png_warning(png_ptr,
-+                    "Call to png_set_acTL() with NULL png_ptr "
-+                    "or info_ptr ignored");
-+        return (0);
-+    }
-+    if (num_frames == 0)
-+    {
-+        png_warning(png_ptr,
-+                    "Ignoring attempt to set acTL with num_frames zero");
-+        return (0);
-+    }
-+    if (num_frames > PNG_UINT_31_MAX)
-+    {
-+        png_warning(png_ptr,
-+                    "Ignoring attempt to set acTL with num_frames > 2^31-1");
-+        return (0);
-+    }
-+    if (num_plays > PNG_UINT_31_MAX)
-+    {
-+        png_warning(png_ptr,
-+                    "Ignoring attempt to set acTL with num_plays "
-+                    "> 2^31-1");
-+        return (0);
-+    }
-+
-+    info_ptr->num_frames = num_frames;
-+    info_ptr->num_plays = num_plays;
-+
-+    info_ptr->valid |= PNG_INFO_acTL;
-+
-+    return (1);
-+}
-+
-+/* delay_num and delay_den can hold any 16-bit values including zero */
-+png_uint_32 PNGAPI
-+png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
-+    png_uint_32 width, png_uint_32 height,
-+    png_uint_32 x_offset, png_uint_32 y_offset,
-+    png_uint_16 delay_num, png_uint_16 delay_den,
-+    png_byte dispose_op, png_byte blend_op)
-+{
-+    png_debug1(1, "in %s storage function", "fcTL");
-+
-+    if (png_ptr == NULL || info_ptr == NULL)
-+    {
-+        png_warning(png_ptr,
-+                    "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
-+                    "ignored");
-+        return (0);
-+    }
-+
-+    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
-+                             delay_num, delay_den, dispose_op, blend_op);
-+
-+    if (blend_op == PNG_BLEND_OP_OVER)
-+    {
-+        if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
-+            !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
-+        {
-+          png_warning(png_ptr, "PNG_BLEND_OP_OVER is meaningless "
-+                               "and wasteful for opaque images, ignored");
-+          blend_op = PNG_BLEND_OP_SOURCE;
-+        }
-+    }
-+
-+    info_ptr->next_frame_width = width;
-+    info_ptr->next_frame_height = height;
-+    info_ptr->next_frame_x_offset = x_offset;
-+    info_ptr->next_frame_y_offset = y_offset;
-+    info_ptr->next_frame_delay_num = delay_num;
-+    info_ptr->next_frame_delay_den = delay_den;
-+    info_ptr->next_frame_dispose_op = dispose_op;
-+    info_ptr->next_frame_blend_op = blend_op;
-+
-+    info_ptr->valid |= PNG_INFO_fcTL;
-+
-+    return (1);
-+}
-+
-+void /* PRIVATE */
-+png_ensure_fcTL_is_valid(png_structp png_ptr,
-+    png_uint_32 width, png_uint_32 height,
-+    png_uint_32 x_offset, png_uint_32 y_offset,
-+    png_uint_16 delay_num, png_uint_16 delay_den,
-+    png_byte dispose_op, png_byte blend_op)
-+{
-+    if (width + x_offset > png_ptr->first_frame_width ||
-+        height + y_offset > png_ptr->first_frame_height)
-+        png_error(png_ptr, "dimensions of a frame are greater than"
-+                           "the ones in IHDR");
-+    if (width > PNG_UINT_31_MAX)
-+        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
-+    if (height > PNG_UINT_31_MAX)
-+        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
-+    if (x_offset > PNG_UINT_31_MAX)
-+        png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
-+    if (y_offset > PNG_UINT_31_MAX)
-+        png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
-+
-+    if (dispose_op != PNG_DISPOSE_OP_NONE &&
-+        dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
-+        dispose_op != PNG_DISPOSE_OP_PREVIOUS)
-+        png_error(png_ptr, "invalid dispose_op in fcTL");
-+
-+    if (blend_op != PNG_BLEND_OP_SOURCE &&
-+        blend_op != PNG_BLEND_OP_OVER)
-+        png_error(png_ptr, "invalid blend_op in fcTL");
-+
-+    PNG_UNUSED(delay_num)
-+    PNG_UNUSED(delay_den)
-+}
-+
-+png_uint_32 PNGAPI
-+png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
-+                              png_byte is_hidden)
-+{
-+    png_debug(1, "in png_first_frame_is_hidden()");
-+
-+    if (png_ptr == NULL)
-+        return 0;
-+
-+    if (is_hidden)
-+        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
-+    else
-+        png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
-+
-+    PNG_UNUSED(info_ptr)
-+
-+    return 1;
-+}
-+#endif /* PNG_APNG_SUPPORTED */
-+
- #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
- void PNGAPI
- png_set_unknown_chunks(png_structp png_ptr,
-    png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
- {
-    png_unknown_chunkp np;
-    int i;
- 
-diff --git libpng-1.5.16-orig/pngstruct.h libpng-1.5.16-sf/pngstruct.h
---- libpng-1.5.16-orig/pngstruct.h	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngstruct.h	2013-06-23 14:46:09.000000000 -0400
-@@ -288,16 +288,37 @@ struct png_struct_def
-    png_uint_32 mng_features_permitted;
- #endif
- 
- /* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
- #ifdef PNG_MNG_FEATURES_SUPPORTED
-    png_byte filter_type;
- #endif
- 
-+#ifdef PNG_APNG_SUPPORTED
-+   png_uint_32 apng_flags;
-+   png_uint_32 next_seq_num;         /* next fcTL/fdAT chunk sequence number */
-+   png_uint_32 first_frame_width;
-+   png_uint_32 first_frame_height;
-+
-+#ifdef PNG_READ_APNG_SUPPORTED
-+   png_uint_32 num_frames_read;      /* incremented after all image data of */
-+                                     /* a frame is read */
-+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-+   png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
-+   png_progressive_frame_ptr frame_end_fn;  /* frame data read callback */
-+#endif
-+#endif
-+
-+#ifdef PNG_WRITE_APNG_SUPPORTED
-+   png_uint_32 num_frames_to_write;
-+   png_uint_32 num_frames_written;
-+#endif
-+#endif /* PNG_APNG_SUPPORTED */
-+
- /* New members added in libpng-1.2.0 */
- 
- /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
- #ifdef PNG_USER_MEM_SUPPORTED
-    png_voidp mem_ptr;             /* user supplied struct for mem functions */
-    png_malloc_ptr malloc_fn;      /* function for allocating memory */
-    png_free_ptr free_fn;          /* function for freeing memory */
- #endif
-diff --git libpng-1.5.16-orig/pngtest.c libpng-1.5.16-sf/pngtest.c
---- libpng-1.5.16-orig/pngtest.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngtest.c	2013-06-23 14:46:09.000000000 -0400
-@@ -830,16 +830,20 @@ test_one_file(PNG_CONST char *inname, PN
-    png_infop write_info_ptr = NULL;
-    png_infop write_end_info_ptr = NULL;
- #endif
-    png_bytep row_buf;
-    png_uint_32 y;
-    png_uint_32 width, height;
-    int num_pass, pass;
-    int bit_depth, color_type;
-+#ifdef PNG_APNG_SUPPORTED
-+   png_uint_32 num_frames;
-+   png_uint_32 num_plays;
-+#endif
- 
-    row_buf = NULL;
-    error_parameters.file_name = inname;
- 
-    if ((fpin = fopen(inname, "rb")) == NULL)
-    {
-       fprintf(STDERR, "Could not find input file %s\n", inname);
-       return (1);
-@@ -1279,16 +1283,30 @@ test_one_file(PNG_CONST char *inname, PN
-              ((int)trans_color->red > sample_max ||
-              (int)trans_color->green > sample_max ||
-              (int)trans_color->blue > sample_max))))
-             png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans,
-                trans_color);
-       }
-    }
- #endif
-+#ifdef PNG_APNG_SUPPORTED
-+   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
-+   {
-+      if (png_get_acTL(read_ptr, read_info_ptr, &num_frames, &num_plays))
-+      {
-+         png_byte is_hidden;
-+         pngtest_debug2("Handling acTL chunks (frames %ld, plays %ld)",
-+                    num_frames, num_plays);
-+         png_set_acTL(write_ptr, write_info_ptr, num_frames, num_plays);
-+         is_hidden = png_get_first_frame_is_hidden(read_ptr, read_info_ptr);
-+         png_set_first_frame_is_hidden(write_ptr, write_info_ptr, is_hidden);
-+      }
-+   }
-+#endif
- #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
-    {
-       png_unknown_chunkp unknowns;
-       int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
-          &unknowns);
- 
-       if (num_unknowns)
-       {
-@@ -1344,16 +1362,99 @@ test_one_file(PNG_CONST char *inname, PN
-    num_pass = 1;
- #endif
- 
- #ifdef PNGTEST_TIMING
-    t_stop = (float)clock();
-    t_misc += (t_stop - t_start);
-    t_start = t_stop;
- #endif
-+#ifdef PNG_APNG_SUPPORTED
-+   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
-+   {
-+      png_uint_32 frame;
-+      for (frame = 0; frame < num_frames; frame++)
-+      {
-+         png_uint_32 frame_width;
-+         png_uint_32 frame_height;
-+         png_uint_32 x_offset;
-+         png_uint_32 y_offset;
-+         png_uint_16 delay_num;
-+         png_uint_16 delay_den;
-+         png_byte dispose_op;
-+         png_byte blend_op;
-+         png_read_frame_head(read_ptr, read_info_ptr);
-+         if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_fcTL))
-+         {
-+            png_get_next_frame_fcTL(read_ptr, read_info_ptr,
-+                                    &frame_width, &frame_height,
-+                                    &x_offset, &y_offset,
-+                                    &delay_num, &delay_den,
-+                                    &dispose_op, &blend_op);
-+         }
-+         else
-+         {
-+            frame_width = width;
-+            frame_height = height;
-+            x_offset = 0;
-+            y_offset = 0;
-+            delay_num = 1;
-+            delay_den = 1;
-+            dispose_op = PNG_DISPOSE_OP_NONE;
-+            blend_op = PNG_BLEND_OP_SOURCE;
-+         }
-+#ifdef PNG_WRITE_APNG_SUPPORTED
-+         png_write_frame_head(write_ptr, write_info_ptr, (png_bytepp)&row_buf,
-+                              frame_width, frame_height,
-+                              x_offset, y_offset,
-+                              delay_num, delay_den,
-+                              dispose_op, blend_op);
-+#endif
-+         for (pass = 0; pass < num_pass; pass++)
-+         {
-+            pngtest_debug1("Writing row data for pass %d", pass);
-+            for (y = 0; y < frame_height; y++)
-+            {
-+#ifndef SINGLE_ROWBUF_ALLOC
-+               pngtest_debug2("Allocating row buffer (pass %d, y = %ld)...", pass, y);
-+               row_buf = (png_bytep)png_malloc(read_ptr,
-+                  png_get_rowbytes(read_ptr, read_info_ptr));
-+               pngtest_debug2("0x%08lx (%ld bytes)", (unsigned long)row_buf,
-+                  png_get_rowbytes(read_ptr, read_info_ptr));
-+#endif /* !SINGLE_ROWBUF_ALLOC */
-+               png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
-+
-+#ifdef PNG_WRITE_SUPPORTED
-+#ifdef PNGTEST_TIMING
-+               t_stop = (float)clock();
-+               t_decode += (t_stop - t_start);
-+               t_start = t_stop;
-+#endif
-+               png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
-+#ifdef PNGTEST_TIMING
-+               t_stop = (float)clock();
-+               t_encode += (t_stop - t_start);
-+               t_start = t_stop;
-+#endif
-+#endif /* PNG_WRITE_SUPPORTED */
-+
-+#ifndef SINGLE_ROWBUF_ALLOC
-+               pngtest_debug2("Freeing row buffer (pass %d, y = %ld)", pass, y);
-+               png_free(read_ptr, row_buf);
-+               row_buf = NULL;
-+#endif /* !SINGLE_ROWBUF_ALLOC */
-+            }
-+         }
-+#ifdef PNG_WRITE_APNG_SUPPORTED
-+         png_write_frame_tail(write_ptr, write_info_ptr);
-+#endif
-+      }
-+   }
-+   else
-+#endif
-    for (pass = 0; pass < num_pass; pass++)
-    {
-       pngtest_debug1("Writing row data for pass %d", pass);
-       for (y = 0; y < height; y++)
-       {
- #ifndef SINGLE_ROWBUF_ALLOC
-          pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
-          row_buf = (png_bytep)png_malloc(read_ptr,
-diff --git libpng-1.5.16-orig/pngwrite.c libpng-1.5.16-sf/pngwrite.c
---- libpng-1.5.16-orig/pngwrite.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngwrite.c	2013-06-23 14:46:09.000000000 -0400
-@@ -53,16 +53,20 @@ png_write_info_before_PLTE(png_structp p
- #ifdef PNG_WRITE_INTERLACING_SUPPORTED
-        info_ptr->interlace_type);
- #else
-        0);
- #endif
-    /* The rest of these check to see if the valid field has the appropriate
-     * flag set, and if it does, writes the chunk.
-     */
-+#ifdef PNG_WRITE_APNG_SUPPORTED
-+   if (info_ptr->valid & PNG_INFO_acTL)
-+      png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
-+#endif
- #ifdef PNG_WRITE_gAMA_SUPPORTED
-    if (info_ptr->valid & PNG_INFO_gAMA)
-       png_write_gAMA_fixed(png_ptr, info_ptr->gamma);
- #endif
- #ifdef PNG_WRITE_sRGB_SUPPORTED
-    if (info_ptr->valid & PNG_INFO_sRGB)
-       png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
- #endif
-@@ -305,16 +309,21 @@ png_write_end(png_structp png_ptr, png_i
-    if (!(png_ptr->mode & PNG_HAVE_IDAT))
-       png_error(png_ptr, "No IDATs written into file");
- 
- #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
-    if (png_ptr->num_palette_max > png_ptr->num_palette)
-       png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
- #endif
- 
-+#ifdef PNG_WRITE_APNG_SUPPORTED
-+   if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
-+      png_error(png_ptr, "Not enough frames written");
-+#endif
-+
-    /* See if user wants us to write information chunks */
-    if (info_ptr != NULL)
-    {
- #ifdef PNG_WRITE_TEXT_SUPPORTED
-       int i; /* local index variable */
- #endif
- #ifdef PNG_WRITE_tIME_SUPPORTED
-       /* Check to see if user has supplied a time chunk */
-@@ -1662,9 +1671,47 @@ png_write_png(png_structp png_ptr, png_i
- 
-    /* It is REQUIRED to call this to finish writing the rest of the file */
-    png_write_end(png_ptr, info_ptr);
- 
-    PNG_UNUSED(transforms)   /* Quiet compiler warnings */
-    PNG_UNUSED(params)
- }
- #endif
-+
-+#ifdef PNG_WRITE_APNG_SUPPORTED
-+void PNGAPI
-+png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
-+    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
-+    png_uint_32 x_offset, png_uint_32 y_offset,
-+    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
-+    png_byte blend_op)
-+{
-+    png_debug(1, "in png_write_frame_head");
-+
-+    /* there is a chance this has been set after png_write_info was called,
-+    * so it would be set but not written. is there a way to be sure? */
-+    if (!(info_ptr->valid & PNG_INFO_acTL))
-+        png_error(png_ptr, "png_write_frame_head(): acTL not set");
-+
-+    png_write_reset(png_ptr);
-+
-+    png_write_reinit(png_ptr, info_ptr, width, height);
-+
-+    if ( !(png_ptr->num_frames_written == 0 &&
-+           (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
-+        png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
-+                       delay_num, delay_den, dispose_op, blend_op);
-+
-+    PNG_UNUSED(row_pointers)
-+}
-+
-+void PNGAPI
-+png_write_frame_tail(png_structp png_ptr, png_infop info_ptr)
-+{
-+    png_debug(1, "in png_write_frame_tail");
-+
-+    png_ptr->num_frames_written++;
-+
-+    PNG_UNUSED(info_ptr)
-+}
-+#endif /* PNG_WRITE_APNG_SUPPORTED */
- #endif /* PNG_WRITE_SUPPORTED */
-diff --git libpng-1.5.16-orig/pngwutil.c libpng-1.5.16-sf/pngwutil.c
---- libpng-1.5.16-orig/pngwutil.c	2013-05-23 07:45:22.000000000 -0400
-+++ libpng-1.5.16-sf/pngwutil.c	2013-06-23 14:46:09.000000000 -0400
-@@ -813,16 +813,21 @@ png_write_IHDR(png_structp png_ptr, png_
-    buf[9] = (png_byte)color_type;
-    buf[10] = (png_byte)compression_type;
-    buf[11] = (png_byte)filter_type;
-    buf[12] = (png_byte)interlace_type;
- 
+Index: pngwutil.c
+===================================================================
+--- pngwutil.c
++++ pngwutil.c
+@@ -818,6 +818,11 @@
     /* Write the chunk */
     png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
  
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +   png_ptr->first_frame_width = width;
 +   png_ptr->first_frame_height = height;
 +#endif
 +
     /* Initialize zlib with PNG info */
     png_ptr->zstream.zalloc = png_zalloc;
     png_ptr->zstream.zfree = png_zfree;
-    png_ptr->zstream.opaque = (voidpf)png_ptr;
- 
-    if (!(png_ptr->do_filter))
-    {
-       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
-@@ -1027,17 +1032,38 @@ png_write_IDAT(png_structp png_ptr, png_
-       }
- 
-       else
-          png_error(png_ptr,
-              "Invalid zlib compression method or flags in IDAT");
+@@ -1032,7 +1037,28 @@
     }
  #endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
  
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +   if (png_ptr->num_frames_written == 0)
 +#endif
     png_write_complete_chunk(png_ptr, png_IDAT, data, length);
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +   else
 +   {
 +      png_byte buf[4];
 +
-+      png_write_chunk_header(png_ptr, png_fdAT, 4 + length);
++      png_write_chunk_header(png_ptr, png_fdAT, (png_uint_32)(4 + length));
 +
 +      png_save_uint_32(buf, png_ptr->next_seq_num);
 +      png_write_chunk_data(png_ptr, buf, 4);
 +
 +      png_write_chunk_data(png_ptr, data, length);
 +
 +      png_write_chunk_end(png_ptr);
 +
 +      png_ptr->next_seq_num++;
 +   }
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +
     png_ptr->mode |= PNG_HAVE_IDAT;
  
     /* Prior to 1.5.4 this code was replicated in every caller (except at the
-     * end, where it isn't technically necessary).  Since this function has
-     * flushed the data we can safely reset the zlib output buffer here.
-     */
-    png_ptr->zstream.next_out = png_ptr->zbuf;
-    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-@@ -1990,16 +2016,74 @@ png_write_tIME(png_structp png_ptr, png_
-    buf[4] = mod_time->hour;
-    buf[5] = mod_time->minute;
-    buf[6] = mod_time->second;
- 
-    png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+@@ -1995,6 +2021,64 @@
  }
  #endif
  
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +void /* PRIVATE */
 +png_write_acTL(png_structp png_ptr,
 +    png_uint_32 num_frames, png_uint_32 num_plays)
 +{
@@ -1937,27 +1490,17 @@ diff --git libpng-1.5.16-orig/pngwutil.c
 +
 +    png_ptr->next_seq_num++;
 +}
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +
  /* Initializes the row writing capability of libpng */
  void /* PRIVATE */
  png_write_start_row(png_structp png_ptr)
- {
- #ifdef PNG_WRITE_INTERLACING_SUPPORTED
-    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
- 
-    /* Start of interlace block */
-@@ -3169,9 +3253,44 @@ png_write_filtered_row(png_structp png_p
- 
-    if (png_ptr->flush_dist > 0 &&
-        png_ptr->flush_rows >= png_ptr->flush_dist)
-    {
-       png_write_flush(png_ptr);
+@@ -3174,4 +3258,39 @@
     }
  #endif
  }
 +
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +void /* PRIVATE */
 +png_write_reset(png_structp png_ptr)
 +{
@@ -1987,25 +1530,21 @@ diff --git libpng-1.5.16-orig/pngwutil.c
 +
 +    png_ptr->width = width;
 +    png_ptr->height = height;
 +    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
 +    png_ptr->usr_width = png_ptr->width;
 +}
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
  #endif /* PNG_WRITE_SUPPORTED */
-diff --git libpng-1.5.16-orig/scripts/symbols.def libpng-1.5.16-sf/scripts/symbols.def
---- libpng-1.5.16-orig/scripts/symbols.def	2013-05-23 07:45:23.000000000 -0400
-+++ libpng-1.5.16-sf/scripts/symbols.def	2013-06-23 14:46:09.000000000 -0400
-@@ -237,8 +237,28 @@ EXPORTS
-  png_set_scale_16 @229
-  png_get_cHRM_XYZ @230
-  png_get_cHRM_XYZ_fixed @231
-  png_set_cHRM_XYZ @232
-  png_set_cHRM_XYZ_fixed @233
+Index: scripts/symbols.def
+===================================================================
+--- scripts/symbols.def
++++ scripts/symbols.def
+@@ -242,3 +242,23 @@
   png_set_check_for_invalid_index @234
   png_get_palette_max @235
   png_set_option @236
 + png_get_acTL @237
 + png_set_acTL @238
 + png_get_num_frames @239
 + png_get_num_plays @240
 + png_get_next_frame_fcTL @241
--- a/media/libpng/arm/arm_init.c
+++ b/media/libpng/arm/arm_init.c
@@ -1,27 +1,27 @@
 
 /* arm_init.c - NEON optimised filter functions
  *
  * Copyright (c) 2013 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.5.16 [May 23, 2013]
+ * Last changed in libpng 1.5.17 [June 27, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 /* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
  * called.
  */
 #define _POSIX_SOURCE 1
 
 #include "../pngpriv.h"
 
-#ifdef PNG_ARM_NEON_SUPPORTED
+#if PNG_ARM_NEON_OPT > 0
 #ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */
 #include <signal.h> /* for sig_atomic_t */
 
 #ifdef __ANDROID__
 /* Linux provides access to information about CPU capabilites via
  * /proc/self/auxv, however Android blocks this while still claiming to be
  * Linux.  The Andoid NDK, however, provides appropriate support.
  *
@@ -211,9 +211,9 @@ png_init_filter_functions_neon(png_struc
    else if (bpp == 4)
    {
       pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
       pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
       pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
           png_read_filter_row_paeth4_neon;
    }
 }
-#endif /* PNG_ARM_NEON_SUPPORTED */
+#endif /* PNG_ARM_NEON_OPT > 0 */
--- a/media/libpng/arm/filter_neon.S
+++ b/media/libpng/arm/filter_neon.S
@@ -1,31 +1,31 @@
 
 /* filter_neon.S - NEON optimised filter functions
  *
  * Copyright (c) 2013 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.5.16 [May 23, 2013]
+ * Last changed in libpng 1.5.17 [June 27, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 /* This is required to get the symbol renames, which are #defines, and also
- * includes the definition (or not) of PNG_ARM_NEON_SUPPORTED.
+ * includes the definition (or not) of PNG_ARM_NEON_OPT.
  */
 #define PNG_VERSION_INFO_ONLY
 #include "../pngpriv.h"
 
 #if defined(__linux__) && defined(__ELF__)
 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
 #endif
 
-#ifdef PNG_ARM_NEON_SUPPORTED
+#if PNG_ARM_NEON_OPT > 0
 
 #ifdef __ELF__
 #   define ELF
 #else
 #   define ELF @
 #endif
 
         .arch armv7-a
@@ -227,9 +227,9 @@ 1:
         vmov            d4,  d19
         vadd.u8         d3,  d3,  d7
         vst1.32         {d3[0]},  [r1], r4
         subs            r12, r12, #12
         bgt             1b
 
         pop             {r4,pc}
 endfunc
-#endif /* PNG_ARM_NEON_SUPPORTED */
+#endif /* PNG_ARM_NEON_OPT > 0 */
--- a/media/libpng/png.c
+++ b/media/libpng/png.c
@@ -9,17 +9,17 @@
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_5_16 Your_png_h_is_not_version_1_5_16;
+typedef png_libpng_version_1_5_17 Your_png_h_is_not_version_1_5_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
  * stream we can set num_bytes = 8 so that libpng will not attempt to read
  * or write any of the magic bytes before it starts on the IHDR.
  */
 
 #ifdef PNG_READ_SUPPORTED
@@ -653,23 +653,23 @@ png_const_charp PNGAPI
 png_get_copyright(png_const_structp png_ptr)
 {
    PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
 #ifdef PNG_STRING_COPYRIGHT
    return PNG_STRING_COPYRIGHT
 #else
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-     "libpng version 1.5.16 - May 23, 2013" PNG_STRING_NEWLINE \
+     "libpng version 1.5.17 - June 27, 2013" PNG_STRING_NEWLINE \
      "Copyright (c) 1998-2013 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.5.16 - May 23, 2013\
+      return "libpng version 1.5.17 - June 27, 2013\
       Copyright (c) 1998-2013 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
 #  endif
 #endif
 }
 
 /* The following return the library version as a short string in the
--- a/media/libpng/png.h
+++ b/media/libpng/png.h
@@ -1,22 +1,22 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.5.16 - May 23, 2013
+ * libpng version 1.5.17 - June 27, 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.)
  *
  * This code is released under the libpng license (See LICENSE, below)
  *
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.5.16 - May 23, 2013: Glenn
+ *   libpng versions 0.97, January 1998, through 1.5.17 - June 27, 2013: Glenn
  *   See also "Contributing Authors", below.
  *
  * Note about libpng version numbers:
  *
  *   Due to various miscommunications, unforeseen code incompatibilities
  *   and occasional factors outside the authors' control, version numbering
  *   on the library has not always been consistent and straightforward.
  *   The following table summarizes matters since version 0.89c, which was
@@ -185,16 +185,19 @@
  *    1.5.14rc01-03           15    10514  15.so.15.14[.0]
  *    1.5.14                  15    10514  15.so.15.14[.0]
  *    1.5.15beta01-09         15    10515  15.so.15.15[.0]
  *    1.5.15rc01              15    10515  15.so.15.15[.0]
  *    1.5.15                  15    10515  15.so.15.15[.0]
  *    1.5.16beta01-06         15    10516  15.so.15.16[.0]
  *    1.5.16rc01              15    10516  15.so.15.16[.0]
  *    1.5.16                  15    10516  15.so.15.16[.0]
+ *    1.5.17beta01            15    10517  15.so.15.17[.0]
+ *    1.5.17rc01-03           15    10517  15.so.15.17[.0]
+ *    1.5.17                  15    10517  15.so.15.17[.0]
  *
  *   Henceforth the source version will match the shared-library major
  *   and minor numbers; the shared-library major version number will be
  *   used for changes in backward compatibility, as it is intended.  The
  *   PNG_LIBPNG_VER macro, which is not used within libpng but is available
  *   for applications, is an unsigned integer of the form xyyzz corresponding
  *   to the source version x.y.z (leading zeros in y and z).  Beta versions
  *   were given the previous public release number plus a letter, until
@@ -216,17 +219,17 @@
 /*
  * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
  *
  * If you modify libpng you may insert additional notices immediately following
  * this sentence.
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.2.6, August 15, 2004, through 1.5.16, May 23, 2013, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.5.17, June 27, 2013, are
  * Copyright (c) 2004, 2006-2013 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:
  *
  *    Cosmin Truta
  *
  * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
  * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
@@ -328,23 +331,23 @@
  *
  * Thanks to Frank J. T. Wojcik for helping with the documentation.
  */
 
 /*
  * Y2K compliance in libpng:
  * =========================
  *
- *    May 23, 2013
+ *    June 27, 2013
  *
  *    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.5.16 are Y2K compliant.  It is my belief that
+ *    upward through 1.5.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
  *    that will hold years up to 65535.  The other holds the date in text
  *    format, and will hold years up to 9999.
  *
  *    The integer is
  *        "png_uint_16 year" in png_time_struct.
@@ -393,27 +396,27 @@
  * with some code on which to build.  This file is useful for looking
  * at the actual function definitions and structure components.
  *
  * If you just need to read a PNG file and don't want to read the documentation
  * skip to the end of this file and read the section entitled 'simplified API'.
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.5.16"
+#define PNG_LIBPNG_VER_STRING "1.5.17"
 #define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.5.16 - May 23, 2013\n"
+     " libpng version 1.5.17 - June 27, 2013\n"
 
 #define PNG_LIBPNG_VER_SONUM   15
 #define PNG_LIBPNG_VER_DLLNUM  15
 
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   5
-#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:
  */
 
 #define PNG_LIBPNG_VER_BUILD  0
 
 /* Release Status */
@@ -434,17 +437,17 @@
 #define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
 
 /* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
  * We must not include leading zeros.
  * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
  * version 1.0.0 was mis-numbered 100 instead of 10000).  From
  * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=release
  */
-#define PNG_LIBPNG_VER 10516 /* 1.5.16 */
+#define PNG_LIBPNG_VER 10517 /* 1.5.17 */
 
 #ifndef MOZPNGCONF_H
 #   include "mozpngconf.h"
 #endif
 
 #ifndef PNG_VERSION_INFO_ONLY
 #  ifndef PNG_BUILDING_SYMBOL_TABLE
   /*
@@ -547,20 +550,31 @@ extern "C" {
  * Otherwise the calls are mapped to png_error.
  */
 
 /* Section 2: type definitions, including structures and compile time
  * constants.
  * See pngconf.h for base types that vary by machine/system
  */
 
+#ifdef PNG_APNG_SUPPORTED
+/* dispose_op flags from inside fcTL */
+#define PNG_DISPOSE_OP_NONE        0x00
+#define PNG_DISPOSE_OP_BACKGROUND  0x01
+#define PNG_DISPOSE_OP_PREVIOUS    0x02
+
+/* blend_op flags from inside fcTL */
+#define PNG_BLEND_OP_SOURCE        0x00
+#define PNG_BLEND_OP_OVER          0x01
+#endif /* PNG_APNG_SUPPORTED */
+
 /* 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_5_16;
+typedef char* png_libpng_version_1_5_17;
 
 /* Three color definitions.  The order of the red, green, and blue, (and the
  * exact size) is not important, although the size of the fields need to
  * be png_byte or png_uint_16 (as defined below).
  */
 typedef struct png_color_struct
 {
    png_byte red;
@@ -2662,26 +2676,56 @@ PNG_EXPORT(207, void, png_save_uint_16, 
 PNG_EXPORT(234, void, png_set_check_for_invalid_index, (png_structp png_ptr,
     int allowed));
 #  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
 PNG_EXPORT(235, int, png_get_palette_max, (png_const_structp png_ptr,
     png_const_infop info_ptr));
 #  endif
 #endif /* CHECK_FOR_INVALID_INDEX */
 
-#ifdef PNG_APNG_SUPPORTED
-/* dispose_op flags from inside fcTL */
-#define PNG_DISPOSE_OP_NONE        0x00
-#define PNG_DISPOSE_OP_BACKGROUND  0x01
-#define PNG_DISPOSE_OP_PREVIOUS    0x02
+/*******************************************************************************
+ *  IMPLEMENTATION OPTIONS
+ *******************************************************************************
+ *
+ * Support for arbitrary implementation-specific optimizations.  The API allows
+ * particular options to be turned on or off.  'Option' is the number of the
+ * option and 'onoff' is 0 (off) or non-0 (on).  The value returned is given
+ * by the PNG_OPTION_ defines below.
+ *
+ * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,
+ *           are detected at run time, however sometimes it may be impossible
+ *           to do this in user mode, in which case it is necessary to discover
+ *           the capabilities in an OS specific way.  Such capabilities are
+ *           listed here when libpng has support for them and must be turned
+ *           ON by the application if present.
+ *
+ * SOFTWARE: sometimes software optimizations actually result in performance
+ *           decrease on some architectures or systems, or with some sets of
+ *           PNG images.  'Software' options allow such optimizations to be
+ *           selected at run time.
+ */
+#ifdef PNG_SET_OPTION_SUPPORTED
+#ifdef PNG_ARM_NEON_API_SUPPORTED
+#  define PNG_ARM_NEON   0 /* HARDWARE: ARM Neon SIMD instructions supported */
+#endif
+#define PNG_OPTION_NEXT  2 /* Next option - numbers must be even */
 
-/* blend_op flags from inside fcTL */
-#define PNG_BLEND_OP_SOURCE        0x00
-#define PNG_BLEND_OP_OVER          0x01
-#endif /* PNG_APNG_SUPPORTED */
+/* Return values: NOTE: there are four values and 'off' is *not* zero */
+#define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
+#define PNG_OPTION_INVALID 1 /* Option number out of range */
+#define PNG_OPTION_OFF     2
+#define PNG_OPTION_ON      3
+
+PNG_EXPORT(236, int, png_set_option, (png_structp png_ptr, int option,
+   int onoff));
+#endif
+
+/*******************************************************************************
+ *  END OF HARDWARE OPTIONS
+ ******************************************************************************/
 
 #ifdef PNG_APNG_SUPPORTED
 PNG_EXPORT(237, png_uint_32, png_get_acTL, (png_structp png_ptr,
    png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
 
 PNG_EXPORT(238, png_uint_32, png_set_acTL, (png_structp png_ptr,
    png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
 
@@ -2742,57 +2786,16 @@ PNG_EXPORT(255, void, png_write_frame_he
    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
    png_byte blend_op));
 
 PNG_EXPORT(256, void, png_write_frame_tail, (png_structp png_ptr,
    png_infop info_ptr));
 #endif /* PNG_WRITE_APNG_SUPPORTED */
 #endif /* PNG_APNG_SUPPORTED */
 
-/*******************************************************************************
- *  IMPLEMENTATION OPTIONS
- *******************************************************************************
- *
- * Support for arbitrary implementation-specific optimizations.  The API allows
- * particular options to be turned on or off.  'Option' is the number of the
- * option and 'onoff' is 0 (off) or non-0 (on).  The value returned is given
- * by the PNG_OPTION_ defines below.
- *
- * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,
- *           are detected at run time, however sometimes it may be impossible
- *           to do this in user mode, in which case it is necessary to discover
- *           the capabilities in an OS specific way.  Such capabilities are
- *           listed here when libpng has support for them and must be turned
- *           ON by the application if present.
- *
- * SOFTWARE: sometimes software optimizations actually result in performance
- *           decrease on some architectures or systems, or with some sets of
- *           PNG images.  'Software' options allow such optimizations to be
- *           selected at run time.
- */
-#ifdef PNG_SET_OPTION_SUPPORTED
-#ifdef PNG_ARM_NEON_API_SUPPORTED
-#  define PNG_ARM_NEON   0 /* HARDWARE: ARM Neon SIMD instructions supported */
-#endif
-#define PNG_OPTION_NEXT  2 /* Next option - numbers must be even */
-
-/* Return values: NOTE: there are four values and 'off' is *not* zero */
-#define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
-#define PNG_OPTION_INVALID 1 /* Option number out of range */
-#define PNG_OPTION_OFF     2
-#define PNG_OPTION_ON      3
-
-PNG_EXPORT(236, int, png_set_option, (png_structp png_ptr, int option,
-   int onoff));
-#endif
-
-/*******************************************************************************
- *  END OF HARDWARE OPTIONS
- ******************************************************************************/
-
 /* Maintainer: Put new public prototypes here ^, in libpng.3, and project
  * defs
  */
 
 /* The last ordinal number (this is the *last* one already used; the next
  * one to use is one more than this.)  Maintainer, remember to add an entry to
  * scripts/symbols.def as well.
  */
--- a/media/libpng/pngconf.h
+++ b/media/libpng/pngconf.h
@@ -1,12 +1,12 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.5.16 - May 23, 2013
+ * libpng version 1.5.17 - June 27, 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.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
--- a/media/libpng/pngget.c
+++ b/media/libpng/pngget.c
@@ -1297,9 +1297,10 @@ png_get_first_frame_is_hidden(png_struct
     if (png_ptr != NULL)
        return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
 
     PNG_UNUSED(info_ptr)
 
     return 0;
 }
 #endif /* PNG_APNG_SUPPORTED */
+
 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
--- a/media/libpng/pngpread.c
+++ b/media/libpng/pngpread.c
@@ -652,17 +652,16 @@ png_push_read_chunk(png_structp png_ptr,
          png_push_save_buffer(png_ptr);
          return;
       }
 
       png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
    }
 
 #endif
-
 #ifdef PNG_READ_APNG_SUPPORTED
    else if (chunk_name == png_acTL)
    {
       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       {
          png_push_save_buffer(png_ptr);
          return;
       }
--- a/media/libpng/pngpriv.h
+++ b/media/libpng/pngpriv.h
@@ -1,17 +1,17 @@
 
 /* pngpriv.h - private declarations for use inside libpng
  *
  * For conditions of distribution and use, see copyright notice in png.h
  * 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.5.15 [March 28, 2013]
+ * Last changed in libpng 1.5.17 [June 27, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 /* The symbols declared in this file (including the functions declared
  * as PNG_EXTERN) are PRIVATE.  They are not part of the libpng public
@@ -57,16 +57,56 @@
 #  ifndef PNG_USER_PRIVATEBUILD
 #    define PNG_USER_PRIVATEBUILD "Custom libpng build"
 #  endif
 #  ifndef PNG_USER_DLLFNAME_POSTFIX
 #    define PNG_USER_DLLFNAME_POSTFIX "Cb"
 #  endif
 #endif
 
+/* Compile time options.
+ * =====================
+ * In a multi-arch build the compiler may compile the code several times for the
+ * same object module, producing different binaries for different architectures.
+ * When this happens configure-time setting of the target host options cannot be
+ * done and this interferes with the handling of the ARM NEON optimizations, and
+ * possibly other similar optimizations.  Put additional tests here; in general
+ * this is needed when the same option can be changed at both compile time and
+ * run time depending on the target OS (i.e. iOS vs Android.)
+ *
+ * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because
+ * this is not possible with certain compilers (Oracle SUN OS CC), as a result
+ * it is necessary to ensure that all extern functions that *might* be used
+ * regardless of $(CFLAGS) get declared in this file.  The test on __ARM_NEON__
+ * below is one example of this behavior because it is controlled by the
+ * presence or not of -mfpu=neon on the GCC command line, it is possible to do
+ * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely
+ * do this.
+ */
+#ifndef PNG_ARM_NEON_OPT
+   /* ARM NEON optimizations are being controlled by the compiler settings,
+    * typically the target FPU.  If the FPU has been set to NEON (-mfpu=neon
+    * with GCC) then the compiler will define __ARM_NEON__ and we can rely
+    * unconditionally on NEON instructions not crashing, otherwise we must
+    * disable use of NEON instructions:
+    */
+#  ifdef __ARM_NEON__
+#     define PNG_ARM_NEON_OPT 2
+#  else
+#     define PNG_ARM_NEON_OPT 0
+#  endif
+#endif
+
+#if PNG_ARM_NEON_OPT > 0
+   /* NEON optimizations are to be at least considered by libpng, so enable the
+    * callbacks to do this.
+    */
+#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
+#endif
+
 /* Is this a build of a DLL where compilation of the object modules requires
  * different preprocessor settings to those required for a simple library?  If
  * so PNG_BUILD_DLL must be set.
  *
  * If libpng is used inside a DLL but that DLL does not export the libpng APIs
  * PNG_BUILD_DLL must not be set.  To avoid the code below kicking in build a
  * static library of libpng then link the DLL against that.
  */
@@ -1776,23 +1816,31 @@ PNG_EXTERN void png_set_gamma_fixed PNGA
 #endif
 
 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
 PNG_EXTERN void png_set_rgb_to_gray_fixed PNGARG((png_structp png_ptr,
     int error_action, png_fixed_point red, png_fixed_point green));
 #endif
 #endif /* FIX MISSING !FIXED_POINT DECLARATIONS */
 
+/* These are initialization functions for hardware specific PNG filter
+ * optimizations; list these here then select the appropriate one at compile
+ * time using the macro PNG_FILTER_OPTIMIZATIONS.  If the macro is not defined
+ * the generic code is used.
+ */
 #ifdef PNG_FILTER_OPTIMIZATIONS
 PNG_EXTERN void PNG_FILTER_OPTIMIZATIONS(png_structp png_ptr, unsigned int bpp);
-   /* This is the initialization function for hardware specific optimizations,
-    * one implementation (for ARM NEON machines) is contained in
-    * arm/filter_neon.c.  It need not be defined - the generic code will be used
-    * if not.
+   /* Just declare the optimization that will be used */
+#else
+   /* List *all* the possible optimizations here - this branch is required if
+    * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
+    * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
     */
+PNG_EXTERN void png_init_filter_functions_neon(png_structp png_ptr,
+    unsigned int bpp);
 #endif
 
 /* Maintainer: Put new private prototypes here ^ */
 
 #include "pngdebug.h"
 
 #ifdef __cplusplus
 }
--- a/media/libpng/pngread.c
+++ b/media/libpng/pngread.c
@@ -364,16 +364,17 @@ png_read_frame_head(png_structp png_ptr,
 
     /* do nothing for the main IDAT */
     if (png_ptr->num_frames_read == 0)
         return;
 
     png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
 
     png_read_reset(png_ptr);
+    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
     png_ptr->mode &= ~PNG_HAVE_fcTL;
 
     have_chunk_after_DAT = 0;
     for (;;)
     {
         png_uint_32 length = png_read_chunk_header(png_ptr);
 
         if (png_ptr->chunk_name == png_IDAT)
--- a/media/libpng/pngrutil.c
+++ b/media/libpng/pngrutil.c
@@ -4297,17 +4297,16 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED
  * to make them usable by the read functions again */
 void /* PRIVATE */
 png_read_reset(png_structp png_ptr)
 {
     png_ptr->mode &= ~PNG_HAVE_IDAT;
     png_ptr->mode &= ~PNG_AFTER_IDAT;
     png_ptr->row_number = 0;
     png_ptr->pass = 0;
-    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 }
 
 void /* PRIVATE */
 png_read_reinit(png_structp png_ptr, png_infop info_ptr)
 {
     png_ptr->width = info_ptr->next_frame_width;
     png_ptr->height = info_ptr->next_frame_height;
     png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
--- a/media/libpng/pngset.c
+++ b/media/libpng/pngset.c
@@ -1,12 +1,12 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * Last changed in libpng 1.5.14 [January 24, 2013]
+ * Last changed in libpng 1.5.17 [June 27, 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.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
@@ -247,26 +247,17 @@ png_set_IHDR(png_structp png_ptr, png_in
    else
       info_ptr->channels = 1;
 
    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
       info_ptr->channels++;
 
    info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
 
-   /* Check for potential overflow */
-   if (width >
-       (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
-       - 48       /* bigrowbuf hack */
-       - 1        /* filter byte */
-       - 7*8      /* rounding of width to multiple of 8 pixels */
-       - 8)       /* extra max_pixel_depth pad */
-      info_ptr->rowbytes = 0;
-   else
-      info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
+   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
 
 #ifdef PNG_APNG_SUPPORTED
    /* for non-animated png. this may be overwritten from an acTL chunk later */
    info_ptr->num_frames = 1;
 #endif
 }
 
 #ifdef PNG_oFFs_SUPPORTED
@@ -1153,18 +1144,18 @@ png_ensure_fcTL_is_valid(png_structp png
     if (height > PNG_UINT_31_MAX)
         png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
     if (x_offset > PNG_UINT_31_MAX)
         png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
     if (y_offset > PNG_UINT_31_MAX)
         png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
     if (width + x_offset > png_ptr->first_frame_width ||
         height + y_offset > png_ptr->first_frame_height)
-        png_error(png_ptr, "dimensions of a frame in fcTL are greater than"
-                           "those in IHDR");
+        png_error(png_ptr, "dimensions of a frame are greater than"
+                           "the ones in IHDR");
 
     if (dispose_op != PNG_DISPOSE_OP_NONE &&
         dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
         dispose_op != PNG_DISPOSE_OP_PREVIOUS)
         png_error(png_ptr, "invalid dispose_op in fcTL");
 
     if (blend_op != PNG_BLEND_OP_SOURCE &&
         blend_op != PNG_BLEND_OP_OVER)
--- a/media/libpng/pngwrite.c
+++ b/media/libpng/pngwrite.c
@@ -309,17 +309,16 @@ png_write_end(png_structp png_ptr, png_i
    if (!(png_ptr->mode & PNG_HAVE_IDAT))
       png_error(png_ptr, "No IDATs written into file");
 
 #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
    if (png_ptr->num_palette_max > png_ptr->num_palette)
       png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
 #endif
 
-    /* See if user wants us to write information chunks */
 #ifdef PNG_WRITE_APNG_SUPPORTED
    if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
       png_error(png_ptr, "Not enough frames written");
 #endif
 
    /* See if user wants us to write information chunks */
    if (info_ptr != NULL)
    {
--- a/media/libpng/pngwutil.c
+++ b/media/libpng/pngwutil.c
@@ -1041,17 +1041,17 @@ png_write_IDAT(png_structp png_ptr, png_
    if (png_ptr->num_frames_written == 0)
 #endif
    png_write_complete_chunk(png_ptr, png_IDAT, data, length);
 #ifdef PNG_WRITE_APNG_SUPPORTED
    else
    {
       png_byte buf[4];
 
-      png_write_chunk_header(png_ptr, png_fdAT, 4 + length);
+      png_write_chunk_header(png_ptr, png_fdAT, (png_uint_32)(4 + length));
 
       png_save_uint_32(buf, png_ptr->next_seq_num);
       png_write_chunk_data(png_ptr, buf, 4);
 
       png_write_chunk_data(png_ptr, data, length);
 
       png_write_chunk_end(png_ptr);