Bug 952505 - Update bundled libpng to version 1.6.9. r=jmuizelaar
☠☠ backed out by 314f24c02ea5 ☠ ☠
authorGlenn Randers-Pehrson <glennrp+bmo@gmail.com>
Fri, 14 Feb 2014 11:58:14 -0500
changeset 187059 2f858de5e9dcffea30f031926ba862702385b9d3
parent 187058 f73e612c9641bf35720b79bbc3a235807f1d2587
child 187060 a99d7db15f4acf7d960935e208e7c8097cb5d7f5
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmuizelaar
bugs952505
milestone30.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 952505 - Update bundled libpng to version 1.6.9. r=jmuizelaar
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/arm/filter_neon_intrinsics.c
media/libpng/libpng-manual.txt
media/libpng/mozpngconf.h
media/libpng/png.c
media/libpng/png.h
media/libpng/pngconf.h
media/libpng/pngdebug.h
media/libpng/pngerror.c
media/libpng/pngmem.c
media/libpng/pngpread.c
media/libpng/pngpriv.h
media/libpng/pngread.c
media/libpng/pngrio.c
media/libpng/pngrtran.c
media/libpng/pngrutil.c
media/libpng/pngset.c
media/libpng/pngtrans.c
media/libpng/pngwio.c
media/libpng/pngwrite.c
media/libpng/pngwtran.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=10607
+MOZPNG=10609
 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
@@ -4707,16 +4707,103 @@ Version 1.6.7beta04 [October 26, 2013]
 Version 1.6.7rc01 [November 2, 2013]
   No changes.
 
 Version 1.6.7rc02 [November 7, 2013]
   Fixed #include in filter_neon_intrinsics.c and ctype macros. The ctype char
     checking macros take an unsigned char argument, not a signed char.
 
 Version 1.6.7 [November 14, 2013]
+  No changes.
+
+Version 1.6.8beta01 [November 24, 2013]
+  Moved prototype for png_handle_unknown() in pngpriv.h outside of
+    the #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED/#endif block.
+  Added "-Wall" to CFLAGS in contrib/pngminim/*/makefile
+  Conditionally compile some unused functions reported by -Wall in
+    pngminim.
+  Fixed 'minimal' builds. Various obviously useful minimal configurations
+    don't build because of missing contrib/libtests test programs and
+    overly complex dependencies in scripts/pnglibconf.dfa. This change
+    adds contrib/conftest/*.dfa files that can be used in automatic build
+    scripts to ensure that these configurations continue to build.
+  Enabled WRITE_INVERT and WRITE_PACK in contrib/pngminim/encoder.
+  Fixed pngvalid 'fail' function declaration on the Intel C Compiler.
+    This reverts to the previous 'static' implementation and works round
+    the 'unused static function' warning by using PNG_UNUSED().
+
+Version 1.6.8beta02 [November 30, 2013]
+  Removed or marked PNG_UNUSED some harmless "dead assignments" reported
+    by clang scan-build.
+  Changed tabs to 3 spaces in png_debug macros and changed '"%s"m'
+    to '"%s" m' to improve portability among compilers.
+  Changed png_free_default() to free() in pngtest.c
+
+Version 1.6.8rc01 [December 12, 2013]
+  Tidied up pngfix inits and fixed pngtest no-write builds.
+
+Version 1.6.8rc02 [December 14, 2013]
+  Handle zero-length PLTE chunk or NULL palette with png_error()
+    instead of png_chunk_report(), which by default issues a warning
+    rather than an error, leading to later reading from a NULL pointer
+    (png_ptr->palette) in png_do_expand_palette(). This is CVE-2013-6954
+    and VU#650142.  Libpng-1.6.1 through 1.6.7 are vulnerable.
+    Libpng-1.6.0 and earlier do not have this bug.
+
+Version 1.6.8 [December 19, 2013]
+  No changes.
+
+Version 1.6.9beta01 [December 26, 2013]
+  Bookkeeping: Moved functions around (no changes). Moved transform
+    function definitions before the place where they are called so that
+    they can be masde static. Move the intrapixel functions and the
+    grayscale palette builder out of the png?tran.c files. The latter
+    isn't a transform function and is no longer used internally, and the
+    former MNG specific functions are better placed in pngread/pngwrite.c
+  Made transform implementation functions static. This makes the internal
+    functions called by png_do_{read|write}_transformations static. On an
+    x86-64 DLL build (Gentoo Linux) this reduces the size of the text
+    segment of the DLL by 1208 bytes, about 0.6%. It also simplifies
+    maintenance by removing the declarations from pngpriv.h and allowing
+    easier changes to the internal interfaces.
+  Rebuilt configure scripts with automake-1.14.1 and autoconf-2.69
+    in the tar distributions.
+
+Version 1.6.9beta02 [January 1, 2014]
+  Added checks for libpng 1.5 to pngvalid.c.  This supports the use of
+    this version of pngvalid in libpng 1.5
+  Merged with pngvalid.c from libpng-1.7 changes to create a single
+    pngvalid.c
+  Removed #error macro from contrib/tools/pngfix.c (Thomas Klausner).
+  Merged pngrio.c, pngtrans.c, pngwio.c, and pngerror.c with libpng-1.7.0
+  Merged libpng-1.7.0 changes to make no-interlace configurations work
+    with test programs.
+  Revised pngvalid.c to support libpng 1.5, which does not support the
+    PNG_MAXIMUM_INFLATE_WINDOW option, so #define it out when appropriate in
+    pngvalid.c
+  Allow unversioned links created on install to be disabled in configure.
+    In configure builds 'make install' changes/adds links like png.h
+    and libpng.a to point to the newly installed, versioned, files (e.g.
+    libpng17/png.h and libpng17.a). Three new configure options and some
+    rearrangement of Makefile.am allow creation of these links to be disabled.
+
+Version 1.6.9beta03 [January 10, 2014]
+  Removed potentially misleading warning from png_check_IHDR().
+
+Version 1.6.9beta04 [January 20, 2014]
+  Updated scripts/makefile.* to use CPPFLAGS (Cosmin).
+  Added clang attribute support (Cosmin).
+
+Version 1.6.9rc01 [January 28, 2014]
+  No changes.
+
+Version 1.6.9rc02 [January 30, 2014]
+  Quiet an uninitialized memory warning from VC2013 in png_get_png().
+
+Version 1.6.9 [February 6, 2014]
 
 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,18 +5,18 @@ 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.6.7, November 14, 2013, are
-Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson, and are
+libpng versions 1.2.6, August 15, 2004, through 1.6.9, February 6, 2014, are
+Copyright (c) 2004, 2006-2014 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
 distributed according to the same disclaimer and license as libpng-1.0.6
@@ -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
-November 14, 2013
+February 6, 2014
--- a/media/libpng/MOZCHANGES
+++ b/media/libpng/MOZCHANGES
@@ -1,11 +1,15 @@
 
 Changes made to pristine png source by mozilla.org developers.
 
+2014/02/11  -- Synced with libpng-1.6.9 (bug #952505).
+
+2014/02/11  -- Fixed crash with empty PLTE, CVE-2013-6954 (bug #945912)
+
 2013/12/11  -- Enable ARM support (bug #832390).
 
 2013/11/17  -- Synced with libpng-1.6.7 (bug #938740).
 
 2013/09/21  -- Synced with libpng-1.6.6 (bug #886499).
 
 2013/07/17  -- Synced with libpng-1.5.17 (bug #886499).
 
--- a/media/libpng/README
+++ b/media/libpng/README
@@ -1,9 +1,9 @@
-README for libpng version 1.6.7 - November 14, 2013 (shared library 16.0)
+README for libpng version 1.6.9 - February 6, 2014 (shared library 16.0)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
 
 Libpng comes in several distribution formats.  Get libpng-*.tar.gz or
 libpng-*.tar.xz or if you want UNIX-style line endings in the text files,
 or lpng*.7z or lpng*.zip if you want DOS-style line endings.
 
@@ -116,17 +116,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 eighteen years now, and it is official and
+been discussing PNG for nineteen 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
--- a/media/libpng/apng.patch
+++ b/media/libpng/apng.patch
@@ -273,28 +273,28 @@ Index: pngget.c
 +    return 0;
 +}
 +#endif /* PNG_APNG_SUPPORTED */
  #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
 Index: png.h
 ===================================================================
 --- png.h
 +++ png.h
-@@ -448,6 +448,10 @@
+@@ -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
     /* Machine specific configuration. */
  #  include "pngconf.h"
-@@ -538,6 +542,17 @@
+@@ -544,6 +548,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
@@ -302,39 +302,39 @@ Index: png.h
 +/* 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.
   */
-@@ -858,6 +873,10 @@
+@@ -864,6 +879,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
-@@ -895,6 +914,10 @@
+@@ -901,6 +920,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
-@@ -3298,6 +3321,75 @@
+@@ -3304,6 +3327,75 @@
   *  END OF HARDWARE OPTIONS
   ******************************************************************************/
  
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_EXPORT(245, 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(246, png_uint_32, png_set_acTL, (png_structp png_ptr,
@@ -400,63 +400,63 @@ Index: png.h
 +PNG_EXPORT(264, 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, scripts/pnglibconf.h, and scripts/pnglibconf.h.prebuilt
   */
-@@ -3307,7 +3399,11 @@
+@@ -3313,7 +3405,11 @@
   * scripts/symbols.def as well.
   */
  #ifdef PNG_EXPORT_LAST_ORDINAL
 +#ifdef PNG_APNG_SUPPORTED
 +  PNG_EXPORT_LAST_ORDINAL(264);
 +#else
    PNG_EXPORT_LAST_ORDINAL(244);
 +#endif /* PNG_APNG_SUPPORTED */
  #endif
  
  #ifdef __cplusplus
 Index: pngpriv.h
 ===================================================================
 --- pngpriv.h
 +++ pngpriv.h
-@@ -544,6 +544,10 @@
+@@ -550,6 +550,10 @@
  #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
                     /*             0x4000 (unused) */
  #define PNG_IS_READ_STRUCT        0x8000 /* Else is a write struct */
 +#ifdef PNG_APNG_SUPPORTED
 +#define PNG_HAVE_acTL            0x10000
 +#define PNG_HAVE_fcTL            0x20000
 +#endif
  
  /* Flags for the transformations the PNG library does on the image data */
  #define PNG_BGR                 0x0001
-@@ -765,6 +769,16 @@
+@@ -771,6 +775,16 @@
  #define png_tRNS PNG_U32(116,  82,  78,  83)
  #define png_zTXt PNG_U32(122,  84,  88, 116)
  
 +#ifdef PNG_APNG_SUPPORTED
 +#define png_acTL PNG_U32( 97,  99,  84,  76)
 +#define png_fcTL PNG_U32(102,  99,  84,  76)
 +#define png_fdAT PNG_U32(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.
   */
-@@ -1559,6 +1573,49 @@
-     png_bytep row),PNG_EMPTY);
- #endif
+@@ -1451,6 +1465,49 @@
+ 
+ #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_INTERNAL_FUNCTION(void,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),PNG_EMPTY);
 +
@@ -576,17 +576,17 @@ Index: pngwrite.c
 +#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
 +
  #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");
-@@ -2327,4 +2336,42 @@
+@@ -2397,4 +2406,42 @@
  }
  #endif /* PNG_STDIO_SUPPORTED */
  #endif /* SIMPLIFIED_WRITE */
 +
 +#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,
@@ -745,18 +745,18 @@ Index: pngpread.c
 +#ifdef PNG_READ_APNG_SUPPORTED
 +      png_have_info(png_ptr, info_ptr);
 +#endif
        png_ptr->idat_size = png_ptr->push_length;
        png_ptr->process_mode = PNG_READ_IDAT_MODE;
        png_push_have_info(png_ptr, info_ptr);
 @@ -530,6 +636,30 @@
     }
+ #endif
  
- #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;
 +      }
@@ -1054,29 +1054,29 @@ Index: pngset.c
 +
  #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
  static png_byte
  check_location(png_const_structrp png_ptr, int location)
 Index: pngrutil.c
 ===================================================================
 --- pngrutil.c
 +++ pngrutil.c
-@@ -821,6 +821,11 @@
+@@ -826,6 +826,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;
-@@ -2695,6 +2700,179 @@
+@@ -2700,6 +2705,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];
@@ -1246,17 +1246,17 @@ Index: pngrutil.c
 +
 +    png_ptr->next_seq_num++;
 +}
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
  #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
  static int
-@@ -3953,6 +4131,38 @@
+@@ -3957,6 +4135,38 @@
           uInt avail_in;
           png_bytep buffer;
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_uint_32 bytes_to_skip = 0;
 +
 +         while (png_ptr->idat_size == 0 || bytes_to_skip != 0)
 +         {
@@ -1285,35 +1285,35 @@ Index: pngrutil.c
 +
 +               png_ptr->idat_size -= 4;
 +            }
 +         }
 +#else
           while (png_ptr->idat_size == 0)
           {
              png_crc_finish(png_ptr, 0);
-@@ -3964,6 +4174,7 @@
+@@ -3968,6 +4178,7 @@
              if (png_ptr->chunk_name != png_IDAT)
                 png_error(png_ptr, "Not enough image data");
           }
 +#endif /* PNG_READ_APNG_SUPPORTED */
  
           avail_in = png_ptr->IDAT_read_size;
  
-@@ -4027,6 +4238,9 @@
+@@ -4031,6 +4242,9 @@
  
           png_ptr->mode |= PNG_AFTER_IDAT;
           png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_ptr->num_frames_read++;
 +#endif
  
           if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
              png_chunk_benign_error(png_ptr, "Extra compressed data");
-@@ -4472,4 +4686,80 @@
+@@ -4476,4 +4690,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 */
--- a/media/libpng/arm/arm_init.c
+++ b/media/libpng/arm/arm_init.c
@@ -85,17 +85,17 @@ safe_read(png_structp png_ptr, int fd, v
       {
          /* This is the devil in the details, a read can terminate early with 0
           * bytes read because of EINTR, yet it still returns -1 otherwise end
           * of file cannot be distinguished.
           */
          if (errno != EINTR)
          {
             png_warning(png_ptr, "/proc read failed");
-            return 0; /* I.e. a permanent failure */
+            return 0; /* I.e., a permanent failure */
          }
       }
 
       else if (iread < 0)
       {
          /* Not a valid 'read' result: */
          png_warning(png_ptr, "OS /proc read bug");
          return 0;
--- a/media/libpng/arm/filter_neon.S
+++ b/media/libpng/arm/filter_neon.S
@@ -1,28 +1,29 @@
 
 /* filter_neon.S - NEON optimised filter functions
  *
  * Copyright (c) 2013 Glenn Randers-Pehrson
  * Written by Mans Rullgard, 2011.
- * Last changed in libpng 1.6.7 [November 14, 2013]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 /* These are required because Mozilla's moz.build system doesn't pass
  * -DDefined macros to the assembler.
  */
 #define PNG_READ_SUPPORTED
 #define MOZ_PNG_HAVE_ARM_NEON
 
 /* This is required to get the symbol renames, which are #defines, and also
- * includes the definition (or not) of PNG_ARM_NEON_OPT.
+ * includes the definition (or not) of PNG_ARM_NEON_OPT and
+ * PNG_ARM_NEON_IMPLEMENTATION.
  */
 #define PNG_VERSION_INFO_ONLY
 #include "../pngpriv.h"
 
 #if defined(__linux__) && defined(__ELF__)
 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
 #endif
 
--- a/media/libpng/arm/filter_neon_intrinsics.c
+++ b/media/libpng/arm/filter_neon_intrinsics.c
@@ -1,32 +1,32 @@
 
 /* filter_neon_intrinsics.c - NEON optimised filter functions
  *
  * Copyright (c) 2013 Glenn Randers-Pehrson
  * Written by James Yu <james.yu at linaro.org>, October 2013.
  * Based on filter_neon.S, written by Mans Rullgard, 2011.
  *
- * Last changed in libpng 1.6.7 [November 14, 2013]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 #include "../pngpriv.h"
 
 /* This code requires -mfpu=neon on the command line: */
-#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code */
+#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
 
 #include <arm_neon.h>
 
 /* libpng row pointers are not necessarily aligned to any particular boundary,
  * however this code will only work with appropriate alignment.  arm/arm_init.c
- * checks for this (and will not compile unless it is done), this code uses
+ * checks for this (and will not compile unless it is done). This code uses
  * variants of png_aligncast to avoid compiler warnings.
  */
 #define png_ptr(type,pointer) png_aligncast(type *,pointer)
 #define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
 
 /* The following relies on a variable 'temp_pointer' being declared with type
  * 'type'.  This is written this way just to hide the GCC strict aliasing
  * warning; note that the code is safe because there never is an alias between
--- a/media/libpng/libpng-manual.txt
+++ b/media/libpng/libpng-manual.txt
@@ -1,24 +1,24 @@
 libpng-manual.txt - A description on how to use and modify libpng
 
- libpng version 1.6.7 - November 14, 2013
+ libpng version 1.6.9 - February 6, 2014
  Updated and distributed by Glenn Randers-Pehrson
  <glennrp at users.sourceforge.net>
- Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ Copyright (c) 1998-2014 Glenn Randers-Pehrson
 
  This document is released under the libpng license.
  For conditions of distribution and use, see the disclaimer
  and license in png.h
 
  Based on:
 
- libpng versions 0.97, January 1998, through 1.6.7 - November 14, 2013
+ libpng versions 0.97, January 1998, through 1.6.9 - February 6, 2014
  Updated and distributed by Glenn Randers-Pehrson
- Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ Copyright (c) 1998-2014 Glenn Randers-Pehrson
 
  libpng 1.0 beta 6  version 0.96 May 28, 1997
  Updated and distributed by Andreas Dilger
  Copyright (c) 1996, 1997 Andreas Dilger
 
  libpng 1.0 beta 2 - version 0.88  January 26, 1996
  For conditions of distribution and use, see copyright
  notice in png.h. Copyright (c) 1995, 1996 Guy Eric
@@ -4388,16 +4388,19 @@ Setting the error callbacks via png_set_
 png_read_init() as was suggested in libpng-0.88 is no longer supported
 because this caused applications that do not use custom error functions
 to fail if the png_ptr was not initialized to zero.  It is still possible
 to set the error callbacks AFTER png_read_init(), or to change them with
 png_set_error_fn(), which is essentially the same function, but with a new
 name to force compilation errors with applications that try to use the old
 method.
 
+Support for the sCAL, iCCP, iTXt, and sPLT chunks was added at libpng-1.0.6;
+however, iTXt support was not enabled by default.
+
 Starting with version 1.0.7, you can find out which version of the library
 you are using at run-time:
 
    png_uint_32 libpng_vn = png_access_version_number();
 
 The number libpng_vn is constructed from the major version, minor
 version with leading zero, and release number with leading zero,
 (e.g., libpng_vn for version 1.0.7 is 10007).
@@ -4616,22 +4619,23 @@ PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS, and 
 was renamed to PNG_READ_QUANTIZE_SUPPORTED.
 
 We removed the trailing '.' from the warning and error messages.
 
 XI.  Changes to Libpng from version 1.4.x to 1.5.x
 
 From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
 function) incorrectly returned a value of type png_uint_32.
-
-Checking for invalid palette index on read or write was added at libpng
-1.5.10.  When an invalid index is found, libpng issues a benign error.
-This is enabled by default because this condition is an error according
-to the PNG specification, Clause 11.3.2, but the error can be ignored in
-each png_ptr with
+The incorrect macro was removed from libpng-1.4.5.
+
+Checking for invalid palette index on write was added at libpng
+1.5.10.  If a pixel contains an invalid (out-of-range) index libpng issues
+a benign error.  This is enabled by default because this condition is an
+error according to the PNG specification, Clause 11.3.2, but the error can
+be ignored in each png_ptr with
 
    png_set_check_for_invalid_index(png_ptr, allowed);
 
       allowed  - one of
                  0: disable benign error (accept the
                     invalid data without warning).
                  1: enable benign error (treat the
                     invalid data as an error or a
@@ -4720,17 +4724,20 @@ not necessary to linearize the image.  T
 been changed to optimize that case correctly, yet.
 
 Fixed point support for the sCAL chunk comes with an important caveat;
 the sCAL specification uses a decimal encoding of floating point values
 and the accuracy of PNG fixed point values is insufficient for
 representation of these values. Consequently a "string" API
 (png_get_sCAL_s and png_set_sCAL_s) is the only reliable way of reading
 arbitrary sCAL chunks in the absence of either the floating point API or
-internal floating point calculations.
+internal floating point calculations.  Starting with libpng-1.5.0, both
+of these functions are present when PNG_sCAL_SUPPORTED is defined.  Prior
+to libpng-1.5.0, their presence also depended upon PNG_FIXED_POINT_SUPPORTED
+being defined and PNG_FLOATING_POINT_SUPPORTED not being defined.
 
 Applications no longer need to include the optional distribution header
 file pngusr.h or define the corresponding macros during application
 build in order to see the correct variant of the libpng API.  From 1.5.0
 application code can check for the corresponding _SUPPORTED macro:
 
 #ifdef PNG_INCH_CONVERSIONS_SUPPORTED
    /* code that uses the inch conversion APIs. */
@@ -4740,21 +4747,16 @@ This macro will only be defined if the i
 compiled into libpng.  The full set of macros, and whether or not support
 has been compiled in, are available in the header file pnglibconf.h.
 This header file is specific to the libpng build.  Notice that prior to
 1.5.0 the _SUPPORTED macros would always have the default definition unless
 reset by pngusr.h or by explicit settings on the compiler command line.
 These settings may produce compiler warnings or errors in 1.5.0 because
 of macro redefinition.
 
-From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
-function) incorrectly returned a value of type png_uint_32.  libpng 1.5.0
-is consistent with the implementation in 1.4.5 and 1.2.x (where the macro
-did not exist.)
-
 Applications can now choose whether to use these macros or to call the
 corresponding function by defining PNG_USE_READ_MACROS or
 PNG_NO_USE_READ_MACROS before including png.h.  Notice that this is
 only supported from 1.5.0; defining PNG_NO_USE_READ_MACROS prior to 1.5.0
 will lead to a link failure.
 
 Prior to libpng-1.5.4, the zlib compressor used the same set of parameters
 when compressing the IDAT data and textual data such as zTXt and iCCP.
@@ -4762,17 +4764,20 @@ In libpng-1.5.4 we reinitialized the zli
 We added five png_set_text_*() functions for setting the parameters to
 use with textual data.
 
 Prior to libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
 option was off by default, and slightly inaccurate scaling occurred.
 This option can no longer be turned off, and the choice of accurate
 or inaccurate 16-to-8 scaling is by using the new png_set_scale_16_to_8()
 API for accurate scaling or the old png_set_strip_16_to_8() API for simple
-chopping.
+chopping.  In libpng-1.5.4, the PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+macro became PNG_READ_SCALE_16_TO_8_SUPPORTED, and the PNG_READ_16_TO_8
+macro became PNG_READ_STRIP_16_TO_8_SUPPORTED, to enable the two
+png_set_*_16_to_8() functions separately.
 
 Prior to libpng-1.5.4, the png_set_user_limits() function could only be
 used to reduce the width and height limits from the value of
 PNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said
 that it could be used to override them.  Now this function will reduce or
 increase the limits.
 
 Starting in libpng-1.5.10, the user limits can be set en masse with the
@@ -5046,28 +5051,29 @@ Unknown chunk handling has been improved
 This adds more correct option control of the unknown handling, corrects
 a pre-existing bug where the per-chunk 'keep' setting is ignored, and makes
 it possible to skip IDAT chunks in the sequential reader.
 
 The machine-generated configure files are no longer included in branches
 libpng16 and later of the GIT repository.  They continue to be included
 in the tarball releases, however.
 
-Libpng-1.6.0 and later use the CMF bytes at the beginning of the IDAT stream
-to set the size of the sliding window for reading instead of using the default
-32-kbyte sliding window size.  It was discovered that there are hundreds of PNG
-files in the wild that have incorrect CMF bytes that cause libpng to now issue
-a "too far back" error and reject the file.  Libpng-1.6.3 provides a way to
-revert to the libpng-1.5.x behavior (ignoring the CMF bytes and using a
+Libpng-1.6.0 through 1.6.2 used the CMF bytes at the beginning of the IDAT
+stream to set the size of the sliding window for reading instead of using the
+default 32-kbyte sliding window size.  It was discovered that there are
+hundreds of PNG files in the wild that have incorrect CMF bytes that caused
+libpng to issue a "too far back" error and reject the file.  Libpng-1.6.3 and
+later calculate their own safe CMF from the image dimensions, provide a way
+to revert to the libpng-1.5.x behavior (ignoring the CMF bytes and using a
 32-kbyte sliding window), by using
 
     png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW,
         PNG_OPTION_ON);
 
-and provides a tool (contrib/tools/pngfix) for optimizing the CMF bytes
+and provide a tool (contrib/tools/pngfix) for optimizing the CMF bytes
 correctly.
 
 Libpng-1.6.0 and libpng-1.6.1 wrote uncompressed iTXt chunks with the wrong
 length, which resulted in PNG files that cannot be read beyond the bad iTXt
 chunk.  This error was fixed in libpng-1.6.3, and a tool (called
 contrib/tools/png-fix-itxt) has been added to the libpng distribution.
 
 XIII.  Detecting libpng
@@ -5227,23 +5233,23 @@ for a few type names that we inherit fro
 We do not use the TAB character for indentation in the C sources.
 
 Lines do not exceed 80 characters.
 
 Other rules can be inferred by inspecting the libpng source.
 
 XVI. Y2K Compliance in libpng
 
-November 14, 2013
+February 6, 2014
 
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
 This is your unofficial assurance that libpng from version 0.71 and
-upward through 1.6.7 are Y2K compliant.  It is my belief that earlier
+upward through 1.6.9 are Y2K compliant.  It is my belief that earlier
 versions were also Y2K compliant.
 
 Libpng only has two year fields.  One is a 2-byte unsigned integer
 that will hold years up to 65535.  The other, which is deprecated,
 holds the date in text format, and will hold years up to 9999.
 
 The integer is
     "png_uint_16 year" in png_time_struct.
--- a/media/libpng/mozpngconf.h
+++ b/media/libpng/mozpngconf.h
@@ -42,17 +42,16 @@
      /* Accept the PNG_ARM_NEON_IMPLEMENTATION setting from pngpriv.h. */
 #  else
 #    define PNG_ARM_NEON_OPT 0
 #  endif
 #else
 #  define PNG_ARM_NEON_OPT 0
 #endif
 
-#define PNG_BENIGN_READ_ERRORS_SUPPORTED
 #define PNG_READ_SUPPORTED
 #define PNG_READ_APNG_SUPPORTED
 #define PNG_READ_cHRM_SUPPORTED
 #define PNG_READ_gAMA_SUPPORTED
 #define PNG_READ_iCCP_SUPPORTED
 #define PNG_READ_sRGB_SUPPORTED
 #define PNG_READ_tRNS_SUPPORTED
 #define PNG_READ_16BIT_SUPPORTED
@@ -69,16 +68,17 @@
 /* necessary for boot animation code */
 #ifdef MOZ_WIDGET_GONK
 #define PNG_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 #define PNG_EASY_ACCESS_SUPPORTED
 #define PNG_READ_BGR_SUPPORTED
 #define PNG_BENIGN_READ_ERRORS_SUPPORTED
+#define PNG_BENIGN_ERRORS_SUPPORTED
 #define PNG_READ_EXPAND_SUPPORTED
 #define PNG_READ_FILLER_SUPPORTED
 #define PNG_READ_GRAY_TO_RGB_SUPPORTED
 #define PNG_READ_STRIP_16_TO_8_SUPPORTED
 #define PNG_READ_STRIP_ALPHA_SUPPORTED
 #define PNG_READ_USER_TRANSFORM_SUPPORTED
 #define PNG_SEQUENTIAL_READ_SUPPORTED
 #endif
@@ -88,17 +88,16 @@
 #define PNG_WRITE_tRNS_SUPPORTED
 #define PNG_WRITE_16BIT_SUPPORTED
 #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
 #define PNG_WRITE_FLUSH_SUPPORTED
 #define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
 #define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
 
 #define PNG_APNG_SUPPORTED
-#define PNG_BENIGN_ERRORS_SUPPORTED
 #define PNG_cHRM_SUPPORTED
 #define PNG_COLORSPACE_SUPPORTED
 #define PNG_gAMA_SUPPORTED
 #define PNG_GAMMA_SUPPORTED
 #define PNG_iCCP_SUPPORTED
 #define PNG_sRGB_SUPPORTED
 #define PNG_tRNS_SUPPORTED
 #define PNG_16BIT_SUPPORTED
--- a/media/libpng/png.c
+++ b/media/libpng/png.c
@@ -1,25 +1,25 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * Last changed in libpng 1.6.2 [April 25, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * 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_6_7 Your_png_h_is_not_version_1_6_7;
+typedef png_libpng_version_1_6_9 Your_png_h_is_not_version_1_6_9;
 
 /* 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
@@ -196,16 +196,17 @@ png_user_version_check(png_structrp png_
          size_t pos = 0;
          char m[128];
 
          pos = png_safecat(m, (sizeof m), pos,
              "Application built with libpng-");
          pos = png_safecat(m, (sizeof m), pos, user_png_ver);
          pos = png_safecat(m, (sizeof m), pos, " but running with ");
          pos = png_safecat(m, (sizeof m), pos, png_libpng_ver);
+         PNG_UNUSED(pos)
 
          png_warning(png_ptr, m);
 #endif
 
 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
          png_ptr->flags = 0;
 #endif
 
@@ -254,16 +255,20 @@ png_create_png_struct,(png_const_charp u
 #     endif
 #  endif
 
    /* The following two API calls simply set fields in png_struct, so it is safe
     * to do them now even though error handling is not yet set up.
     */
 #  ifdef PNG_USER_MEM_SUPPORTED
       png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
+#  else
+      PNG_UNUSED(mem_ptr)
+      PNG_UNUSED(malloc_fn)
+      PNG_UNUSED(free_fn)
 #  endif
 
    /* (*error_fn) can return control to the caller after the error_ptr is set,
     * this will result in a memory leak unless the error_fn does something
     * extremely sophisticated.  The design lacks merit but is implicit in the
     * API.
     */
    png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
@@ -763,24 +768,24 @@ png_const_charp PNGAPI
 png_get_copyright(png_const_structrp 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.6.7 - November 14, 2013" PNG_STRING_NEWLINE \
-     "Copyright (c) 1998-2013 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+     "libpng version 1.6.9 - February 6, 2014" PNG_STRING_NEWLINE \
+     "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
      PNG_STRING_NEWLINE;
 #  else
-      return "libpng version 1.6.7 - November 14, 2013\
-      Copyright (c) 1998-2013 Glenn Randers-Pehrson\
+      return "libpng version 1.6.9 - February 6, 2014\
+      Copyright (c) 1998-2014 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
  * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
@@ -816,16 +821,73 @@ png_get_header_version(png_const_structr
    "     (NO READ SUPPORT)"
 #  endif
    PNG_STRING_NEWLINE;
 #else
    return PNG_HEADER_VERSION_STRING;
 #endif
 }
 
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+/* NOTE: this routine is not used internally! */
+/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
+ * large of png_color.  This lets grayscale images be treated as
+ * paletted.  Most useful for gamma correction and simplification
+ * of code.  This API is not used internally.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+   int num_palette;
+   int color_inc;
+   int i;
+   int v;
+
+   png_debug(1, "in png_do_build_grayscale_palette");
+
+   if (palette == NULL)
+      return;
+
+   switch (bit_depth)
+   {
+      case 1:
+         num_palette = 2;
+         color_inc = 0xff;
+         break;
+
+      case 2:
+         num_palette = 4;
+         color_inc = 0x55;
+         break;
+
+      case 4:
+         num_palette = 16;
+         color_inc = 0x11;
+         break;
+
+      case 8:
+         num_palette = 256;
+         color_inc = 1;
+         break;
+
+      default:
+         num_palette = 0;
+         color_inc = 0;
+         break;
+   }
+
+   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+   {
+      palette[i].red = (png_byte)v;
+      palette[i].green = (png_byte)v;
+      palette[i].blue = (png_byte)v;
+   }
+}
+#endif
+
 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
 int PNGAPI
 png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
 {
    /* Check chunk_name and return "keep" value if it's on the list, else 0 */
    png_const_bytep p, p_end;
 
    if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
@@ -1717,16 +1779,17 @@ png_icc_profile_error(png_const_structrp
          pos = png_safecat(message, (sizeof message), pos,
             png_format_number(number, number+(sizeof number),
                PNG_NUMBER_FORMAT_x, value));
          pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
       }
 #  endif
    /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
    pos = png_safecat(message, (sizeof message), pos, reason);
+   PNG_UNUSED(pos)
 
    /* This is recoverable, but make it unconditionally an app_error on write to
     * avoid writing invalid ICC profiles into PNG files.  (I.e.  we handle them
     * on read, with a warning, but on write unless the app turns off
     * application errors the PNG won't be written.)
     */
    png_chunk_report(png_ptr, message,
       (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
@@ -2405,24 +2468,16 @@ png_check_IHDR(png_const_structrp png_pt
    }
 
    if (height > PNG_UINT_31_MAX)
    {
       png_warning(png_ptr, "Invalid image height in IHDR");
       error = 1;
    }
 
-   if (width > (PNG_UINT_32_MAX
-                 >> 3)      /* 8-byte RGBA pixels */
-                 - 48       /* bigrowbuf hack */
-                 - 1        /* filter byte */
-                 - 7*8      /* rounding of width to multiple of 8 pixels */
-                 - 8)       /* extra max_pixel_depth pad */
-      png_warning(png_ptr, "Width is too large for libpng to process pixels");
-
    /* Check other values */
    if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
        bit_depth != 8 && bit_depth != 16)
    {
       png_warning(png_ptr, "Invalid bit depth in IHDR");
       error = 1;
    }
 
@@ -3086,21 +3141,25 @@ png_ascii_from_fixed(png_const_structrp 
 png_fixed_point
 png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
 {
    double r = floor(100000 * fp + .5);
 
    if (r > 2147483647. || r < -2147483648.)
       png_fixed_error(png_ptr, text);
 
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(text)
+#  endif
+
    return (png_fixed_point)r;
 }
 #endif
 
-#if defined(PNG_READ_GAMMA_SUPPORTED) || \
+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
     defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
 /* muldiv functions */
 /* This API takes signed arguments and rounds the result to the nearest
  * integer (or, for a fixed point number - the standard argument - to
  * the nearest .00001).  Overflow and divide by zero are signalled in
  * the result, a boolean - true on success, false on overflow.
  */
 int
@@ -3263,37 +3322,39 @@ int /* PRIVATE */
 png_gamma_significant(png_fixed_point gamma_val)
 {
    return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
        gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
 }
 #endif
 
 #ifdef PNG_READ_GAMMA_SUPPORTED
+#  ifdef PNG_16BIT_SUPPORTED
 /* A local convenience routine. */
 static png_fixed_point
 png_product2(png_fixed_point a, png_fixed_point b)
 {
    /* The required result is 1/a * 1/b; the following preserves accuracy. */
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+#    ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    double r = a * 1E-5;
    r *= b;
    r = floor(r+.5);
 
    if (r <= 2147483647. && r >= -2147483648.)
       return (png_fixed_point)r;
-#else
+#    else
    png_fixed_point res;
 
    if (png_muldiv(&res, a, b, 100000))
       return res;
-#endif
+#    endif
 
    return 0; /* overflow */
 }
+#  endif /* 16BIT */
 
 /* The inverse of the above. */
 png_fixed_point
 png_reciprocal2(png_fixed_point a, png_fixed_point b)
 {
    /* The required result is 1/a * 1/b; the following preserves accuracy. */
 #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    double r = 1E15/a;
@@ -3588,26 +3649,28 @@ png_exp8bit(png_fixed_point lg2)
    /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the
     * second, rounding, step can't overflow because of the first, subtraction,
     * step.
     */
    x -= x >> 8;
    return (png_byte)((x + 0x7fffffU) >> 24);
 }
 
+#ifdef PNG_16BIT_SUPPORTED
 static png_uint_16
 png_exp16bit(png_fixed_point lg2)
 {
    /* Get a 32-bit value: */
    png_uint_32 x = png_exp(lg2);
 
    /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
    x -= x >> 16;
    return (png_uint_16)((x + 32767U) >> 16);
 }
+#endif /* 16BIT */
 #endif /* FLOATING_ARITHMETIC */
 
 png_byte
 png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
 {
    if (value > 0 && value < 255)
    {
 #     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
@@ -3623,16 +3686,17 @@ png_gamma_8bit_correct(unsigned int valu
          /* Overflow. */
          value = 0;
 #     endif
    }
 
    return (png_byte)value;
 }
 
+#ifdef PNG_16BIT_SUPPORTED
 png_uint_16
 png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
 {
    if (value > 0 && value < 65535)
    {
 #     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
          double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5);
          return (png_uint_16)r;
@@ -3645,33 +3709,40 @@ png_gamma_16bit_correct(unsigned int val
 
          /* Overflow. */
          value = 0;
 #     endif
    }
 
    return (png_uint_16)value;
 }
+#endif /* 16BIT */
 
 /* This does the right thing based on the bit_depth field of the
  * png_struct, interpreting values as 8-bit or 16-bit.  While the result
  * is nominally a 16-bit value if bit depth is 8 then the result is
  * 8-bit (as are the arguments.)
  */
 png_uint_16 /* PRIVATE */
 png_gamma_correct(png_structrp png_ptr, unsigned int value,
     png_fixed_point gamma_val)
 {
    if (png_ptr->bit_depth == 8)
       return png_gamma_8bit_correct(value, gamma_val);
 
+#ifdef PNG_16BIT_SUPPORTED
    else
       return png_gamma_16bit_correct(value, gamma_val);
+#else
+      /* should not reach this */
+      return 0;
+#endif /* 16BIT */
 }
 
+#ifdef PNG_16BIT_SUPPORTED
 /* Internal function to build a single 16-bit table - the table consists of
  * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
  * to shift the input values right (or 16-number_of_signifiant_bits).
  *
  * The caller is responsible for ensuring that the table gets cleaned up on
  * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
  * should be somewhere that will be cleaned.
  */
@@ -3800,16 +3871,17 @@ png_build_16to8_table(png_structrp png_p
 
    /* And fill in the final entries. */
    while (last < (num << 8))
    {
       table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
       last++;
    }
 }
+#endif /* 16BIT */
 
 /* Build a single 8-bit table: same as the 16-bit case but much simpler (and
  * typically much faster).  Note that libpng currently does no sBIT processing
  * (apparently contrary to the spec) so a 256 entry table is always generated.
  */
 static void
 png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
    PNG_CONST png_fixed_point gamma_val)
@@ -3828,36 +3900,39 @@ png_build_8bit_table(png_structrp png_pt
  * tables.
  */
 void /* PRIVATE */
 png_destroy_gamma_table(png_structrp png_ptr)
 {
    png_free(png_ptr, png_ptr->gamma_table);
    png_ptr->gamma_table = NULL;
 
+#ifdef PNG_16BIT_SUPPORTED
    if (png_ptr->gamma_16_table != NULL)
    {
       int i;
       int istop = (1 << (8 - png_ptr->gamma_shift));
       for (i = 0; i < istop; i++)
       {
          png_free(png_ptr, png_ptr->gamma_16_table[i]);
       }
    png_free(png_ptr, png_ptr->gamma_16_table);
    png_ptr->gamma_16_table = NULL;
    }
+#endif /* 16BIT */
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    png_free(png_ptr, png_ptr->gamma_from_1);
    png_ptr->gamma_from_1 = NULL;
    png_free(png_ptr, png_ptr->gamma_to_1);
    png_ptr->gamma_to_1 = NULL;
 
+#ifdef PNG_16BIT_SUPPORTED
    if (png_ptr->gamma_16_from_1 != NULL)
    {
       int i;
       int istop = (1 << (8 - png_ptr->gamma_shift));
       for (i = 0; i < istop; i++)
       {
          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
       }
@@ -3870,16 +3945,17 @@ png_destroy_gamma_table(png_structrp png
       int istop = (1 << (8 - png_ptr->gamma_shift));
       for (i = 0; i < istop; i++)
       {
          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
       }
    png_free(png_ptr, png_ptr->gamma_16_to_1);
    png_ptr->gamma_16_to_1 = NULL;
    }
+#endif /* 16BIT */
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
 }
 
 /* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
  * tables, we don't make a full table if we are reducing to 8-bit in
  * the future.  Note also how the gamma_16 tables are segmented so that
  * we don't need to allocate > 64K chunks for a full 16-bit table.
  */
@@ -3915,16 +3991,17 @@ png_build_gamma_table(png_structrp png_p
             png_reciprocal(png_ptr->colorspace.gamma));
 
         png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
             png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
   }
+#ifdef PNG_16BIT_SUPPORTED
   else
   {
      png_byte shift, sig_bit;
 
      if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
      {
         sig_bit = png_ptr->sig_bit.red;
 
@@ -3971,34 +4048,30 @@ png_build_gamma_table(png_structrp png_p
            shift = (16U - PNG_MAX_GAMMA_8);
      }
 
      if (shift > 8U)
         shift = 8U; /* Guarantees at least one table! */
 
      png_ptr->gamma_shift = shift;
 
-#ifdef PNG_16BIT_SUPPORTED
      /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
       * PNG_COMPOSE).  This effectively smashed the background calculation for
       * 16-bit output because the 8-bit table assumes the result will be reduced
       * to 8 bits.
       */
      if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
-#endif
          png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
          png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
          png_ptr->screen_gamma) : PNG_FP_1);
 
-#ifdef PNG_16BIT_SUPPORTED
      else
          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
          png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
          png_ptr->screen_gamma) : PNG_FP_1);
-#endif
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
      if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
      {
         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
             png_reciprocal(png_ptr->colorspace.gamma));
@@ -4008,16 +4081,17 @@ png_build_gamma_table(png_structrp png_p
          * TODO: fix this.
          */
         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
             png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
             png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
      }
 #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
   }
+#endif /* 16BIT */
 }
 #endif /* READ_GAMMA */
 
 /* HARDWARE OPTION SUPPORT */
 #ifdef PNG_SET_OPTION_SUPPORTED
 int PNGAPI
 png_set_option(png_structrp png_ptr, int option, int onoff)
 {
--- 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.6.7 - November 14, 2013
+ * libpng version 1.6.9 - February 6, 2014
  * 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.6.7 - November 14, 2013: Glenn
+ *   libpng versions 0.97, January 1998, through 1.6.9 - February 6, 2014: 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
@@ -179,18 +179,24 @@
  *    1.6.3rc01               16    10603  16.so.16.3[.0]
  *    1.6.3                   16    10603  16.so.16.3[.0]
  *    1.6.4beta01-02          16    10604  16.so.16.4[.0]
  *    1.6.4rc01               16    10604  16.so.16.4[.0]
  *    1.6.4                   16    10604  16.so.16.4[.0]
  *    1.6.5                   16    10605  16.so.16.5[.0]
  *    1.6.6                   16    10606  16.so.16.6[.0]
  *    1.6.7beta01-04          16    10607  16.so.16.7[.0]
- *    1.6.7rc01-02            16    10607  16.so.16.7[.0]
+ *    1.6.7rc01-03            16    10607  16.so.16.7[.0]
  *    1.6.7                   16    10607  16.so.16.7[.0]
+ *    1.6.8beta01-02          16    10608  16.so.16.8[.0]
+ *    1.6.8rc01-02            16    10608  16.so.16.8[.0]
+ *    1.6.8                   16    10608  16.so.16.8[.0]
+ *    1.6.9beta01-04          16    10609  16.so.16.9[.0]
+ *    1.6.9rc01-02            16    10609  16.so.16.9[.0]
+ *    1.6.9                   16    10609  16.so.16.9[.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
@@ -212,17 +218,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.6.7, November 14, 2013, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.9, February 6, 2014, 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
@@ -324,23 +330,23 @@
  *
  * Thanks to Frank J. T. Wojcik for helping with the documentation.
  */
 
 /*
  * Y2K compliance in libpng:
  * =========================
  *
- *    November 14, 2013
+ *    February 6, 2014
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
  *
  *    This is your unofficial assurance that libpng from version 0.71 and
- *    upward through 1.6.7 are Y2K compliant.  It is my belief that
+ *    upward through 1.6.9 are Y2K compliant.  It is my belief that
  *    earlier versions were also Y2K compliant.
  *
  *    Libpng only has two year fields.  One is a 2-byte unsigned integer
  *    that will hold years up to 65535.  The other, which is deprecated,
  *    holds the date in text format, and will hold years up to 9999.
  *
  *    The integer is
  *        "png_uint_16 year" in png_time_struct.
@@ -390,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.6.7"
+#define PNG_LIBPNG_VER_STRING "1.6.9"
 #define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.6.7 - November 14, 2013\n"
+     " libpng version 1.6.9 - February 6, 2014\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
 
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 7
+#define PNG_LIBPNG_VER_RELEASE 9
 
 /* 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 */
@@ -431,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 10607 /* 1.6.7 */
+#define PNG_LIBPNG_VER 10609 /* 1.6.9 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
  */
 
 #ifndef PNG_VERSION_INFO_ONLY
    /* Machine specific configuration. */
 #  include "mozpngconf.h"
@@ -542,17 +548,17 @@ extern "C" {
 /* 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_6_7;
+typedef char* png_libpng_version_1_6_9;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
  * png_struct is the cache of information used while reading or writing a single
  * PNG file.  One of these is always required, although the simplified API
  * (below) hides the creation and destruction of it.
  */
 typedef struct png_struct_def png_struct;
--- a/media/libpng/pngconf.h
+++ b/media/libpng/pngconf.h
@@ -1,12 +1,12 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.6.7 - November 14, 2013
+ * libpng version 1.6.9 - February 6, 2014
  *
  * 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
@@ -356,17 +356,41 @@
 
 #ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
   /* Support for compiler specific function attributes.  These are used
    * so that where compiler support is available, incorrect use of API
    * functions in png.h will generate compiler warnings.  Added at libpng
    * version 1.2.41.  Disabling these removes the warnings but may also produce
    * less efficient code.
    */
-#  if defined(__GNUC__)
+#  if defined(__clang__)
+     /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
+#    if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
+#      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+#    endif
+#    if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
+#      define PNG_NORETURN __attribute__((__noreturn__))
+#    endif
+#    if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
+#      define PNG_ALLOCATED __attribute__((__malloc__))
+#    endif
+#    if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
+#      define PNG_DEPRECATED __attribute__((__deprecated__))
+#    endif
+#    if !defined(PNG_PRIVATE)
+#      if __has_extension(attribute_unavailable_with_message)
+#        define PNG_PRIVATE __attribute__((__unavailable__(\
+           "This function is not exported by libpng.")))
+#      endif
+#    endif
+#    ifndef PNG_RESTRICT
+#      define PNG_RESTRICT __restrict
+#    endif
+
+#  elif defined(__GNUC__)
 #    ifndef PNG_USE_RESULT
 #      define PNG_USE_RESULT __attribute__((__warn_unused_result__))
 #    endif
 #    ifndef PNG_NORETURN
 #      define PNG_NORETURN   __attribute__((__noreturn__))
 #    endif
 #    if __GNUC__ >= 3
 #      ifndef PNG_ALLOCATED
@@ -379,22 +403,22 @@
 #        if 0 /* Doesn't work so we use deprecated instead*/
 #          define PNG_PRIVATE \
             __attribute__((warning("This function is not exported by libpng.")))
 #        else
 #          define PNG_PRIVATE \
             __attribute__((__deprecated__))
 #        endif
 #      endif
-#      if ((__GNUC__ != 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
+#      if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
 #        ifndef PNG_RESTRICT
 #          define PNG_RESTRICT __restrict
 #        endif
-#      endif /*  __GNUC__ == 3.0 */
-#    endif /*  __GNUC__ >= 3 */
+#      endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
+#    endif /* __GNUC__ >= 3 */
 
 #  elif defined(_MSC_VER)  && (_MSC_VER >= 1300)
 #    ifndef PNG_USE_RESULT
 #      define PNG_USE_RESULT /* not supported */
 #    endif
 #    ifndef PNG_NORETURN
 #      define PNG_NORETURN   __declspec(noreturn)
 #    endif
@@ -414,17 +438,17 @@
 #        define PNG_RESTRICT __restrict
 #      endif
 #    endif
 
 #  elif defined(__WATCOMC__)
 #    ifndef PNG_RESTRICT
 #      define PNG_RESTRICT __restrict
 #    endif
-#  endif /* _MSC_VER */
+#  endif
 #endif /* PNG_PEDANTIC_WARNINGS */
 
 #ifndef PNG_DEPRECATED
 #  define PNG_DEPRECATED  /* Use of this function is deprecated */
 #endif
 #ifndef PNG_USE_RESULT
 #  define PNG_USE_RESULT  /* The result of this function must be checked */
 #endif
@@ -435,16 +459,17 @@
 #  define PNG_ALLOCATED   /* The result of the function is new memory */
 #endif
 #ifndef PNG_PRIVATE
 #  define PNG_PRIVATE     /* This is a private libpng function */
 #endif
 #ifndef PNG_RESTRICT
 #  define PNG_RESTRICT    /* The C99 "restrict" feature */
 #endif
+
 #ifndef PNG_FP_EXPORT     /* A floating point API. */
 #  ifdef PNG_FLOATING_POINT_SUPPORTED
 #     define PNG_FP_EXPORT(ordinal, type, name, args)\
          PNG_EXPORT(ordinal, type, name, args);
 #  else                   /* No floating point APIs */
 #     define PNG_FP_EXPORT(ordinal, type, name, args)
 #  endif
 #endif
--- a/media/libpng/pngdebug.h
+++ b/media/libpng/pngdebug.h
@@ -1,16 +1,16 @@
 
 /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
  *
- * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * 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.0 [January 6, 2011]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 /* Define PNG_DEBUG at compile time for debugging information.  Higher
  * numbers for PNG_DEBUG mean more debugging information.  This has
@@ -20,17 +20,17 @@
  * png_debug[1-2]?(level, message ,arg{0-2})
  *   Expands to a statement (either a simple expression or a compound
  *   do..while(0) statement) that outputs a message with parameter
  *   substitution if PNG_DEBUG is defined to 2 or more.  If PNG_DEBUG
  *   is undefined, 0 or 1 every png_debug expands to a simple expression
  *   (actually ((void)0)).
  *
  *   level: level of detail of message, starting at 0.  A level 'n'
- *          message is preceded by 'n' tab characters (not implemented
+ *          message is preceded by 'n' 3-space indentations (not implemented
  *          on Microsoft compilers unless PNG_DEBUG_FILE is also
  *          defined, to allow debug DLL compilation with no standard IO).
  *   message: a printf(3) style text string.  A trailing '\n' is added
  *            to the message.
  *   arg: 0 to 2 arguments for printf(3) style substitution in message.
  */
 #ifndef PNGDEBUG_H
 #define PNGDEBUG_H
@@ -72,42 +72,39 @@
 #      ifndef PNG_STDIO_SUPPORTED
 #        include <stdio.h> /* not included yet */
 #      endif
 #      ifndef PNG_DEBUG_FILE
 #        define PNG_DEBUG_FILE stderr
 #      endif /* PNG_DEBUG_FILE */
 
 #      if (PNG_DEBUG > 1)
-/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on
- * non-ISO compilers
- */
 #        ifdef __STDC__
 #          ifndef png_debug
 #            define png_debug(l,m) \
        do { \
        int num_tabs=l; \
-       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
+         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : "")))); \
        } while (0)
 #          endif
 #          ifndef png_debug1
 #            define png_debug1(l,m,p1) \
        do { \
        int num_tabs=l; \
-       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
+         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : ""))),p1); \
        } while (0)
 #          endif
 #          ifndef png_debug2
 #            define png_debug2(l,m,p1,p2) \
        do { \
        int num_tabs=l; \
-       fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
-         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
+         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : ""))),p1,p2);\
        } while (0)
 #          endif
 #        else /* __STDC __ */
 #          ifndef png_debug
 #            define png_debug(l,m) \
        do { \
        int num_tabs=l; \
        char format[256]; \
--- a/media/libpng/pngerror.c
+++ b/media/libpng/pngerror.c
@@ -1,12 +1,12 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
@@ -377,51 +377,64 @@ png_benign_error(png_const_structrp png_
 #     ifdef PNG_READ_SUPPORTED
          if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
             png_ptr->chunk_name != 0)
             png_chunk_error(png_ptr, error_message);
          else
 #     endif
       png_error(png_ptr, error_message);
    }
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
 }
 
 void /* PRIVATE */
 png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
 {
   if (png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN)
      png_warning(png_ptr, error_message);
   else
      png_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
 }
 
 void /* PRIVATE */
 png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
 {
   if (png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN)
      png_warning(png_ptr, error_message);
   else
      png_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
 }
 #endif /* BENIGN_ERRORS */
 
 /* These utilities are used internally to build an error message that relates
  * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
  * this is used to prefix the message.  The message is limited in length
  * to 63 bytes, the name characters are output as hex digits wrapped in []
  * if the character is invalid.
  */
 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
 static PNG_CONST char png_digit[16] = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    'A', 'B', 'C', 'D', 'E', 'F'
 };
 
 #define PNG_MAX_ERROR_TEXT 196 /* Currently limited be profile_error in png.c */
-#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
+#if defined(PNG_WARNINGS_SUPPORTED) || \
+   (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
 static void /* PRIVATE */
 png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
     error_message)
 {
    png_uint_32 chunk_name = png_ptr->chunk_name;
    int iout = 0, ishift = 24;
 
    while (ishift >= 0)
@@ -501,23 +514,31 @@ void PNGAPI
 png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
     error_message)
 {
    if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
       png_chunk_warning(png_ptr, error_message);
 
    else
       png_chunk_error(png_ptr, error_message);
+
+#  ifndef PNG_ERROR_TEXT_SUPPORTED
+      PNG_UNUSED(error_message)
+#  endif
 }
 #endif
 #endif /* PNG_READ_SUPPORTED */
 
 void /* PRIVATE */
 png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
 {
+#  ifndef PNG_WARNINGS_SUPPORTED
+      PNG_UNUSED(message)
+#  endif
+
    /* This is always supported, but for just read or just write it
     * unconditionally does the right thing.
     */
 #  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
       if (png_ptr->mode & PNG_IS_READ_STRUCT)
 #  endif
 
 #  ifdef PNG_READ_SUPPORTED
@@ -735,17 +756,22 @@ png_default_error,(png_const_structrp pn
 PNG_FUNCTION(void,PNGAPI
 png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
 {
 #ifdef PNG_SETJMP_SUPPORTED
    if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr)
       png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
 #endif
 
-   /* Here if not setjmp support or if png_ptr is null. */
+   /* If control reaches this point, png_longjmp() must not return. The only
+    * choice is to terminate the whole process (or maybe the thread); to do
+    * this the ANSI-C abort() function is used unless a different method is 
+    * implemented by overriding the default configuration setting for
+    * PNG_ABORT().
+    */
    PNG_ABORT();
 }
 
 #ifdef PNG_WARNINGS_SUPPORTED
 /* This function is called when there is a warning, but the library thinks
  * it can continue anyway.  Replacement functions don't have to do anything
  * here if you don't want them to.  In the default configuration, png_ptr is
  * not used, but it is passed in case it may be useful.
--- a/media/libpng/pngmem.c
+++ b/media/libpng/pngmem.c
@@ -1,12 +1,12 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
@@ -68,19 +68,20 @@ PNG_FUNCTION(png_voidp /* PRIVATE */,
 png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
    PNG_ALLOCATED)
 {
    /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
     * allocators have also been removed in 1.6.0, so any 16-bit system now has
     * to implement a user memory handler.  This checks to be sure it isn't
     * called with big numbers.
     */
-#ifdef PNG_USER_MEM_SUPPORTED
+#ifndef PNG_USER_MEM_SUPPORTED
    PNG_UNUSED(png_ptr)
 #endif
+
    if (size > 0 && size <= PNG_SIZE_MAX
 #     ifdef PNG_MAX_MALLOC_64K
          && size <= 65536U
 #     endif
       )
    {
 #ifdef PNG_USER_MEM_SUPPORTED
       if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
@@ -90,16 +91,18 @@ png_malloc_base,(png_const_structrp png_
 #endif
          return malloc((size_t)size); /* checked for truncation above */
    }
 
    else
       return NULL;
 }
 
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
 /* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
  * that arises because of the checks in png_realloc_array that are repeated in
  * png_malloc_array.
  */
 static png_voidp
 png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
    size_t element_size)
 {
@@ -151,16 +154,17 @@ png_realloc_array,(png_const_structrp pn
             element_size*(unsigned)add_elements);
 
          return new_array;
       }
    }
 
    return NULL; /* error */
 }
+#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
 
 /* Various functions that have different error handling are derived from this.
  * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
  * function png_malloc_default is also provided.
  */
 PNG_FUNCTION(png_voidp,PNGAPI
 png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
 {
--- a/media/libpng/pngpread.c
+++ b/media/libpng/pngpread.c
@@ -1,12 +1,12 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
@@ -180,17 +180,17 @@ png_push_read_sig(png_structrp png_ptr, 
       }
    }
 }
 
 void /* PRIVATE */
 png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
 {
    png_uint_32 chunk_name;
-#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    int keep; /* unknown handling method */
 #endif
 
    /* First we make sure we have enough data for the 4 byte chunk name
     * and the 4 byte chunk length before proceeding with decoding the
     * chunk data.  To fully decode each of these chunks, we also make
     * sure we have enough data in the buffer for the 4 byte CRC at the
     * end of every chunk (except IDAT, which is handled separately).
@@ -369,32 +369,32 @@ png_push_read_chunk(png_structrp png_ptr
       }
 
       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
 
       png_ptr->process_mode = PNG_READ_DONE_MODE;
       png_push_have_end(png_ptr, info_ptr);
    }
 
-#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
    {
       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, keep);
 
       if (chunk_name == png_PLTE)
          png_ptr->mode |= PNG_HAVE_PLTE;
    }
+#endif
 
-#endif
    else if (chunk_name == png_PLTE)
    {
       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       {
          png_push_save_buffer(png_ptr);
          return;
       }
       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
@@ -629,18 +629,18 @@ png_push_read_chunk(png_structrp png_ptr
       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       {
          png_push_save_buffer(png_ptr);
          return;
       }
 
       png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
    }
+#endif
 
-#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;
       }
@@ -653,18 +653,18 @@ png_push_read_chunk(png_structrp png_ptr
       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,
--- 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
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng 1.6.7 [November 14, 2013]
+ * Last changed in libpng 1.6.9 [February 6, 2014]
  *
  * 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 extern) are PRIVATE.  They are not part of the libpng public
@@ -109,34 +109,40 @@
  * 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:
+    * disable use of NEON instructions.
+    *
+    * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they
+    * can only be turned on automatically if that is supported too.  If
+    * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail
+    * to compile with an appropriate #error if ALIGNED_MEMORY has been turned
+    * off.
     */
-#  ifdef __ARM_NEON__
+#  if defined(__ARM_NEON__) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
 #     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
 
    /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used
     * if possible - if __ARM_NEON__ is set and the compiler version is not known
-    * to be broken.  This is control by PNG_ARM_NEON_IMPLEMENTATION which can
+    * to be broken.  This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can
     * be:
     *
     *    1  The intrinsics code (the default with __ARM_NEON__)
     *    2  The hand coded assembler (the default without __ARM_NEON__)
     *
     * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however
     * this is *NOT* supported and may cease to work even after a minor revision
     * to libpng.  It *is* valid to do this for testing purposes, e.g. speed
@@ -1229,53 +1235,28 @@ PNG_INTERNAL_FUNCTION(void,png_read_fini
    PNG_EMPTY);
    /* This cleans up when the IDAT LZ stream does not end when the last image
     * byte is read; there is still some pending input.
     */
 
 PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
    PNG_EMPTY);
    /* Finish a row while reading, dealing with interlacing passes, etc. */
-#endif
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
 
 /* Initialize the row buffers, etc. */
 PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
 
 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
 /* Optional call to update the users info structure */
 PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
     png_inforp info_ptr),PNG_EMPTY);
 #endif
 
-/* These are the functions that do the transformations */
-#ifdef PNG_READ_FILLER_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_read_filler,(png_row_infop row_info,
-    png_bytep row, png_uint_32 filler, png_uint_32 flags),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_read_swap_alpha,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_write_swap_alpha,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_read_invert_alpha,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_write_invert_alpha,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
+/* Shared transform functions, defined in pngtran.c */
 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
 PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,
     png_bytep row, int at_start),PNG_EMPTY);
 #endif
 
 #ifdef PNG_16BIT_SUPPORTED
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
@@ -1285,106 +1266,26 @@ PNG_INTERNAL_FUNCTION(void,png_do_swap,(
 #endif
 
 #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
     defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,
     png_bytep row),PNG_EMPTY);
 #endif
 
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-PNG_INTERNAL_FUNCTION(int,png_do_rgb_to_gray,(png_structrp png_ptr,
-    png_row_infop row_info, png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_gray_to_rgb,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_PACK_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_unpack,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_unshift,(png_row_infop row_info,
-    png_bytep row, png_const_color_8p sig_bits),PNG_EMPTY);
-#endif
-
 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
 PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,
     png_bytep row),PNG_EMPTY);
 #endif
 
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_scale_16_to_8,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_chop,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_quantize,(png_row_infop row_info,
-    png_bytep row, png_const_bytep palette_lookup,
-    png_const_bytep quantize_lookup),PNG_EMPTY);
-
-#  ifdef PNG_CORRECT_PALETTE_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_correct_palette,(png_structrp png_ptr,
-    png_colorp palette, int num_palette),PNG_EMPTY);
-#  endif
-#endif
-
 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
 PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
     png_bytep row),PNG_EMPTY);
 #endif
 
-#ifdef PNG_WRITE_PACK_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_pack,(png_row_infop row_info,
-   png_bytep row, png_uint_32 bit_depth),PNG_EMPTY);
-#endif
-
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_shift,(png_row_infop row_info,
-    png_bytep row, png_const_color_8p bit_depth),PNG_EMPTY);
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
-    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void,png_do_compose,(png_row_infop row_info,
-    png_bytep row, png_structrp png_ptr),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_gamma,(png_row_infop row_info,
-    png_bytep row, png_structrp png_ptr),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_encode_alpha,(png_row_infop row_info,
-   png_bytep row, png_structrp png_ptr),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_expand_palette,(png_row_infop row_info,
-    png_bytep row, png_const_colorp palette, png_const_bytep trans,
-    int num_trans),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_do_expand,(png_row_infop row_info,
-    png_bytep row, png_const_color_16p trans_color),PNG_EMPTY);
-#endif
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_expand_16,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
 /* The following decodes the appropriate chunks, and does error correction,
  * then calls the appropriate callback for the chunk if it is valid.
  */
 
 /* Decode the IHDR chunk */
 PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr,
@@ -1483,26 +1384,24 @@ PNG_INTERNAL_FUNCTION(void,png_check_chu
 PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
    /* This is the function that gets called for unknown chunks.  The 'keep'
     * argument is either non-zero for a known chunk that has been set to be
     * handled as unknown or zero for an unknown chunk.  By default the function
     * just skips the chunk or errors out if it is critical.
     */
 
-#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
-   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+    defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
 PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
     (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
    /* Exactly as the API png_handle_as_unknown() except that the argument is a
     * 32-bit chunk name, not a string.
     */
 #endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
-#endif /* PNG_SET_UNKNOWN_CHUNKS_SUPPORTED */
 
 /* Handle the transformations for reading and writing */
 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
    png_row_infop row_info),PNG_EMPTY);
 #endif
 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
@@ -1563,23 +1462,16 @@ PNG_INTERNAL_FUNCTION(void,png_push_read
 PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr,
     png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
 PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr,
     png_inforp info_ptr),PNG_EMPTY);
 #  endif
 
 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-PNG_INTERNAL_FUNCTION(void,png_do_read_intrapixel,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_do_write_intrapixel,(png_row_infop row_info,
-    png_bytep row),PNG_EMPTY);
-#endif
-
 #ifdef PNG_APNG_SUPPORTED
 PNG_INTERNAL_FUNCTION(void,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),PNG_EMPTY);
 
 #ifdef PNG_READ_APNG_SUPPORTED
@@ -1954,17 +1846,17 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_n
  * function also returns the state at the end of parsing the number if
  * it was valid (otherwise it returns 0.)  This can be used for testing
  * for negative or zero values using the sticky flag.
  */
 PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
    png_size_t size),PNG_EMPTY);
 #endif /* pCAL || sCAL */
 
-#if defined(PNG_READ_GAMMA_SUPPORTED) ||\
+#if defined(PNG_GAMMA_SUPPORTED) ||\
     defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
 /* Added at libpng version 1.5.0 */
 /* This is a utility to provide a*times/div (rounded) and indicate
  * if there is an overflow.  The result is a boolean - false (0)
  * for overflow, true (1) if no overflow, in which case *res
  * holds the result.
  */
 PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
--- a/media/libpng/pngread.c
+++ b/media/libpng/pngread.c
@@ -1,13 +1,13 @@
 
 /* pngread.c - read a PNG file
  *
- * Last changed in libpng 1.6.1 [March 28, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
  * This file contains routines that an application calls directly to
@@ -380,16 +380,82 @@ png_start_read_image(png_structrp png_pt
       else
          png_app_error(png_ptr,
             "png_start_read_image/png_read_update_info: duplicate call");
    }
 }
 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
 
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing,
+ * NOTE: this is apparently only supported in the 'sequential' reader.
+ */
+static void
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_read_intrapixel");
+
+   if (
+       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
+            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
+         }
+      }
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
+            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
+            *(rp    ) = (png_byte)((red >> 8) & 0xff);
+            *(rp + 1) = (png_byte)(red & 0xff);
+            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp + 5) = (png_byte)(blue & 0xff);
+         }
+      }
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+
 void PNGAPI
 png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
 {
    png_row_info row_info;
 
    if (png_ptr == NULL)
       return;
 
@@ -564,17 +630,16 @@ png_read_row(png_structrp png_ptr, png_b
    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
        (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
    {
       /* Intrapixel differencing */
       png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
    }
 #endif
 
-
 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
    if (png_ptr->transformations)
       png_do_read_transformations(png_ptr, &row_info);
 #endif
 
    /* The transformed pixel depth should match the depth now in row_info. */
    if (png_ptr->transformed_pixel_depth == 0)
    {
@@ -1079,17 +1144,17 @@ png_read_png(png_structrp png_ptr, png_i
    /* Expand paletted colors into true RGB triplets
     * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
     * Expand paletted or RGB images with transparency to full alpha
     * channels so the data will be available as RGBA quartets.
     */
    if (transforms & PNG_TRANSFORM_EXPAND)
       if ((png_ptr->bit_depth < 8) ||
           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
-          (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+          (info_ptr->valid & PNG_INFO_tRNS))
          png_set_expand(png_ptr);
 #endif
 
    /* We don't handle background color or gamma transformation or quantizing.
     */
 
 #ifdef PNG_READ_INVERT_SUPPORTED
    /* Invert monochrome files to have 0 as white and 1 as black
@@ -1098,24 +1163,18 @@ png_read_png(png_structrp png_ptr, png_i
       png_set_invert_mono(png_ptr);
 #endif
 
 #ifdef PNG_READ_SHIFT_SUPPORTED
    /* If you want to shift the pixel values from the range [0,255] or
     * [0,65535] to the original [0,7] or [0,31], or whatever range the
     * colors were originally in:
     */
-   if ((transforms & PNG_TRANSFORM_SHIFT)
-       && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
-   {
-      png_color_8p sig_bit;
-
-      png_get_sBIT(png_ptr, info_ptr, &sig_bit);
-      png_set_shift(png_ptr, sig_bit);
-   }
+   if ((transforms & PNG_TRANSFORM_SHIFT) && (info_ptr->valid & PNG_INFO_sBIT))
+      png_set_shift(png_ptr, &info_ptr->sig_bit);
 #endif
 
 #ifdef PNG_READ_BGR_SUPPORTED
    /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
    if (transforms & PNG_TRANSFORM_BGR)
       png_set_bgr(png_ptr);
 #endif
 
@@ -1200,22 +1259,21 @@ png_read_png(png_structrp png_ptr, png_i
 /* SIMPLIFIED READ
  *
  * This code currently relies on the sequential reader, though it could easily
  * be made to work with the progressive one.
  */
 /* Arguments to png_image_finish_read: */
 
 /* Encoding of PNG data (used by the color-map code) */
-/* TODO: change these, dang, ANSI-C reserves the 'E' namespace. */
-#  define E_NOTSET  0 /* File encoding not yet known */
-#  define E_sRGB    1 /* 8-bit encoded to sRGB gamma */
-#  define E_LINEAR  2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
-#  define E_FILE    3 /* 8-bit encoded to file gamma, not sRGB or linear */
-#  define E_LINEAR8 4 /* 8-bit linear: only from a file value */
+#  define P_NOTSET  0 /* File encoding not yet known */
+#  define P_sRGB    1 /* 8-bit encoded to sRGB gamma */
+#  define P_LINEAR  2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
+#  define P_FILE    3 /* 8-bit encoded to file gamma, not sRGB or linear */
+#  define P_LINEAR8 4 /* 8-bit linear: only from a file value */
 
 /* Color-map processing: after libpng has run on the PNG image further
  * processing may be needed to conver the data to color-map indicies.
  */
 #define PNG_CMAP_NONE      0
 #define PNG_CMAP_GA        1 /* Process GA data to a color-map with alpha */
 #define PNG_CMAP_TRANS     2 /* Process GA data to a background index */
 #define PNG_CMAP_RGB       3 /* Process RGB data */
@@ -1236,17 +1294,17 @@ typedef struct
    png_int_32 row_stride;
    png_voidp  colormap;
    png_const_colorp background;
    /* Local variables: */
    png_voidp       local_row;
    png_voidp       first_row;
    ptrdiff_t       row_bytes;           /* step between rows */
    int             file_encoding;       /* E_ values above */
-   png_fixed_point gamma_to_linear;     /* For E_FILE, reciprocal of gamma */
+   png_fixed_point gamma_to_linear;     /* For P_FILE, reciprocal of gamma */
    int             colormap_processing; /* PNG_CMAP_ values above */
 } png_image_read_control;
 
 /* Do all the *safe* initialization - 'safe' means that png_error won't be
  * called, so setting up the jmp_buf is not required.  This means that anything
  * called from here must *not* call png_malloc - it has to call png_malloc_warn
  * instead so that control is returned safely back to this routine.
  */
@@ -1368,17 +1426,17 @@ png_image_read_header(png_voidp argument
    {
       png_uint_32 format = png_image_format(png_ptr);
 
       image->format = format;
 
 #ifdef PNG_COLORSPACE_SUPPORTED
       /* Does the colorspace match sRGB?  If there is no color endpoint
        * (colorant) information assume yes, otherwise require the
-       * 'ENDPOINTS_MATCHE_sRGB' colorspace flag to have been set.  If the
+       * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set.  If the
        * colorspace has been determined to be invalid ignore it.
        */
       if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
          & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
             PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
          image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
 #endif
    }
@@ -1557,27 +1615,34 @@ png_image_skip_unused_chunks(png_structr
    /* Prepare the reader to ignore all recognized chunks whose data will not
     * be used, i.e., all chunks recognized by libpng except for those
     * involved in basic image reading:
     *
     *    IHDR, PLTE, IDAT, IEND
     *
     * Or image data handling:
     *
-    *    tRNS, bKGD, gAMA, cHRM, sRGB, iCCP and sBIT.
+    *    tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.
     *
     * This provides a small performance improvement and eliminates any
     * potential vulnerability to security problems in the unused chunks.
+    *
+    * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
+    * too.  This allows the simplified API to be compiled without iCCP support,
+    * however if the support is there the chunk is still checked to detect
+    * errors (which are unfortunately quite common.)
     */
    {
          static PNG_CONST png_byte chunks_to_process[] = {
             98,  75,  71,  68, '\0',  /* bKGD */
             99,  72,  82,  77, '\0',  /* cHRM */
            103,  65,  77,  65, '\0',  /* gAMA */
+#        ifdef PNG_READ_iCCP_SUPPORTED
            105,  67,  67,  80, '\0',  /* iCCP */
+#        endif
            115,  66,  73,  84, '\0',  /* sBIT */
            115,  82,  71,  66, '\0',  /* sRGB */
            };
 
        /* Ignore unknown chunks and all other chunks except for the
         * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
         */
        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
@@ -1604,54 +1669,54 @@ png_image_skip_unused_chunks(png_structr
 static void
 set_file_encoding(png_image_read_control *display)
 {
    png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
    if (png_gamma_significant(g))
    {
       if (png_gamma_not_sRGB(g))
       {
-         display->file_encoding = E_FILE;
+         display->file_encoding = P_FILE;
          display->gamma_to_linear = png_reciprocal(g);
       }
 
       else
-         display->file_encoding = E_sRGB;
+         display->file_encoding = P_sRGB;
    }
 
    else
-      display->file_encoding = E_LINEAR8;
+      display->file_encoding = P_LINEAR8;
 }
 
 static unsigned int
 decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
 {
-   if (encoding == E_FILE) /* double check */
+   if (encoding == P_FILE) /* double check */
       encoding = display->file_encoding;
 
-   if (encoding == E_NOTSET) /* must be the file encoding */
+   if (encoding == P_NOTSET) /* must be the file encoding */
    {
       set_file_encoding(display);
       encoding = display->file_encoding;
    }
 
    switch (encoding)
    {
-      case E_FILE:
+      case P_FILE:
          value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
          break;
 
-      case E_sRGB:
+      case P_sRGB:
          value = png_sRGB_table[value];
          break;
 
-      case E_LINEAR:
+      case P_LINEAR:
          break;
 
-      case E_LINEAR8:
+      case P_LINEAR8:
          value *= 257;
          break;
 
       default:
          png_error(display->image->opaque->png_ptr,
             "unexpected encoding (internal error)");
          break;
    }
@@ -1660,174 +1725,174 @@ decode_gamma(png_image_read_control *dis
 }
 
 static png_uint_32
 png_colormap_compose(png_image_read_control *display,
    png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
    png_uint_32 background, int encoding)
 {
    /* The file value is composed on the background, the background has the given
-    * encoding and so does the result, the file is encoded with E_FILE and the
+    * encoding and so does the result, the file is encoded with P_FILE and the
     * file and alpha are 8-bit values.  The (output) encoding will always be
-    * E_LINEAR or E_sRGB.
+    * P_LINEAR or P_sRGB.
     */
    png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
    png_uint_32 b = decode_gamma(display, background, encoding);
 
    /* The alpha is always an 8-bit value (it comes from the palette), the value
     * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
     */
    f = f * alpha + b * (255-alpha);
 
-   if (encoding == E_LINEAR)
+   if (encoding == P_LINEAR)
    {
       /* Scale to 65535; divide by 255, approximately (in fact this is extremely
        * accurate, it divides by 255.00000005937181414556, with no overflow.)
        */
       f *= 257; /* Now scaled by 65535 */
       f += f >> 16;
       f = (f+32768) >> 16;
    }
 
-   else /* E_sRGB */
+   else /* P_sRGB */
       f = PNG_sRGB_FROM_LINEAR(f);
 
    return f;
 }
 
-/* NOTE: E_LINEAR values to this routine must be 16-bit, but E_FILE values must
+/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must
  * be 8-bit.
  */
 static void
 png_create_colormap_entry(png_image_read_control *display,
    png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
    png_uint_32 alpha, int encoding)
 {
    png_imagep image = display->image;
    const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) ?
-      E_LINEAR : E_sRGB;
+      P_LINEAR : P_sRGB;
    const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
       (red != green || green != blue);
 
    if (ip > 255)
       png_error(image->opaque->png_ptr, "color-map index out of range");
 
    /* Update the cache with whether the file gamma is significantly different
     * from sRGB.
     */
-   if (encoding == E_FILE)
+   if (encoding == P_FILE)
    {
-      if (display->file_encoding == E_NOTSET)
+      if (display->file_encoding == P_NOTSET)
          set_file_encoding(display);
 
-      /* Note that the cached value may be E_FILE too, but if it is then the
+      /* Note that the cached value may be P_FILE too, but if it is then the
        * gamma_to_linear member has been set.
        */
       encoding = display->file_encoding;
    }
 
-   if (encoding == E_FILE)
+   if (encoding == P_FILE)
    {
       png_fixed_point g = display->gamma_to_linear;
 
       red = png_gamma_16bit_correct(red*257, g);
       green = png_gamma_16bit_correct(green*257, g);
       blue = png_gamma_16bit_correct(blue*257, g);
 
-      if (convert_to_Y || output_encoding == E_LINEAR)
+      if (convert_to_Y || output_encoding == P_LINEAR)
       {
          alpha *= 257;
-         encoding = E_LINEAR;
+         encoding = P_LINEAR;
       }
 
       else
       {
          red = PNG_sRGB_FROM_LINEAR(red * 255);
          green = PNG_sRGB_FROM_LINEAR(green * 255);
          blue = PNG_sRGB_FROM_LINEAR(blue * 255);
-         encoding = E_sRGB;
+         encoding = P_sRGB;
       }
    }
 
-   else if (encoding == E_LINEAR8)
+   else if (encoding == P_LINEAR8)
    {
       /* This encoding occurs quite frequently in test cases because PngSuite
        * includes a gAMA 1.0 chunk with most images.
        */
       red *= 257;
       green *= 257;
       blue *= 257;
       alpha *= 257;
-      encoding = E_LINEAR;
+      encoding = P_LINEAR;
    }
 
-   else if (encoding == E_sRGB && (convert_to_Y || output_encoding == E_LINEAR))
+   else if (encoding == P_sRGB && (convert_to_Y || output_encoding == P_LINEAR))
    {
       /* The values are 8-bit sRGB values, but must be converted to 16-bit
        * linear.
        */
       red = png_sRGB_table[red];
       green = png_sRGB_table[green];
       blue = png_sRGB_table[blue];
       alpha *= 257;
-      encoding = E_LINEAR;
+      encoding = P_LINEAR;
    }
 
    /* This is set if the color isn't gray but the output is. */
-   if (encoding == E_LINEAR)
+   if (encoding == P_LINEAR)
    {
       if (convert_to_Y)
       {
          /* NOTE: these values are copied from png_do_rgb_to_gray */
          png_uint_32 y = (png_uint_32)6968 * red  + (png_uint_32)23434 * green +
             (png_uint_32)2366 * blue;
 
-         if (output_encoding == E_LINEAR)
+         if (output_encoding == P_LINEAR)
             y = (y + 16384) >> 15;
 
          else
          {
             /* y is scaled by 32768, we need it scaled by 255: */
             y = (y + 128) >> 8;
             y *= 255;
             y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
-            encoding = E_sRGB;
+            encoding = P_sRGB;
          }
 
          blue = red = green = y;
       }
 
-      else if (output_encoding == E_sRGB)
+      else if (output_encoding == P_sRGB)
       {
          red = PNG_sRGB_FROM_LINEAR(red * 255);
          green = PNG_sRGB_FROM_LINEAR(green * 255);
          blue = PNG_sRGB_FROM_LINEAR(blue * 255);
          alpha = PNG_DIV257(alpha);
-         encoding = E_sRGB;
+         encoding = P_sRGB;
       }
    }
 
    if (encoding != output_encoding)
       png_error(image->opaque->png_ptr, "bad encoding (internal error)");
 
    /* Store the value. */
    {
-#     ifdef PNG_FORMAT_BGR_SUPPORTED
+#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
          const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
             (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
 #     else
 #        define afirst 0
 #     endif
 #     ifdef PNG_FORMAT_BGR_SUPPORTED
          const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
 #     else
 #        define bgr 0
 #     endif
 
-      if (output_encoding == E_LINEAR)
+      if (output_encoding == P_LINEAR)
       {
          png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
 
          entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
 
          /* The linear 16-bit values must be pre-multiplied by the alpha channel
           * value, if less than 65535 (this is, effectively, composite on black
           * if the alpha channel is removed.)
@@ -1872,17 +1937,17 @@ png_create_colormap_entry(png_image_read
                entry[afirst] = (png_uint_16)green;
                break;
 
             default:
                break;
          }
       }
 
-      else /* output encoding is E_sRGB */
+      else /* output encoding is P_sRGB */
       {
          png_bytep entry = png_voidcast(png_bytep, display->colormap);
 
          entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
 
          switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
          {
             case 4:
@@ -1914,28 +1979,28 @@ png_create_colormap_entry(png_image_read
 }
 
 static int
 make_gray_file_colormap(png_image_read_control *display)
 {
    unsigned int i;
 
    for (i=0; i<256; ++i)
-      png_create_colormap_entry(display, i, i, i, i, 255, E_FILE);
+      png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
 
    return i;
 }
 
 static int
 make_gray_colormap(png_image_read_control *display)
 {
    unsigned int i;
 
    for (i=0; i<256; ++i)
-      png_create_colormap_entry(display, i, i, i, i, 255, E_sRGB);
+      png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
 
    return i;
 }
 #define PNG_GRAY_COLORMAP_ENTRIES 256
 
 static int
 make_ga_colormap(png_image_read_control *display)
 {
@@ -1964,31 +2029,31 @@ make_ga_colormap(png_image_read_control 
     *    base = 226 + 6 * PNG_DIV51(alpha);
     *    entry = PNG_DIV51(gray);
     * }
     */
    i = 0;
    while (i < 231)
    {
       unsigned int gray = (i * 256 + 115) / 231;
-      png_create_colormap_entry(display, i++, gray, gray, gray, 255, E_sRGB);
+      png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);
    }
 
    /* 255 is used here for the component values for consistency with the code
     * that undoes premultiplication in pngwrite.c.
     */
-   png_create_colormap_entry(display, i++, 255, 255, 255, 0, E_sRGB);
+   png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);
 
    for (a=1; a<5; ++a)
    {
       unsigned int g;
 
       for (g=0; g<6; ++g)
          png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
-            E_sRGB);
+            P_sRGB);
    }
 
    return i;
 }
 
 #define PNG_GA_COLORMAP_ENTRIES 256
 
 static int
@@ -2002,17 +2067,17 @@ make_rgb_colormap(png_image_read_control
       unsigned int g;
 
       for (g=0; g<6; ++g)
       {
          unsigned int b;
 
          for (b=0; b<6; ++b)
             png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
-               E_sRGB);
+               P_sRGB);
       }
    }
 
    return i;
 }
 
 #define PNG_RGB_COLORMAP_ENTRIES 216
 
@@ -2025,21 +2090,21 @@ png_image_read_colormap(png_voidp argume
 {
    png_image_read_control *display =
       png_voidcast(png_image_read_control*, argument);
    const png_imagep image = display->image;
 
    const png_structrp png_ptr = image->opaque->png_ptr;
    const png_uint_32 output_format = image->format;
    const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) ?
-      E_LINEAR : E_sRGB;
+      P_LINEAR : P_sRGB;
 
    unsigned int cmap_entries;
    unsigned int output_processing;        /* Output processing option */
-   unsigned int data_encoding = E_NOTSET; /* Encoding libpng must produce */
+   unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */
 
    /* Background information; the background color and the index of this color
     * in the color-map if it exists (else 256).
     */
    unsigned int background_index = 256;
    png_uint_32 back_r, back_g, back_b;
 
    /* Flags to accumulate things that need to be done to the input. */
@@ -2049,17 +2114,17 @@ png_image_read_colormap(png_voidp argume
     * very difficult to do, the results look awful, and it is difficult to see
     * what possible use it is because the application can't control the
     * color-map.
     */
    if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||
          png_ptr->num_trans > 0) /* alpha in input */ &&
       ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
    {
-      if (output_encoding == E_LINEAR) /* compose on black */
+      if (output_encoding == P_LINEAR) /* compose on black */
          back_b = back_g = back_r = 0;
 
       else if (display->background == NULL /* no way to remove it */)
          png_error(png_ptr,
             "a background color must be supplied to remove alpha/transparency");
 
       /* Get a copy of the background color (this avoids repeating the checks
        * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
@@ -2073,17 +2138,17 @@ png_image_read_colormap(png_voidp argume
             back_r = display->background->red;
             back_b = display->background->blue;
          }
          else
             back_b = back_r = back_g;
       }
    }
 
-   else if (output_encoding == E_LINEAR)
+   else if (output_encoding == P_LINEAR)
       back_b = back_r = back_g = 65535;
 
    else
       back_b = back_r = back_g = 255;
 
    /* Default the input file gamma if required - this is necessary because
     * libpng assumes that if no gamma information is present the data is in the
     * output format, but the simplified API deduces the gamma from the input
@@ -2131,17 +2196,17 @@ png_image_read_colormap(png_voidp argume
             /* If there is a tRNS chunk then this either selects a transparent
              * value or, if the output has no alpha, the background color.
              */
             if (png_ptr->num_trans > 0)
             {
                trans = png_ptr->trans_color.gray;
 
                if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
-                  back_alpha = output_encoding == E_LINEAR ? 65535 : 255;
+                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
             }
 
             /* png_create_colormap_entry just takes an RGBA and writes the
              * corresponding color-map entry using the format from 'image',
              * including the required conversion to sRGB or linear as
              * appropriate.  The input values are always either sRGB (if the
              * gamma correction flag is 0) or 0..255 scaled file encoded values
              * (if the function must gamma correct them).
@@ -2149,33 +2214,33 @@ png_image_read_colormap(png_voidp argume
             for (i=val=0; i<cmap_entries; ++i, val += step)
             {
                /* 'i' is a file value.  While this will result in duplicated
                 * entries for 8-bit non-sRGB encoded files it is necessary to
                 * have non-gamma corrected values to do tRNS handling.
                 */
                if (i != trans)
                   png_create_colormap_entry(display, i, val, val, val, 255,
-                     E_FILE/*8-bit with file gamma*/);
+                     P_FILE/*8-bit with file gamma*/);
 
                /* Else this entry is transparent.  The colors don't matter if
                 * there is an alpha channel (back_alpha == 0), but it does no
                 * harm to pass them in; the values are not set above so this
                 * passes in white.
                 *
                 * NOTE: this preserves the full precision of the application
                 * supplied background color when it is used.
                 */
                else
                   png_create_colormap_entry(display, i, back_r, back_g, back_b,
                      back_alpha, output_encoding);
             }
 
             /* We need libpng to preserve the original encoding. */
-            data_encoding = E_FILE;
+            data_encoding = P_FILE;
 
             /* The rows from libpng, while technically gray values, are now also
              * color-map indicies; however, they may need to be expanded to 1
              * byte per pixel.  This is what png_set_packing does (i.e., it
              * unpacks the bit values into bytes.)
              */
             if (png_ptr->bit_depth < 8)
                png_set_packing(png_ptr);
@@ -2194,17 +2259,17 @@ png_image_read_colormap(png_voidp argume
              * this means libpng must handle it too; otherwise it is impossible
              * to do the exact match on the 16-bit value.
              *
              * If the output has no alpha channel *and* the background color is
              * gray then it is possible to let libpng handle the substitution by
              * ensuring that the corresponding gray level matches the background
              * color exactly.
              */
-            data_encoding = E_sRGB;
+            data_encoding = P_sRGB;
 
             if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray[16] color-map: too few entries");
 
             cmap_entries = make_gray_colormap(display);
 
             if (png_ptr->num_trans > 0)
             {
@@ -2218,25 +2283,25 @@ png_image_read_colormap(png_voidp argume
                   if (back_r == back_g && back_g == back_b)
                   {
                      /* Background is gray; no special processing will be
                       * required.
                       */
                      png_color_16 c;
                      png_uint_32 gray = back_g;
 
-                     if (output_encoding == E_LINEAR)
+                     if (output_encoding == P_LINEAR)
                      {
                         gray = PNG_sRGB_FROM_LINEAR(gray * 255);
 
                         /* And make sure the corresponding palette entry
                          * matches.
                          */
                         png_create_colormap_entry(display, gray, back_g, back_g,
-                           back_g, 65535, E_LINEAR);
+                           back_g, 65535, P_LINEAR);
                      }
 
                      /* The background passed to libpng, however, must be the
                       * sRGB value.
                       */
                      c.index = 0; /*unused*/
                      c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
 
@@ -2247,17 +2312,17 @@ png_image_read_colormap(png_voidp argume
                      png_set_background_fixed(png_ptr, &c,
                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
                         0/*gamma: not used*/);
 
                      output_processing = PNG_CMAP_NONE;
                      break;
                   }
 
-                  back_alpha = output_encoding == E_LINEAR ? 65535 : 255;
+                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
                }
 
                /* output_processing means that the libpng-processed row will be
                 * 8-bit GA and it has to be processing to single byte color-map
                 * values.  Entry 254 is replaced by either a completely
                 * transparent entry or by the background color at full
                 * precision (and the background color is not a simple gray leve
                 * in this case.)
@@ -2284,17 +2349,17 @@ png_image_read_colormap(png_voidp argume
           * removed there are only 256 possibilities if the background is gray.
           * (Otherwise there is a subset of the 65536 possibilities defined by
           * the triangle between black, white and the background color.)
           *
           * Reduce 16-bit files to 8-bit and sRGB encode the result.  No need to
           * worry about tRNS matching - tRNS is ignored if there is an alpha
           * channel.
           */
-         data_encoding = E_sRGB;
+         data_encoding = P_sRGB;
 
          if (output_format & PNG_FORMAT_FLAG_ALPHA)
          {
             if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                png_error(png_ptr, "gray+alpha color-map: too few entries");
 
             cmap_entries = make_ga_colormap(display);
 
@@ -2327,23 +2392,23 @@ png_image_read_colormap(png_voidp argume
                png_color_16 c;
                png_uint_32 gray = back_g;
 
                if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "gray-alpha color-map: too few entries");
 
                cmap_entries = make_gray_colormap(display);
 
-               if (output_encoding == E_LINEAR)
+               if (output_encoding == P_LINEAR)
                {
                   gray = PNG_sRGB_FROM_LINEAR(gray * 255);
 
                   /* And make sure the corresponding palette entry matches. */
                   png_create_colormap_entry(display, gray, back_g, back_g,
-                     back_g, 65535, E_LINEAR);
+                     back_g, 65535, P_LINEAR);
                }
 
                /* The background passed to libpng, however, must be the sRGB
                 * value.
                 */
                c.index = 0; /*unused*/
                c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
 
@@ -2364,35 +2429,35 @@ png_image_read_colormap(png_voidp argume
                if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
                   png_error(png_ptr, "ga-alpha color-map: too few entries");
 
                i = 0;
                while (i < 231)
                {
                   png_uint_32 gray = (i * 256 + 115) / 231;
                   png_create_colormap_entry(display, i++, gray, gray, gray,
-                     255, E_sRGB);
+                     255, P_sRGB);
                }
 
                /* NOTE: this preserves the full precision of the application
                 * background color.
                 */
                background_index = i;
                png_create_colormap_entry(display, i++, back_r, back_g, back_b,
-                  output_encoding == E_LINEAR ? 65535U : 255U, output_encoding);
+                  output_encoding == P_LINEAR ? 65535U : 255U, output_encoding);
 
                /* For non-opaque input composite on the sRGB background - this
                 * requires inverting the encoding for each component.  The input
                 * is still converted to the sRGB encoding because this is a
                 * reasonable approximate to the logarithmic curve of human
                 * visual sensitivity, at least over the narrow range which PNG
                 * represents.  Consequently 'G' is always sRGB encoded, while
                 * 'A' is linear.  We need the linear background colors.
                 */
-               if (output_encoding == E_sRGB) /* else already linear */
+               if (output_encoding == P_sRGB) /* else already linear */
                {
                   /* This may produce a value not exactly matching the
                    * background, but that's ok because these numbers are only
                    * used when alpha != 0
                    */
                   back_r = png_sRGB_table[back_r];
                   back_g = png_sRGB_table[back_g];
                   back_b = png_sRGB_table[back_b];
@@ -2412,17 +2477,17 @@ png_image_read_colormap(png_voidp argume
 
                   for (g=0; g<6; ++g)
                   {
                      png_uint_32 gray = png_sRGB_table[g*51] * alpha;
 
                      png_create_colormap_entry(display, i++,
                         PNG_sRGB_FROM_LINEAR(gray + back_rx),
                         PNG_sRGB_FROM_LINEAR(gray + back_gx),
-                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, E_sRGB);
+                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
                   }
                }
 
                cmap_entries = i;
                output_processing = PNG_CMAP_GA;
             }
          }
          break;
@@ -2439,17 +2504,17 @@ png_image_read_colormap(png_voidp argume
              * code above.
              *
              * NOTE: calling this apparently damages the recognition of the
              * transparent color in background color handling; call
              * png_set_tRNS_to_alpha before png_set_background_fixed.
              */
             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
                -1);
-            data_encoding = E_sRGB;
+            data_encoding = P_sRGB;
 
             /* The output will now be one or two 8-bit gray or gray+alpha
              * channels.  The more complex case arises when the input has alpha.
              */
             if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
                png_ptr->num_trans > 0) &&
                (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
             {
@@ -2484,17 +2549,17 @@ png_image_read_colormap(png_voidp argume
                 * duplicate palette entries, but that's better than the
                 * alternative of double gamma correction.
                 */
                if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
                   png_ptr->num_trans > 0) &&
                   png_gamma_not_sRGB(png_ptr->colorspace.gamma))
                {
                   cmap_entries = make_gray_file_colormap(display);
-                  data_encoding = E_FILE;
+                  data_encoding = P_FILE;
                }
 
                else
                   cmap_entries = make_gray_colormap(display);
 
                /* But if the input has alpha or transparency it must be removed
                 */
                if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
@@ -2503,44 +2568,44 @@ png_image_read_colormap(png_voidp argume
                   png_color_16 c;
                   png_uint_32 gray = back_g;
 
                   /* We need to ensure that the application background exists in
                    * the colormap and that completely transparent pixels map to
                    * it.  Achieve this simply by ensuring that the entry
                    * selected for the background really is the background color.
                    */
-                  if (data_encoding == E_FILE) /* from the fixup above */
+                  if (data_encoding == P_FILE) /* from the fixup above */
                   {
                      /* The app supplied a gray which is in output_encoding, we
-                      * need to convert it to a value of the input (E_FILE)
+                      * need to convert it to a value of the input (P_FILE)
                       * encoding then set this palette entry to the required
                       * output encoding.
                       */
-                     if (output_encoding == E_sRGB)
-                        gray = png_sRGB_table[gray]; /* now E_LINEAR */
+                     if (output_encoding == P_sRGB)
+                        gray = png_sRGB_table[gray]; /* now P_LINEAR */
 
                      gray = PNG_DIV257(png_gamma_16bit_correct(gray,
-                        png_ptr->colorspace.gamma)); /* now E_FILE */
+                        png_ptr->colorspace.gamma)); /* now P_FILE */
 
                      /* And make sure the corresponding palette entry contains
                       * exactly the required sRGB value.
                       */
                      png_create_colormap_entry(display, gray, back_g, back_g,
                         back_g, 0/*unused*/, output_encoding);
                   }
 
-                  else if (output_encoding == E_LINEAR)
+                  else if (output_encoding == P_LINEAR)
                   {
                      gray = PNG_sRGB_FROM_LINEAR(gray * 255);
 
                      /* And make sure the corresponding palette entry matches.
                       */
                      png_create_colormap_entry(display, gray, back_g, back_g,
-                        back_g, 0/*unused*/, E_LINEAR);
+                        back_g, 0/*unused*/, P_LINEAR);
                   }
 
                   /* The background passed to libpng, however, must be the
                    * output (normally sRGB) value.
                    */
                   c.index = 0; /*unused*/
                   c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
 
@@ -2560,17 +2625,17 @@ png_image_read_colormap(png_voidp argume
 
          else /* output is color */
          {
             /* We could use png_quantize here so long as there is no transparent
              * color or alpha; png_quantize ignores alpha.  Easier overall just
              * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
              * Consequently we always want libpng to produce sRGB data.
              */
-            data_encoding = E_sRGB;
+            data_encoding = P_sRGB;
 
             /* Is there any transparency or alpha? */
             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
                png_ptr->num_trans > 0)
             {
                /* Is there alpha in the output too?  If so all four channels are
                 * processed into a special RGB cube with alpha support.
                 */
@@ -2580,17 +2645,17 @@ png_image_read_colormap(png_voidp argume
 
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb+alpha color-map: too few entries");
 
                   cmap_entries = make_rgb_colormap(display);
 
                   /* Add a transparent entry. */
                   png_create_colormap_entry(display, cmap_entries, 255, 255,
-                     255, 0, E_sRGB);
+                     255, 0, P_sRGB);
 
                   /* This is stored as the background index for the processing
                    * algorithm.
                    */
                   background_index = cmap_entries++;
 
                   /* Add 27 r,g,b entries each with alpha 0.5. */
                   for (r=0; r<256; r = (r << 1) | 0x7f)
@@ -2601,17 +2666,17 @@ png_image_read_colormap(png_voidp argume
                      {
                         png_uint_32 b;
 
                         /* This generates components with the values 0, 127 and
                          * 255
                          */
                         for (b=0; b<256; b = (b << 1) | 0x7f)
                            png_create_colormap_entry(display, cmap_entries++,
-                              r, g, b, 128, E_sRGB);
+                              r, g, b, 128, P_sRGB);
                      }
                   }
 
                   expand_tRNS = 1;
                   output_processing = PNG_CMAP_RGB_ALPHA;
                }
 
                else
@@ -2630,17 +2695,17 @@ png_image_read_colormap(png_voidp argume
                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
                      png_error(png_ptr, "rgb-alpha color-map: too few entries");
 
                   cmap_entries = make_rgb_colormap(display);
 
                   png_create_colormap_entry(display, cmap_entries, back_r,
                         back_g, back_b, 0/*unused*/, output_encoding);
 
-                  if (output_encoding == E_LINEAR)
+                  if (output_encoding == P_LINEAR)
                   {
                      r = PNG_sRGB_FROM_LINEAR(back_r * 255);
                      g = PNG_sRGB_FROM_LINEAR(back_g * 255);
                      b = PNG_sRGB_FROM_LINEAR(back_b * 255);
                   }
 
                   else
                   {
@@ -2670,21 +2735,21 @@ png_image_read_colormap(png_voidp argume
                      {
                         for (g=0; g<256; g = (g << 1) | 0x7f)
                         {
                            /* This generates components with the values 0, 127
                             * and 255
                             */
                            for (b=0; b<256; b = (b << 1) | 0x7f)
                               png_create_colormap_entry(display, cmap_entries++,
-                                 png_colormap_compose(display, r, E_sRGB, 128,
+                                 png_colormap_compose(display, r, P_sRGB, 128,
                                     back_r, output_encoding),
-                                 png_colormap_compose(display, g, E_sRGB, 128,
+                                 png_colormap_compose(display, g, P_sRGB, 128,
                                     back_g, output_encoding),
-                                 png_colormap_compose(display, b, E_sRGB, 128,
+                                 png_colormap_compose(display, b, P_sRGB, 128,
                                     back_b, output_encoding),
                                  0/*unused*/, output_encoding);
                         }
                      }
 
                      expand_tRNS = 1;
                      output_processing = PNG_CMAP_RGB_ALPHA;
                   }
@@ -2733,17 +2798,17 @@ png_image_read_colormap(png_voidp argume
                (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
             unsigned int i;
 
             /* Just in case: */
             if (trans == NULL)
                num_trans = 0;
 
             output_processing = PNG_CMAP_NONE;
-            data_encoding = E_FILE; /* Don't change from color-map indicies */
+            data_encoding = P_FILE; /* Don't change from color-map indicies */
             cmap_entries = png_ptr->num_palette;
             if (cmap_entries > 256)
                cmap_entries = 256;
 
             if (cmap_entries > image->colormap_entries)
                png_error(png_ptr, "palette color-map: too few entries");
 
             for (i=0; i < cmap_entries; ++i)
@@ -2755,32 +2820,32 @@ png_image_read_colormap(png_voidp argume
                         back_b, 0, output_encoding);
 
                   else
                   {
                      /* Must compose the PNG file color in the color-map entry
                       * on the sRGB color in 'back'.
                       */
                      png_create_colormap_entry(display, i,
-                        png_colormap_compose(display, colormap[i].red, E_FILE,
+                        png_colormap_compose(display, colormap[i].red, P_FILE,
                            trans[i], back_r, output_encoding),
-                        png_colormap_compose(display, colormap[i].green, E_FILE,
+                        png_colormap_compose(display, colormap[i].green, P_FILE,
                            trans[i], back_g, output_encoding),
-                        png_colormap_compose(display, colormap[i].blue, E_FILE,
+                        png_colormap_compose(display, colormap[i].blue, P_FILE,
                            trans[i], back_b, output_encoding),
-                        output_encoding == E_LINEAR ? trans[i] * 257U :
+                        output_encoding == P_LINEAR ? trans[i] * 257U :
                            trans[i],
                         output_encoding);
                   }
                }
 
                else
                   png_create_colormap_entry(display, i, colormap[i].red,
                      colormap[i].green, colormap[i].blue,
-                     i < num_trans ? trans[i] : 255U, E_FILE/*8-bit*/);
+                     i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
             }
 
             /* The PNG data may have indicies packed in fewer than 8 bits, it
              * must be expanded if so.
              */
             if (png_ptr->bit_depth < 8)
                png_set_packing(png_ptr);
          }
@@ -2798,22 +2863,22 @@ png_image_read_colormap(png_voidp argume
       png_set_tRNS_to_alpha(png_ptr);
 
    switch (data_encoding)
    {
       default:
          png_error(png_ptr, "bad data option (internal error)");
          break;
 
-      case E_sRGB:
+      case P_sRGB:
          /* Change to 8-bit sRGB */
          png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
          /* FALL THROUGH */
 
-      case E_FILE:
+      case P_FILE:
          if (png_ptr->bit_depth > 8)
             png_set_scale_16(png_ptr);
          break;
    }
 
    if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
       png_error(png_ptr, "color map overflow (BAD internal error)");
 
@@ -2880,17 +2945,16 @@ png_image_read_and_map(png_voidp argumen
          passes = 1;
          break;
 
       case PNG_INTERLACE_ADAM7:
          passes = PNG_INTERLACE_ADAM7_PASSES;
          break;
 
       default:
-         passes = 0;
          png_error(png_ptr, "unknown interlace type");
    }
 
    {
       png_uint_32  height = image->height;
       png_uint_32  width = image->width;
       int          proc = display->colormap_processing;
       png_bytep    first_row = png_voidcast(png_bytep, display->first_row);
@@ -3199,17 +3263,16 @@ png_image_read_composite(png_voidp argum
          passes = 1;
          break;
 
       case PNG_INTERLACE_ADAM7:
          passes = PNG_INTERLACE_ADAM7_PASSES;
          break;
 
       default:
-         passes = 0;
          png_error(png_ptr, "unknown interlace type");
    }
 
    {
       png_uint_32  height = image->height;
       png_uint_32  width = image->width;
       ptrdiff_t    step_row = display->row_bytes;
       unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
@@ -3348,21 +3411,25 @@ png_image_read_background(png_voidp argu
          passes = 1;
          break;
 
       case PNG_INTERLACE_ADAM7:
          passes = PNG_INTERLACE_ADAM7_PASSES;
          break;
 
       default:
-         passes = 0;
          png_error(png_ptr, "unknown interlace type");
    }
 
-   switch (png_get_bit_depth(png_ptr, info_ptr))
+   /* Use direct access to info_ptr here because otherwise the simplified API
+    * would require PNG_EASY_ACCESS_SUPPORTED (just for this.)  Note this is
+    * checking the value after libpng expansions, not the original value in the
+    * PNG.
+    */
+   switch (info_ptr->bit_depth)
    {
       default:
          png_error(png_ptr, "unexpected bit depth");
          break;
 
       case 8:
          /* 8-bit sRGB gray values with an alpha channel; the alpha channel is
           * to be removed by composing on a background: either the row if
@@ -3500,18 +3567,20 @@ png_image_read_background(png_voidp argu
             /* The division by two is safe because the caller passed in a
              * stride which was multiplied by 2 (below) to get row_bytes.
              */
             ptrdiff_t    step_row = display->row_bytes / 2;
             int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
             unsigned int outchannels = 1+preserve_alpha;
             int swap_alpha = 0;
 
-            if (preserve_alpha && (image->format & PNG_FORMAT_FLAG_AFIRST))
-               swap_alpha = 1;
+#           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+               if (preserve_alpha && (image->format & PNG_FORMAT_FLAG_AFIRST))
+                  swap_alpha = 1;
+#           endif
 
             for (pass = 0; pass < passes; ++pass)
             {
                unsigned int     startx, stepx, stepy;
                png_uint_32      y;
 
                /* The 'x' start and step are adjusted to output components here.
                 */
--- a/media/libpng/pngrio.c
+++ b/media/libpng/pngrio.c
@@ -1,13 +1,13 @@
 
 /* pngrio.c - functions for data input
  *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
  * This file provides a location for all input.  Users who need
@@ -97,22 +97,24 @@ png_set_read_fn(png_structrp png_ptr, pn
       png_ptr->read_data_fn = read_data_fn;
 
    else
       png_ptr->read_data_fn = png_default_read_data;
 #else
    png_ptr->read_data_fn = read_data_fn;
 #endif
 
+#ifdef PNG_WRITE_SUPPORTED
    /* It is an error to write to a read device */
    if (png_ptr->write_data_fn != NULL)
    {
       png_ptr->write_data_fn = NULL;
       png_warning(png_ptr,
           "Can't set both read_data_fn and write_data_fn in the"
           " same structure");
    }
+#endif
 
 #ifdef PNG_WRITE_FLUSH_SUPPORTED
    png_ptr->output_flush_fn = NULL;
 #endif
 }
 #endif /* PNG_READ_SUPPORTED */
--- a/media/libpng/pngrtran.c
+++ b/media/libpng/pngrtran.c
@@ -1,13 +1,13 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * Last changed in libpng 1.6.4 [August 21, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
  * This file contains functions optionally called by an application
@@ -1129,17 +1129,17 @@ png_init_palette_transformations(png_str
          }
       }
    }
 
    /* If no alpha we can optimize. */
    if (!input_has_alpha)
    {
       /* Any alpha means background and associative alpha processing is
-       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
+       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
        * and ENCODE_ALPHA are irrelevant.
        */
       png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
 
       if (!input_has_transparency)
          png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
    }
@@ -1194,17 +1194,17 @@ png_init_rgb_transformations(png_structr
     */
    int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
    int input_has_transparency = png_ptr->num_trans > 0;
 
    /* If no alpha we can optimize. */
    if (!input_has_alpha)
    {
       /* Any alpha means background and associative alpha processing is
-       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
+       * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
        * and ENCODE_ALPHA are irrelevant.
        */
 #     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
 #     endif
 
       if (!input_has_transparency)
@@ -1937,16 +1937,19 @@ png_read_transform_info(png_structrp png
          if (png_ptr->num_trans > 0)
             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
 
          else
             info_ptr->color_type = PNG_COLOR_TYPE_RGB;
 
          info_ptr->bit_depth = 8;
          info_ptr->num_trans = 0;
+
+         if (png_ptr->palette == NULL)
+            png_error (png_ptr, "Palette is NULL in indexed image");
       }
       else
       {
          if (png_ptr->num_trans)
          {
             if (png_ptr->transformations & PNG_EXPAND_tRNS)
                info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
          }
@@ -2115,321 +2118,24 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTE
    png_ptr->info_rowbytes = info_ptr->rowbytes;
 
 #ifndef PNG_READ_EXPAND_SUPPORTED
    if (png_ptr)
       return;
 #endif
 }
 
-/* Transform the row.  The order of transformations is significant,
- * and is very touchy.  If you add a transformation, take care to
- * decide how it fits in with the other transformations here.
- */
-void /* PRIVATE */
-png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
-{
-   png_debug(1, "in png_do_read_transformations");
-
-   if (png_ptr->row_buf == NULL)
-   {
-      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
-       * error is incredibly rare and incredibly easy to debug without this
-       * information.
-       */
-      png_error(png_ptr, "NULL row buffer");
-   }
-
-   /* The following is debugging; prior to 1.5.4 the code was never compiled in;
-    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
-    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
-    * all transformations, however in practice the ROW_INIT always gets done on
-    * demand, if necessary.
-    */
-   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
-      !(png_ptr->flags & PNG_FLAG_ROW_INIT))
-   {
-      /* Application has failed to call either png_read_start_image() or
-       * png_read_update_info() after setting transforms that expand pixels.
-       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
-       */
-      png_error(png_ptr, "Uninitialized row");
-   }
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
-   if (png_ptr->transformations & PNG_EXPAND)
-   {
-      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
-             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
-      }
-
-      else
-      {
-         if (png_ptr->num_trans &&
-             (png_ptr->transformations & PNG_EXPAND_tRNS))
-            png_do_expand(row_info, png_ptr->row_buf + 1,
-                &(png_ptr->trans_color));
-
-         else
-            png_do_expand(row_info, png_ptr->row_buf + 1,
-                NULL);
-      }
-   }
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
-      !(png_ptr->transformations & PNG_COMPOSE) &&
-      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
-      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
-      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         0 /* at_start == false, because SWAP_ALPHA happens later */);
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
-   {
-      int rgb_error =
-          png_do_rgb_to_gray(png_ptr, row_info,
-              png_ptr->row_buf + 1);
-
-      if (rgb_error)
-      {
-         png_ptr->rgb_to_gray_status=1;
-         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
-             PNG_RGB_TO_GRAY_WARN)
-            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
-
-         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
-             PNG_RGB_TO_GRAY_ERR)
-            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
-      }
-   }
-#endif
-
-/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
- *
- *   In most cases, the "simple transparency" should be done prior to doing
- *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
- *   pixel is transparent.  You would also need to make sure that the
- *   transparency information is upgraded to RGB.
- *
- *   To summarize, the current flow is:
- *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
- *                                   with background "in place" if transparent,
- *                                   convert to RGB if necessary
- *   - Gray + alpha -> composite with gray background and remove alpha bytes,
- *                                   convert to RGB if necessary
- *
- *   To support RGB backgrounds for gray images we need:
- *   - Gray + simple transparency -> convert to RGB + simple transparency,
- *                                   compare 3 or 6 bytes and composite with
- *                                   background "in place" if transparent
- *                                   (3x compare/pixel compared to doing
- *                                   composite with gray bkgrnd)
- *   - Gray + alpha -> convert to RGB + alpha, composite with background and
- *                                   remove alpha bytes (3x float
- *                                   operations/pixel compared with composite
- *                                   on gray background)
- *
- *  Greg's change will do this.  The reason it wasn't done before is for
- *  performance, as this increases the per-pixel operations.  If we would check
- *  in advance if the background was gray or RGB, and position the gray-to-RGB
- *  transform appropriately, then it would save a lot of work/time.
- */
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-   /* If gray -> RGB, do so now only if background is non-gray; else do later
-    * for performance reasons
-    */
-   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
-       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
-      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-   if (png_ptr->transformations & PNG_COMPOSE)
-      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
-   if ((png_ptr->transformations & PNG_GAMMA) &&
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-      /* Because RGB_TO_GRAY does the gamma transform. */
-      !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&
-#endif
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
-   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
-      /* Because PNG_COMPOSE does the gamma transform if there is something to
-       * do (if there is an alpha channel or transparency.)
-       */
-       !((png_ptr->transformations & PNG_COMPOSE) &&
-       ((png_ptr->num_trans != 0) ||
-       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
-#endif
-      /* Because png_init_read_transformations transforms the palette, unless
-       * RGB_TO_GRAY will do the transform.
-       */
-       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
-      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
-      (png_ptr->transformations & PNG_COMPOSE) &&
-      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
-      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
-      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         0 /* at_start == false, because SWAP_ALPHA happens later */);
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
-      (row_info->color_type & PNG_COLOR_MASK_ALPHA))
-      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
-   if (png_ptr->transformations & PNG_SCALE_16_TO_8)
-      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-   /* There is no harm in doing both of these because only one has any effect,
-    * by putting the 'scale' option first if the app asks for scale (either by
-    * calling the API or in a TRANSFORM flag) this is what happens.
-    */
-   if (png_ptr->transformations & PNG_16_TO_8)
-      png_do_chop(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
-   if (png_ptr->transformations & PNG_QUANTIZE)
-   {
-      png_do_quantize(row_info, png_ptr->row_buf + 1,
-          png_ptr->palette_lookup, png_ptr->quantize_index);
-
-      if (row_info->rowbytes == 0)
-         png_error(png_ptr, "png_do_quantize returned rowbytes=0");
-   }
-#endif /* PNG_READ_QUANTIZE_SUPPORTED */
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
-   /* Do the expansion now, after all the arithmetic has been done.  Notice
-    * that previous transformations can handle the PNG_EXPAND_16 flag if this
-    * is efficient (particularly true in the case of gamma correction, where
-    * better accuracy results faster!)
-    */
-   if (png_ptr->transformations & PNG_EXPAND_16)
-      png_do_expand_16(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
-   /* NOTE: moved here in 1.5.4 (from much later in this list.) */
-   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
-       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
-      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_INVERT_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_MONO)
-      png_do_invert(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
-   if (png_ptr->transformations & PNG_SHIFT)
-      png_do_unshift(row_info, png_ptr->row_buf + 1,
-          &(png_ptr->shift));
-#endif
-
-#ifdef PNG_READ_PACK_SUPPORTED
-   if (png_ptr->transformations & PNG_PACK)
-      png_do_unpack(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
-   /* Added at libpng-1.5.10 */
-   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
-       png_ptr->num_palette_max >= 0)
-      png_do_check_palette_indexes(png_ptr, row_info);
-#endif
-
-#ifdef PNG_READ_BGR_SUPPORTED
-   if (png_ptr->transformations & PNG_BGR)
-      png_do_bgr(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_PACKSWAP)
-      png_do_packswap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_FILLER_SUPPORTED
-   if (png_ptr->transformations & PNG_FILLER)
-      png_do_read_filler(row_info, png_ptr->row_buf + 1,
-          (png_uint_32)png_ptr->filler, png_ptr->flags);
-#endif
-
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_ALPHA)
-      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_ALPHA)
-      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-#ifdef PNG_READ_SWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_BYTES)
-      png_do_swap(row_info, png_ptr->row_buf + 1);
-#endif
-#endif
-
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-   if (png_ptr->transformations & PNG_USER_TRANSFORM)
-    {
-      if (png_ptr->read_user_transform_fn != NULL)
-         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
-             (png_ptr,     /* png_ptr */
-             row_info,     /* row_info: */
-                /*  png_uint_32 width;       width of row */
-                /*  png_size_t rowbytes;     number of bytes in row */
-                /*  png_byte color_type;     color type of pixels */
-                /*  png_byte bit_depth;      bit depth of samples */
-                /*  png_byte channels;       number of channels (1-4) */
-                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
-             png_ptr->row_buf + 1);    /* start of pixel data for row */
-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
-      if (png_ptr->user_transform_depth)
-         row_info->bit_depth = png_ptr->user_transform_depth;
-
-      if (png_ptr->user_transform_channels)
-         row_info->channels = png_ptr->user_transform_channels;
-#endif
-      row_info->pixel_depth = (png_byte)(row_info->bit_depth *
-          row_info->channels);
-
-      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
-   }
-#endif
-}
-
 #ifdef PNG_READ_PACK_SUPPORTED
 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
  * without changing the actual values.  Thus, if you had a row with
  * a bit depth of 1, you would end up with bytes that only contained
  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
  * png_do_shift() after this.
  */
-void /* PRIVATE */
+static void
 png_do_unpack(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_unpack");
 
    if (row_info->bit_depth < 8)
    {
       png_uint_32 i;
       png_uint_32 row_width=row_info->width;
@@ -2517,17 +2223,17 @@ png_do_unpack(png_row_infop row_info, pn
 #endif
 
 #ifdef PNG_READ_SHIFT_SUPPORTED
 /* Reverse the effects of png_do_shift.  This routine merely shifts the
  * pixels back to their significant bits values.  Thus, if you have
  * a row of bit depth 8, but only 5 are significant, this will shift
  * the values back to 0 through 31.
  */
-void /* PRIVATE */
+static void
 png_do_unshift(png_row_infop row_info, png_bytep row,
     png_const_color_8p sig_bits)
 {
    int color_type;
 
    png_debug(1, "in png_do_unshift");
 
    /* The palette case has already been handled in the _init routine. */
@@ -2656,17 +2362,17 @@ png_do_unshift(png_row_infop row_info, p
 #endif
       }
    }
 }
 #endif
 
 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
 /* Scale rows of bit depth 16 down to 8 accurately */
-void /* PRIVATE */
+static void
 png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_scale_16_to_8");
 
    if (row_info->bit_depth == 16)
    {
       png_bytep sp = row; /* source */
       png_bytep dp = row; /* destination */
@@ -2714,17 +2420,17 @@ png_do_scale_16_to_8(png_row_infop row_i
       row_info->bit_depth = 8;
       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
       row_info->rowbytes = row_info->width * row_info->channels;
    }
 }
 #endif
 
 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-void /* PRIVATE */
+static void
 /* Simply discard the low byte.  This was the default behavior prior
  * to libpng-1.5.4.
  */
 png_do_chop(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_chop");
 
    if (row_info->bit_depth == 16)
@@ -2742,17 +2448,17 @@ png_do_chop(png_row_infop row_info, png_
       row_info->bit_depth = 8;
       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
       row_info->rowbytes = row_info->width * row_info->channels;
    }
 }
 #endif
 
 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-void /* PRIVATE */
+static void
 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_read_swap_alpha");
 
    {
       png_uint_32 row_width = row_info->width;
       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
       {
@@ -2839,17 +2545,17 @@ png_do_read_swap_alpha(png_row_infop row
          }
 #endif
       }
    }
 }
 #endif
 
 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-void /* PRIVATE */
+static void
 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
 {
    png_uint_32 row_width;
    png_debug(1, "in png_do_read_invert_alpha");
 
    row_width = row_info->width;
    if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    {
@@ -2941,17 +2647,17 @@ png_do_read_invert_alpha(png_row_infop r
       }
 #endif
    }
 }
 #endif
 
 #ifdef PNG_READ_FILLER_SUPPORTED
 /* Add filler channel if we have RGB color */
-void /* PRIVATE */
+static void
 png_do_read_filler(png_row_infop row_info, png_bytep row,
     png_uint_32 filler, png_uint_32 flags)
 {
    png_uint_32 i;
    png_uint_32 row_width = row_info->width;
 
 #ifdef PNG_READ_16BIT_SUPPORTED
    png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
@@ -3128,17 +2834,17 @@ png_do_read_filler(png_row_infop row_inf
       }
 #endif
    } /* COLOR_TYPE == RGB */
 }
 #endif
 
 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 /* Expand grayscale files to RGB, with or without alpha */
-void /* PRIVATE */
+static void
 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
 {
    png_uint_32 i;
    png_uint_32 row_width = row_info->width;
 
    png_debug(1, "in png_do_gray_to_rgb");
 
    if (row_info->bit_depth >= 8 &&
@@ -3267,17 +2973,17 @@ png_do_gray_to_rgb(png_row_infop row_inf
  *  values this results in an implicit assumption that the original PNG RGB
  *  values were linear.
  *
  *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
  *  the API takes just red and green coefficients the blue coefficient is
  *  calculated to make the sum 32768.  This will result in different rounding
  *  to that used above.
  */
-int /* PRIVATE */
+static int
 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
 
 {
    int rgb_error = 0;
 
    png_debug(1, "in png_do_rgb_to_gray");
 
    if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&
@@ -3461,83 +3167,24 @@ png_do_rgb_to_gray(png_structrp png_ptr,
           ~PNG_COLOR_MASK_COLOR);
       row_info->pixel_depth = (png_byte)(row_info->channels *
           row_info->bit_depth);
       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
    }
    return rgb_error;
 }
 #endif
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
-/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
- * large of png_color.  This lets grayscale images be treated as
- * paletted.  Most useful for gamma correction and simplification
- * of code.  This API is not used internally.
- */
-void PNGAPI
-png_build_grayscale_palette(int bit_depth, png_colorp palette)
-{
-   int num_palette;
-   int color_inc;
-   int i;
-   int v;
-
-   png_debug(1, "in png_do_build_grayscale_palette");
-
-   if (palette == NULL)
-      return;
-
-   switch (bit_depth)
-   {
-      case 1:
-         num_palette = 2;
-         color_inc = 0xff;
-         break;
-
-      case 2:
-         num_palette = 4;
-         color_inc = 0x55;
-         break;
-
-      case 4:
-         num_palette = 16;
-         color_inc = 0x11;
-         break;
-
-      case 8:
-         num_palette = 256;
-         color_inc = 1;
-         break;
-
-      default:
-         num_palette = 0;
-         color_inc = 0;
-         break;
-   }
-
-   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
-   {
-      palette[i].red = (png_byte)v;
-      palette[i].green = (png_byte)v;
-      palette[i].blue = (png_byte)v;
-   }
-}
-#endif
-
-
-#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+
 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
 /* Replace any alpha or transparency with the supplied background color.
  * "background" is already in the screen gamma, while "background_1" is
  * at a gamma of 1.0.  Paletted files have already been taken care of.
  */
-void /* PRIVATE */
+static void
 png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
 {
 #ifdef PNG_READ_GAMMA_SUPPORTED
    png_const_bytep gamma_table = png_ptr->gamma_table;
    png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
    png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
    png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
    png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
@@ -4267,17 +3914,17 @@ png_do_compose(png_row_infop row_info, p
 
 #ifdef PNG_READ_GAMMA_SUPPORTED
 /* Gamma correct the image, avoiding the alpha channel.  Make sure
  * you do this after you deal with the transparency issue on grayscale
  * or RGB images. If your bit depth is 8, use gamma_table, if it
  * is 16, use gamma_16_table and gamma_shift.  Build these with
  * build_gamma_table().
  */
-void /* PRIVATE */
+static void
 png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
 {
    png_const_bytep gamma_table = png_ptr->gamma_table;
    png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
    int gamma_shift = png_ptr->gamma_shift;
 
    png_bytep sp;
    png_uint_32 i;
@@ -4468,17 +4115,17 @@ png_do_gamma(png_row_infop row_info, png
 }
 #endif
 
 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
 /* Encode the alpha channel to the output gamma (the input channel is always
  * linear.)  Called only with color types that have an alpha channel.  Needs the
  * from_1 tables.
  */
-void /* PRIVATE */
+static void
 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
 {
    png_uint_32 row_width = row_info->width;
 
    png_debug(1, "in png_do_encode_alpha");
 
    if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
    {
@@ -4534,17 +4181,17 @@ png_do_encode_alpha(png_row_infop row_in
    png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
 }
 #endif
 
 #ifdef PNG_READ_EXPAND_SUPPORTED
 /* Expands a palette row to an RGB or RGBA row depending
  * upon whether you supply trans and num_trans.
  */
-void /* PRIVATE */
+static void
 png_do_expand_palette(png_row_infop row_info, png_bytep row,
    png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
 {
    int shift, value;
    png_bytep sp, dp;
    png_uint_32 i;
    png_uint_32 row_width=row_info->width;
 
@@ -4687,17 +4334,17 @@ png_do_expand_palette(png_row_infop row_
          }
       }
    }
 }
 
 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
  * expanded transparency value is supplied, an alpha channel is built.
  */
-void /* PRIVATE */
+static void
 png_do_expand(png_row_infop row_info, png_bytep row,
     png_const_color_16p trans_color)
 {
    int shift, value;
    png_bytep sp, dp;
    png_uint_32 i;
    png_uint_32 row_width=row_info->width;
 
@@ -4917,17 +4564,17 @@ png_do_expand(png_row_infop row_info, pn
    }
 }
 #endif
 
 #ifdef PNG_READ_EXPAND_16_SUPPORTED
 /* If the bit depth is 8 and the color type is not a palette type expand the
  * whole row to 16 bits.  Has no effect otherwise.
  */
-void /* PRIVATE */
+static void
 png_do_expand_16(png_row_infop row_info, png_bytep row)
 {
    if (row_info->bit_depth == 8 &&
       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
    {
       /* The row have a sequence of bytes containing [0..255] and we need
        * to turn it into another row containing [0..65535], to do this we
        * calculate:
@@ -4945,17 +4592,17 @@ png_do_expand_16(png_row_infop row_info,
       row_info->rowbytes *= 2;
       row_info->bit_depth = 16;
       row_info->pixel_depth = (png_byte)(row_info->channels * 16);
    }
 }
 #endif
 
 #ifdef PNG_READ_QUANTIZE_SUPPORTED
-void /* PRIVATE */
+static void
 png_do_quantize(png_row_infop row_info, png_bytep row,
     png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
 {
    png_bytep sp, dp;
    png_uint_32 i;
    png_uint_32 row_width=row_info->width;
 
    png_debug(1, "in png_do_quantize");
@@ -5037,74 +4684,308 @@ png_do_quantize(png_row_infop row_info, 
          for (i = 0; i < row_width; i++, sp++)
          {
             *sp = quantize_lookup[*sp];
          }
       }
    }
 }
 #endif /* PNG_READ_QUANTIZE_SUPPORTED */
-#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-/* Undoes intrapixel differencing  */
+
+/* Transform the row.  The order of transformations is significant,
+ * and is very touchy.  If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
 void /* PRIVATE */
-png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
 {
-   png_debug(1, "in png_do_read_intrapixel");
-
-   if (
-       (row_info->color_type & PNG_COLOR_MASK_COLOR))
+   png_debug(1, "in png_do_read_transformations");
+
+   if (png_ptr->row_buf == NULL)
    {
-      int bytes_per_pixel;
-      png_uint_32 row_width = row_info->width;
-
-      if (row_info->bit_depth == 8)
+      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
+       * error is incredibly rare and incredibly easy to debug without this
+       * information.
+       */
+      png_error(png_ptr, "NULL row buffer");
+   }
+
+   /* The following is debugging; prior to 1.5.4 the code was never compiled in;
+    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
+    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
+    * all transformations, however in practice the ROW_INIT always gets done on
+    * demand, if necessary.
+    */
+   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
+      !(png_ptr->flags & PNG_FLAG_ROW_INIT))
+   {
+      /* Application has failed to call either png_read_start_image() or
+       * png_read_update_info() after setting transforms that expand pixels.
+       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
+       */
+      png_error(png_ptr, "Uninitialized row");
+   }
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+   if (png_ptr->transformations & PNG_EXPAND)
+   {
+      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
       {
-         png_bytep rp;
-         png_uint_32 i;
-
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 3;
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 4;
+         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
+             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+      }
+
+      else
+      {
+         if (png_ptr->num_trans &&
+             (png_ptr->transformations & PNG_EXPAND_tRNS))
+            png_do_expand(row_info, png_ptr->row_buf + 1,
+                &(png_ptr->trans_color));
 
          else
-            return;
-
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
-            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
-         }
+            png_do_expand(row_info, png_ptr->row_buf + 1,
+                NULL);
       }
-      else if (row_info->bit_depth == 16)
+   }
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+      !(png_ptr->transformations & PNG_COMPOSE) &&
+      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+         0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+   {
+      int rgb_error =
+          png_do_rgb_to_gray(png_ptr, row_info,
+              png_ptr->row_buf + 1);
+
+      if (rgb_error)
       {
-         png_bytep rp;
-         png_uint_32 i;
-
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 6;
-
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 8;
-
-         else
-            return;
-
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
-            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
-            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
-            *(rp    ) = (png_byte)((red >> 8) & 0xff);
-            *(rp + 1) = (png_byte)(red & 0xff);
-            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
-            *(rp + 5) = (png_byte)(blue & 0xff);
-         }
+         png_ptr->rgb_to_gray_status=1;
+         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+             PNG_RGB_TO_GRAY_WARN)
+            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+
+         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+             PNG_RGB_TO_GRAY_ERR)
+            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
       }
    }
+#endif
+
+/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
+ *
+ *   In most cases, the "simple transparency" should be done prior to doing
+ *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ *   pixel is transparent.  You would also need to make sure that the
+ *   transparency information is upgraded to RGB.
+ *
+ *   To summarize, the current flow is:
+ *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ *                                   with background "in place" if transparent,
+ *                                   convert to RGB if necessary
+ *   - Gray + alpha -> composite with gray background and remove alpha bytes,
+ *                                   convert to RGB if necessary
+ *
+ *   To support RGB backgrounds for gray images we need:
+ *   - Gray + simple transparency -> convert to RGB + simple transparency,
+ *                                   compare 3 or 6 bytes and composite with
+ *                                   background "in place" if transparent
+ *                                   (3x compare/pixel compared to doing
+ *                                   composite with gray bkgrnd)
+ *   - Gray + alpha -> convert to RGB + alpha, composite with background and
+ *                                   remove alpha bytes (3x float
+ *                                   operations/pixel compared with composite
+ *                                   on gray background)
+ *
+ *  Greg's change will do this.  The reason it wasn't done before is for
+ *  performance, as this increases the per-pixel operations.  If we would check
+ *  in advance if the background was gray or RGB, and position the gray-to-RGB
+ *  transform appropriately, then it would save a lot of work/time.
+ */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* If gray -> RGB, do so now only if background is non-gray; else do later
+    * for performance reasons
+    */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+   if (png_ptr->transformations & PNG_COMPOSE)
+      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+   if ((png_ptr->transformations & PNG_GAMMA) &&
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+      /* Because RGB_TO_GRAY does the gamma transform. */
+      !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+      /* Because PNG_COMPOSE does the gamma transform if there is something to
+       * do (if there is an alpha channel or transparency.)
+       */
+       !((png_ptr->transformations & PNG_COMPOSE) &&
+       ((png_ptr->num_trans != 0) ||
+       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+      /* Because png_init_read_transformations transforms the palette, unless
+       * RGB_TO_GRAY will do the transform.
+       */
+       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+      (png_ptr->transformations & PNG_COMPOSE) &&
+      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+         0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
+      (row_info->color_type & PNG_COLOR_MASK_ALPHA))
+      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+   if (png_ptr->transformations & PNG_SCALE_16_TO_8)
+      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+   /* There is no harm in doing both of these because only one has any effect,
+    * by putting the 'scale' option first if the app asks for scale (either by
+    * calling the API or in a TRANSFORM flag) this is what happens.
+    */
+   if (png_ptr->transformations & PNG_16_TO_8)
+      png_do_chop(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+   if (png_ptr->transformations & PNG_QUANTIZE)
+   {
+      png_do_quantize(row_info, png_ptr->row_buf + 1,
+          png_ptr->palette_lookup, png_ptr->quantize_index);
+
+      if (row_info->rowbytes == 0)
+         png_error(png_ptr, "png_do_quantize returned rowbytes=0");
+   }
+#endif /* PNG_READ_QUANTIZE_SUPPORTED */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+   /* Do the expansion now, after all the arithmetic has been done.  Notice
+    * that previous transformations can handle the PNG_EXPAND_16 flag if this
+    * is efficient (particularly true in the case of gamma correction, where
+    * better accuracy results faster!)
+    */
+   if (png_ptr->transformations & PNG_EXPAND_16)
+      png_do_expand_16(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+   /* NOTE: moved here in 1.5.4 (from much later in this list.) */
+   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_unshift(row_info, png_ptr->row_buf + 1,
+          &(png_ptr->shift));
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_unpack(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+   /* Added at libpng-1.5.10 */
+   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+       png_ptr->num_palette_max >= 0)
+      png_do_check_palette_indexes(png_ptr, row_info);
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_read_filler(row_info, png_ptr->row_buf + 1,
+          (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+#ifdef PNG_READ_SWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+    {
+      if (png_ptr->read_user_transform_fn != NULL)
+         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
+             (png_ptr,     /* png_ptr */
+             row_info,     /* row_info: */
+                /*  png_uint_32 width;       width of row */
+                /*  png_size_t rowbytes;     number of bytes in row */
+                /*  png_byte color_type;     color type of pixels */
+                /*  png_byte bit_depth;      bit depth of samples */
+                /*  png_byte channels;       number of channels (1-4) */
+                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
+             png_ptr->row_buf + 1);    /* start of pixel data for row */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+      if (png_ptr->user_transform_depth)
+         row_info->bit_depth = png_ptr->user_transform_depth;
+
+      if (png_ptr->user_transform_channels)
+         row_info->channels = png_ptr->user_transform_channels;
+#endif
+      row_info->pixel_depth = (png_byte)(row_info->bit_depth *
+          row_info->channels);
+
+      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
+   }
+#endif
 }
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
+
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
 #endif /* PNG_READ_SUPPORTED */
--- a/media/libpng/pngrutil.c
+++ b/media/libpng/pngrutil.c
@@ -1,12 +1,12 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.6.7 [November 14, 2013]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
@@ -273,16 +273,20 @@ png_crc_error(png_structrp png_ptr)
       crc = png_get_uint_32(crc_bytes);
       return ((int)(crc != png_ptr->crc));
    }
 
    else
       return (0);
 }
 
+#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
+    defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\
+    defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\
+    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED)
 /* Manage the read buffer; this simply reallocates the buffer if it is not small
  * enough (or if it is not allocated).  The routine returns a pointer to the
  * buffer; if an error occurs and 'warn' is set the routine returns NULL, else
  * it will call png_error (via png_malloc) on failure.  (warn == 2 means
  * 'silent').
  */
 static png_bytep
 png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
@@ -320,16 +324,17 @@ png_read_buffer(png_structrp png_ptr, pn
              png_chunk_error(png_ptr, "insufficient memory to read chunk");
 #endif
          }
       }
    }
 
    return buffer;
 }
+#endif /* PNG_READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */
 
 /* png_inflate_claim: claim the zstream for some nefarious purpose that involves
  * decompression.  Returns Z_OK on success, else a zlib error code.  It checks
  * the owner but, in final release builds, just issues a warning if some other
  * chunk apparently owns the stream.  Prior to release it does a png_error.
  */
 static int
 png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
@@ -4044,17 +4049,16 @@ png_read_filter_row_paeth_multibyte_pixe
          pa = p < 0 ? -p : p;
          pb = pc < 0 ? -pc : pc;
          pc = (p + pc) < 0 ? -(p + pc) : p + pc;
 #     endif
 
       if (pb < pa) pa = pb, a = b;
       if (pc < pa) a = c;
 
-      c = b;
       a += *row;
       *row++ = (png_byte)a;
    }
 }
 
 static void
 png_init_filter_functions(png_structrp pp)
    /* This function is called once for every PNG image (except for PNG images
--- 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.6.3 [July 18, 2013]
+ * Last changed in libpng 1.6.8 [December 19, 2013]
  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
@@ -527,17 +527,17 @@ png_set_PLTE(png_structrp png_ptr, png_i
 
    if ((num_palette > 0 && palette == NULL) ||
       (num_palette == 0
 #        ifdef PNG_MNG_FEATURES_SUPPORTED
             && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
 #        endif
       ))
    {
-      png_chunk_error(png_ptr, "Invalid palette");
+      png_error(png_ptr, "Invalid palette");
       return;
    }
 
    /* It may not actually be necessary to set png_ptr->palette here;
     * we do it for backward compatibility with the way the png_handle_tRNS
     * function used to do the allocation.
     *
     * 1.6.0: the above statement appears to be incorrect; something has to set
--- a/media/libpng/pngtrans.c
+++ b/media/libpng/pngtrans.c
@@ -1,13 +1,13 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * Last changed in libpng 1.6.2 [April 25, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
@@ -52,17 +52,19 @@ png_set_packing(png_structrp png_ptr)
    png_debug(1, "in png_set_packing");
 
    if (png_ptr == NULL)
       return;
 
    if (png_ptr->bit_depth < 8)
    {
       png_ptr->transformations |= PNG_PACK;
-      png_ptr->usr_bit_depth = 8;
+#     ifdef PNG_WRITE_SUPPORTED
+         png_ptr->usr_bit_depth = 8;
+#     endif
    }
 }
 #endif
 
 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 /* Turn on packed pixel swapping */
 void PNGAPI
 png_set_packswap(png_structrp png_ptr)
--- a/media/libpng/pngwio.c
+++ b/media/libpng/pngwio.c
@@ -1,13 +1,13 @@
 
 /* pngwio.c - functions for data output
  *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  *
  * This file provides a location for all output.  Users who need
@@ -144,21 +144,25 @@ png_set_write_fn(png_structrp png_ptr, p
       png_ptr->output_flush_fn = output_flush_fn;
 
    else
       png_ptr->output_flush_fn = png_default_flush;
 
 #  else
    png_ptr->output_flush_fn = output_flush_fn;
 #  endif
+#else
+   PNG_UNUSED(output_flush_fn)
 #endif /* PNG_WRITE_FLUSH_SUPPORTED */
 
+#ifdef PNG_READ_SUPPORTED
    /* It is an error to read while writing a png file */
    if (png_ptr->read_data_fn != NULL)
    {
       png_ptr->read_data_fn = NULL;
 
       png_warning(png_ptr,
           "Can't set both read_data_fn and write_data_fn in the"
           " same structure");
    }
+#endif
 }
 #endif /* PNG_WRITE_SUPPORTED */
--- a/media/libpng/pngwrite.c
+++ b/media/libpng/pngwrite.c
@@ -1,13 +1,13 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * Last changed in libpng 1.6.2 [April 25, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
@@ -611,16 +611,81 @@ png_write_image(png_structrp png_ptr, pn
       /* Loop through image */
       for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
       {
          png_write_row(png_ptr, *rp);
       }
    }
 }
 
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Performs intrapixel differencing  */
+static void
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+   png_debug(1, "in png_do_write_intrapixel");
+
+   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
+   {
+      int bytes_per_pixel;
+      png_uint_32 row_width = row_info->width;
+      if (row_info->bit_depth == 8)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 3;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 4;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
+            *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
+         }
+      }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+      else if (row_info->bit_depth == 16)
+      {
+         png_bytep rp;
+         png_uint_32 i;
+
+         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+            bytes_per_pixel = 6;
+
+         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+            bytes_per_pixel = 8;
+
+         else
+            return;
+
+         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+         {
+            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
+            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
+            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
+            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
+            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
+            *(rp    ) = (png_byte)((red >> 8) & 0xff);
+            *(rp + 1) = (png_byte)(red & 0xff);
+            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+            *(rp + 5) = (png_byte)(blue & 0xff);
+         }
+      }
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
+   }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+
 /* Called by user to write a row of image data */
 void PNGAPI
 png_write_row(png_structrp png_ptr, png_const_bytep row)
 {
    /* 1.5.6: moved from png_struct to be a local structure: */
    png_row_info row_info;
 
    if (png_ptr == NULL)
@@ -1642,24 +1707,26 @@ png_write_image_16bit(png_voidp argument
    png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
    png_uint_16p row_end;
    const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
    int aindex = 0;
    png_uint_32 y = image->height;
 
    if (image->format & PNG_FORMAT_FLAG_ALPHA)
    {
-      if (image->format & PNG_FORMAT_FLAG_AFIRST)
-      {
-         aindex = -1;
-         ++input_row; /* To point to the first component */
-         ++output_row;
-      }
+#     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+         if (image->format & PNG_FORMAT_FLAG_AFIRST)
+         {
+            aindex = -1;
+            ++input_row; /* To point to the first component */
+            ++output_row;
+         }
 
-      else
+         else
+#     endif
          aindex = channels;
    }
 
    else
       png_error(png_ptr, "png_write_image: internal call error");
 
    /* Work out the output row end and count over this, note that the increment
     * above to 'row' means that row_end can actually be beyond the end of the
@@ -1798,24 +1865,26 @@ png_write_image_8bit(png_voidp argument)
    png_uint_32 y = image->height;
    const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
 
    if (image->format & PNG_FORMAT_FLAG_ALPHA)
    {
       png_bytep row_end;
       int aindex;
 
-      if (image->format & PNG_FORMAT_FLAG_AFIRST)
-      {
-         aindex = -1;
-         ++input_row; /* To point to the first component */
-         ++output_row;
-      }
+#     ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+         if (image->format & PNG_FORMAT_FLAG_AFIRST)
+         {
+            aindex = -1;
+            ++input_row; /* To point to the first component */
+            ++output_row;
+         }
 
-      else
+         else
+#     endif
          aindex = channels;
 
       /* Use row_end in place of a loop counter: */
       row_end = output_row + image->width * (channels+1);
 
       while (y-- > 0)
       {
          png_const_uint_16p in_ptr = input_row;
@@ -1885,17 +1954,18 @@ png_image_set_PLTE(png_image_write_contr
    const void *cmap = display->colormap;
    const int entries = image->colormap_entries > 256 ? 256 :
       (int)image->colormap_entries;
 
    /* NOTE: the caller must check for cmap != NULL and entries != 0 */
    const png_uint_32 format = image->format;
    const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
 
-#  ifdef PNG_FORMAT_BGR_SUPPORTED
+#  if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
+      defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
       const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
          (format & PNG_FORMAT_FLAG_ALPHA) != 0;
 #  else
 #     define afirst 0
 #  endif
 
 #  ifdef PNG_FORMAT_BGR_SUPPORTED
       const int bgr = (format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
--- a/media/libpng/pngwtran.c
+++ b/media/libpng/pngwtran.c
@@ -1,108 +1,32 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * Last changed in libpng 1.6.0 [February 14, 2013]
- * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.9 [February 6, 2014]
+ * Copyright (c) 1998-2014 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
  * and license in png.h
  */
 
 #include "pngpriv.h"
 
 #ifdef PNG_WRITE_SUPPORTED
-
 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-/* Transform the data according to the user's wishes.  The order of
- * transformations is significant.
- */
-void /* PRIVATE */
-png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
-{
-   png_debug(1, "in png_do_write_transformations");
-
-   if (png_ptr == NULL)
-      return;
-
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-   if (png_ptr->transformations & PNG_USER_TRANSFORM)
-      if (png_ptr->write_user_transform_fn != NULL)
-         (*(png_ptr->write_user_transform_fn)) /* User write transform
-                                                 function */
-             (png_ptr,  /* png_ptr */
-             row_info,  /* row_info: */
-                /*  png_uint_32 width;       width of row */
-                /*  png_size_t rowbytes;     number of bytes in row */
-                /*  png_byte color_type;     color type of pixels */
-                /*  png_byte bit_depth;      bit depth of samples */
-                /*  png_byte channels;       number of channels (1-4) */
-                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
-             png_ptr->row_buf + 1);      /* start of pixel data for row */
-#endif
-
-#ifdef PNG_WRITE_FILLER_SUPPORTED
-   if (png_ptr->transformations & PNG_FILLER)
-      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
-         !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
-#endif
-
-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_PACKSWAP)
-      png_do_packswap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_PACK_SUPPORTED
-   if (png_ptr->transformations & PNG_PACK)
-      png_do_pack(row_info, png_ptr->row_buf + 1,
-          (png_uint_32)png_ptr->bit_depth);
-#endif
-
-#ifdef PNG_WRITE_SWAP_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_BYTES)
-      png_do_swap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
-   if (png_ptr->transformations & PNG_SHIFT)
-      png_do_shift(row_info, png_ptr->row_buf + 1,
-          &(png_ptr->shift));
-#endif
-
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_SWAP_ALPHA)
-      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_ALPHA)
-      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_BGR_SUPPORTED
-   if (png_ptr->transformations & PNG_BGR)
-      png_do_bgr(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_INVERT_SUPPORTED
-   if (png_ptr->transformations & PNG_INVERT_MONO)
-      png_do_invert(row_info, png_ptr->row_buf + 1);
-#endif
-}
 
 #ifdef PNG_WRITE_PACK_SUPPORTED
 /* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
  * row_info bit depth should be 8 (one pixel per byte).  The channels
  * should be 1 (this only happens on grayscale and paletted images).
  */
-void /* PRIVATE */
+static void
 png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
 {
    png_debug(1, "in png_do_pack");
 
    if (row_info->bit_depth == 8 &&
       row_info->channels == 1)
    {
       switch ((int)bit_depth)
@@ -237,17 +161,17 @@ png_do_pack(png_row_infop row_info, png_
 #ifdef PNG_WRITE_SHIFT_SUPPORTED
 /* Shift pixel values to take advantage of whole range.  Pass the
  * true number of bits in bit_depth.  The row should be packed
  * according to row_info->bit_depth.  Thus, if you had a row of
  * bit depth 4, but the pixels only had values from 0 to 7, you
  * would pass 3 as bit_depth, and this routine would translate the
  * data to 0 to 15.
  */
-void /* PRIVATE */
+static void
 png_do_shift(png_row_infop row_info, png_bytep row,
     png_const_color_8p bit_depth)
 {
    png_debug(1, "in png_do_shift");
 
    if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
    {
       int shift_start[4], shift_dec[4];
@@ -376,17 +300,17 @@ png_do_shift(png_row_infop row_info, png
             *bp++ = (png_byte)(value & 0xff);
          }
       }
    }
 }
 #endif
 
 #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-void /* PRIVATE */
+static void
 png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_write_swap_alpha");
 
    {
       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
       {
          if (row_info->bit_depth == 8)
@@ -470,17 +394,17 @@ png_do_write_swap_alpha(png_row_infop ro
          }
 #endif /* PNG_WRITE_16BIT_SUPPORTED */
       }
    }
 }
 #endif
 
 #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-void /* PRIVATE */
+static void
 png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
 {
    png_debug(1, "in png_do_write_invert_alpha");
 
    {
       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
       {
          if (row_info->bit_depth == 8)
@@ -563,75 +487,86 @@ png_do_write_invert_alpha(png_row_infop 
                *(dp++) = (png_byte)(255 - *(sp++));
             }
          }
 #endif /* PNG_WRITE_16BIT_SUPPORTED */
       }
    }
 }
 #endif
-#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
 
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-/* Undoes intrapixel differencing  */
+/* Transform the data according to the user's wishes.  The order of
+ * transformations is significant.
+ */
 void /* PRIVATE */
-png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
 {
-   png_debug(1, "in png_do_write_intrapixel");
+   png_debug(1, "in png_do_write_transformations");
+
+   if (png_ptr == NULL)
+      return;
 
-   if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
-   {
-      int bytes_per_pixel;
-      png_uint_32 row_width = row_info->width;
-      if (row_info->bit_depth == 8)
-      {
-         png_bytep rp;
-         png_uint_32 i;
-
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 3;
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+   if (png_ptr->transformations & PNG_USER_TRANSFORM)
+      if (png_ptr->write_user_transform_fn != NULL)
+         (*(png_ptr->write_user_transform_fn)) /* User write transform
+                                                 function */
+             (png_ptr,  /* png_ptr */
+             row_info,  /* row_info: */
+                /*  png_uint_32 width;       width of row */
+                /*  png_size_t rowbytes;     number of bytes in row */
+                /*  png_byte color_type;     color type of pixels */
+                /*  png_byte bit_depth;      bit depth of samples */
+                /*  png_byte channels;       number of channels (1-4) */
+                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
+             png_ptr->row_buf + 1);      /* start of pixel data for row */
+#endif
 
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 4;
-
-         else
-            return;
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+   if (png_ptr->transformations & PNG_FILLER)
+      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+         !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+#endif
 
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            *(rp)     = (png_byte)((*rp       - *(rp + 1)) & 0xff);
-            *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
-         }
-      }
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_PACKSWAP)
+      png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
 
-#ifdef PNG_WRITE_16BIT_SUPPORTED
-      else if (row_info->bit_depth == 16)
-      {
-         png_bytep rp;
-         png_uint_32 i;
+#ifdef PNG_WRITE_PACK_SUPPORTED
+   if (png_ptr->transformations & PNG_PACK)
+      png_do_pack(row_info, png_ptr->row_buf + 1,
+          (png_uint_32)png_ptr->bit_depth);
+#endif
 
-         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
-            bytes_per_pixel = 6;
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_BYTES)
+      png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
 
-         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
-            bytes_per_pixel = 8;
-
-         else
-            return;
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+   if (png_ptr->transformations & PNG_SHIFT)
+      png_do_shift(row_info, png_ptr->row_buf + 1,
+          &(png_ptr->shift));
+#endif
 
-         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
-         {
-            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
-            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
-            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
-            png_uint_32 red  = (png_uint_32)((s0 - s1) & 0xffffL);
-            png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
-            *(rp    ) = (png_byte)((red >> 8) & 0xff);
-            *(rp + 1) = (png_byte)(red & 0xff);
-            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
-            *(rp + 5) = (png_byte)(blue & 0xff);
-         }
-      }
-#endif /* PNG_WRITE_16BIT_SUPPORTED */
-   }
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_SWAP_ALPHA)
+      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_ALPHA)
+      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+   if (png_ptr->transformations & PNG_BGR)
+      png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+   if (png_ptr->transformations & PNG_INVERT_MONO)
+      png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
 }
-#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
 #endif /* PNG_WRITE_SUPPORTED */