Bug 759067 - Add an "APNG-aware app" flag. r=joe
authorMax Stepin <newstop@gmail.com>
Mon, 16 Jul 2012 20:38:46 -0400
changeset 105492 8a9b06abad5e0caedb49e062b3d356e328d24446
parent 105491 68f6f8dbb06d74aba999ce4cec0ee5edc9c00acd
child 105493 61b4f7c9f5261a6064c4726c3860a1956b51d4d0
push id214
push userakeybl@mozilla.com
push dateWed, 14 Nov 2012 20:38:59 +0000
treeherdermozilla-release@c8b08ec8e1aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs759067
milestone17.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 759067 - Add an "APNG-aware app" flag. r=joe
media/libpng/MOZCHANGES
media/libpng/apng.patch
media/libpng/pngpread.c
media/libpng/pngpriv.h
media/libpng/pngread.c
--- a/media/libpng/MOZCHANGES
+++ b/media/libpng/MOZCHANGES
@@ -1,11 +1,13 @@
 
 Changes made to pristine png source by mozilla.org developers.
 
+2012/07/16  -- Add an "APNG-aware app" flag (bug #759067).
+
 2012/07/04  -- Synced with libpng-1.5.11 (bug #771394).
 
 2012/04/13  -- Synced with libpng-1.5.10 (bug #745178).
 
 2012/02/19  -- Synced with libpng-1.5.9 (bug #648690).
 
 2011/07/20  -- Synced with libpng-1.4.8 (bug #669863).
 
--- a/media/libpng/apng.patch
+++ b/media/libpng/apng.patch
@@ -1,11 +1,11 @@
 diff -up8 png.h png.h
 --- png.h	2012-06-14 07:28:00 -0400
-+++ png.h	2012-07-04 16:27:29 -0400
++++ png.h	2012-07-07 10:21:31 -0400
 @@ -423,24 +423,18 @@
  /* 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 10511 /* 1.5.11 */
@@ -195,17 +195,17 @@ diff -up8 png.h png.h
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* PNG_VERSION_INFO_ONLY */
  /* Do not put anything past this line */
 diff -up8 pngget.c pngget.c
 --- pngget.c	2012-06-14 07:28:00 -0400
-+++ pngget.c	2012-07-04 16:27:29 -0400
++++ pngget.c	2012-04-24 20:51:09 -0400
 @@ -1116,9 +1116,171 @@ png_get_io_chunk_type (png_const_structp
  png_const_bytep PNGAPI
  png_get_io_chunk_name (png_structp png_ptr)
  {
     PNG_CSTRING_FROM_CHUNK(png_ptr->io_chunk_string, png_ptr->chunk_name);
     return png_ptr->io_chunk_string;
  }
  #endif /* ?PNG_IO_STATE_SUPPORTED */
@@ -370,17 +370,17 @@ diff -up8 pngget.c pngget.c
 +    PNG_UNUSED(info_ptr)
 +
 +    return 0;
 +}
 +#endif /* PNG_APNG_SUPPORTED */
  #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
 diff -up8 pnginfo.h pnginfo.h
 --- pnginfo.h	2012-06-14 07:28:00 -0400
-+++ pnginfo.h	2012-07-04 16:27:29 -0400
++++ pnginfo.h	2012-03-03 22:17:56 -0500
 @@ -260,10 +260,23 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
  
  #ifdef PNG_INFO_IMAGE_SUPPORTED
     /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
        non-zero */
     /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
     png_bytepp row_pointers;        /* the image bits */
  #endif
@@ -397,17 +397,17 @@ diff -up8 pnginfo.h pnginfo.h
 +   png_byte next_frame_dispose_op;
 +   png_byte next_frame_blend_op;
 +#endif
 +
  };
  #endif /* PNGINFO_H */
 diff -up8 pngpread.c pngpread.c
 --- pngpread.c	2012-06-14 07:28:00 -0400
-+++ pngpread.c	2012-07-04 16:29:59 -0400
++++ pngpread.c	2012-07-16 20:05:38 -0400
 @@ -210,16 +210,119 @@ png_push_read_chunk(png_structp png_ptr,
        png_crc_read(png_ptr, chunk_tag, 4);
        png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
        png_check_chunk_name(png_ptr, png_ptr->chunk_name);
        png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
     }
  
     chunk_name = png_ptr->chunk_name;
@@ -670,47 +670,74 @@ diff -up8 pngpread.c pngpread.c
     }
  
     if (png_ptr->idat_size && png_ptr->save_buffer_size)
     {
        png_size_t save_size = png_ptr->save_buffer_size;
        png_uint_32 idat_size = png_ptr->idat_size;
  
        /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
-@@ -1299,16 +1479,27 @@ png_set_progressive_read_fn(png_structp 
+@@ -854,16 +1034,25 @@ png_push_read_IDAT(png_structp png_ptr)
+ void /* PRIVATE */
+ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+    png_size_t buffer_length)
+ {
+    /* The caller checks for a non-zero buffer length. */
+    if (!(buffer_length > 0) || buffer == NULL)
+       png_error(png_ptr, "No IDAT data (internal error)");
+ 
++#ifdef PNG_READ_APNG_SUPPORTED
++   /* If the app is not APNG-aware, decode only the first frame */
++   if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
++   {
++     png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
++     return;
++   }
++#endif
++
+    /* This routine must process all the data it has been given
+     * before returning, calling the row callback as required to
+     * handle the uncompressed results.
+     */
+    png_ptr->zstream.next_in = buffer;
+    png_ptr->zstream.avail_in = (uInt)buffer_length;
+ 
+    /* Keep going until the decompressed data is all processed
+@@ -1299,16 +1488,28 @@ png_set_progressive_read_fn(png_structp 
  
     png_ptr->info_fn = info_fn;
     png_ptr->row_fn = row_fn;
     png_ptr->end_fn = end_fn;
  
     png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  }
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +void PNGAPI
 +png_set_progressive_frame_fn(png_structp png_ptr,
 +   png_progressive_frame_ptr frame_info_fn,
 +   png_progressive_frame_ptr frame_end_fn)
 +{
 +   png_ptr->frame_info_fn = frame_info_fn;
 +   png_ptr->frame_end_fn = frame_end_fn;
++   png_ptr->apng_flags |= PNG_APNG_APP;
 +}
 +#endif
 +
  png_voidp PNGAPI
  png_get_progressive_ptr(png_const_structp png_ptr)
  {
     if (png_ptr == NULL)
        return (NULL);
  
     return png_ptr->io_ptr;
  }
 diff -up8 pngpriv.h pngpriv.h
 --- pngpriv.h	2012-06-14 07:28:00 -0400
-+++ pngpriv.h	2012-07-04 16:27:29 -0400
++++ pngpriv.h	2012-07-16 20:05:38 -0400
 @@ -462,16 +462,20 @@ typedef PNG_CONST png_uint_16p FAR * png
  #define PNG_HAVE_sRGB               0x80
  #define PNG_HAVE_CHUNK_HEADER      0x100
  #define PNG_WROTE_tIME             0x200
  #define PNG_WROTE_INFO_BEFORE_PLTE 0x400
  #define PNG_BACKGROUND_IS_GRAY     0x800
  #define PNG_HAVE_PNG_SIGNATURE    0x1000
  #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
@@ -722,43 +749,44 @@ diff -up8 pngpriv.h pngpriv.h
  
  /* Flags for the transformations the PNG library does on the image data */
  #define PNG_BGR                 0x0001
  #define PNG_INTERLACE           0x0002
  #define PNG_PACK                0x0004
  #define PNG_SHIFT               0x0008
  #define PNG_SWAP_BYTES          0x0010
  #define PNG_INVERT_MONO         0x0020
-@@ -657,16 +661,25 @@ PNG_EXTERN png_fixed_point png_fixed PNG
+@@ -657,16 +661,26 @@ PNG_EXTERN png_fixed_point png_fixed PNG
  #define png_sPLT PNG_CHUNK(115,  80,  76,  84)
  #define png_sRGB PNG_CHUNK(115,  82,  71,  66)
  #define png_sTER PNG_CHUNK(115,  84,  69,  82)
  #define png_tEXt PNG_CHUNK(116,  69,  88, 116)
  #define png_tIME PNG_CHUNK(116,  73,  77,  69)
  #define png_tRNS PNG_CHUNK(116,  82,  78,  83)
  #define png_zTXt PNG_CHUNK(122,  84,  88, 116)
  
 +#ifdef PNG_APNG_SUPPORTED
 +#define png_acTL PNG_CHUNK( 97,  99,  84,  76)
 +#define png_fcTL PNG_CHUNK(102,  99,  84,  76)
 +#define png_fdAT PNG_CHUNK(102, 100,  65,  84)
 +
 +/* For png_struct.apng_flags: */
 +#define PNG_FIRST_FRAME_HIDDEN       0x0001
++#define PNG_APNG_APP                 0x0002
 +#endif
 +
  /* The following will work on (signed char*) strings, whereas the get_uint_32
   * macro will fail on top-bit-set values because of the sign extension.
   */
  #define PNG_CHUNK_FROM_STRING(s)\
     PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
  
  /* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
   * signed and the argument is a (char[])  This macro will fail miserably on
-@@ -1338,16 +1351,55 @@ PNG_EXTERN void png_push_read_iTXt PNGAR
+@@ -1338,16 +1352,55 @@ PNG_EXTERN void png_push_read_iTXt PNGAR
  
  #ifdef PNG_MNG_FEATURES_SUPPORTED
  PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
      png_bytep row));
  PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
      png_bytep row));
  #endif
  
@@ -806,17 +834,17 @@ diff -up8 pngpriv.h pngpriv.h
  PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr,
      png_fixed_point int_white_x, png_fixed_point int_white_y,
      png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
      int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
      png_fixed_point int_blue_y));
  #endif
 diff -up8 pngread.c pngread.c
 --- pngread.c	2012-06-14 07:28:00 -0400
-+++ pngread.c	2012-07-04 16:27:29 -0400
++++ pngread.c	2012-07-16 20:05:38 -0400
 @@ -235,16 +235,19 @@ png_read_info(png_structp png_ptr, png_i
        {
           if (!(png_ptr->mode & PNG_HAVE_IHDR))
              png_error(png_ptr, "Missing IHDR before IDAT");
  
           else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
               !(png_ptr->mode & PNG_HAVE_PLTE))
              png_error(png_ptr, "Missing PLTE before IDAT");
@@ -1006,45 +1034,19 @@ diff -up8 pngread.c pngread.c
           break;
        }
  
        if (ret != Z_OK)
           png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
               "Decompression error");
  
     } while (png_ptr->zstream.avail_out);
-@@ -927,16 +1044,25 @@ png_read_end(png_structp png_ptr, png_in
-          png_handle_zTXt(png_ptr, info_ptr, length);
- #endif
- 
- #ifdef PNG_READ_iTXt_SUPPORTED
-       else if (chunk_name == png_iTXt)
-          png_handle_iTXt(png_ptr, info_ptr, length);
- #endif
- 
-+#ifdef PNG_READ_APNG_SUPPORTED
-+      else if (chunk_name == png_acTL)
-+         png_handle_acTL(png_ptr, info_ptr, length);
-+      else if (chunk_name == png_fcTL)
-+         png_handle_fcTL(png_ptr, info_ptr, length);
-+      else if (chunk_name == png_fdAT)
-+         png_handle_fdAT(png_ptr, info_ptr, length);
-+#endif
-+
-       else
-          png_handle_unknown(png_ptr, info_ptr, length);
-    } while (!(png_ptr->mode & PNG_HAVE_IEND));
- }
- #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
- 
- /* Free all memory used by the read */
- void PNGAPI
 diff -up8 pngrutil.c pngrutil.c
 --- pngrutil.c	2012-06-14 07:28:00 -0400
-+++ pngrutil.c	2012-07-04 16:27:29 -0400
++++ pngrutil.c	2012-04-24 20:51:09 -0400
 @@ -542,16 +542,21 @@ png_handle_IHDR(png_structp png_ptr, png
     width = png_get_uint_31(png_ptr, buf);
     height = png_get_uint_31(png_ptr, buf + 4);
     bit_depth = buf[8];
     color_type = buf[9];
     compression_type = buf[10];
     filter_type = buf[11];
     interlace_type = buf[12];
@@ -1336,17 +1338,17 @@ diff -up8 pngrutil.c pngrutil.c
 +    png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
 +        png_ptr->iwidth) + 1;
 +}
 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 +#endif /* PNG_READ_APNG_SUPPORTED */
  #endif /* PNG_READ_SUPPORTED */
 diff -up8 pngset.c pngset.c
 --- pngset.c	2012-06-14 07:28:00 -0400
-+++ pngset.c	2012-07-04 16:27:29 -0400
++++ pngset.c	2012-07-07 10:21:31 -0400
 @@ -257,16 +257,21 @@ png_set_IHDR(png_structp png_ptr, png_in
         (PNG_UINT_32_MAX >> 3)      /* 8-byte RRGGBBAA pixels */
         - 48       /* bigrowbuf hack */
         - 1        /* filter byte */
         - 7*8      /* rounding of width to multiple of 8 pixels */
         - 8)       /* extra max_pixel_depth pad */
        info_ptr->rowbytes = 0;
     else
@@ -1519,17 +1521,17 @@ diff -up8 pngset.c pngset.c
  png_set_unknown_chunks(png_structp png_ptr,
     png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
  {
     png_unknown_chunkp np;
     int i;
  
 diff -up8 pngstruct.h pngstruct.h
 --- pngstruct.h	2012-06-14 07:28:00 -0400
-+++ pngstruct.h	2012-07-04 16:27:29 -0400
++++ pngstruct.h	2012-07-07 10:21:31 -0400
 @@ -288,16 +288,37 @@ struct png_struct_def
     png_uint_32 mng_features_permitted;
  #endif
  
  /* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
  #ifdef PNG_MNG_FEATURES_SUPPORTED
     png_byte filter_type;
  #endif
@@ -1560,17 +1562,17 @@ diff -up8 pngstruct.h pngstruct.h
  /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
  #ifdef PNG_USER_MEM_SUPPORTED
     png_voidp mem_ptr;             /* user supplied struct for mem functions */
     png_malloc_ptr malloc_fn;      /* function for allocating memory */
     png_free_ptr free_fn;          /* function for freeing memory */
  #endif
 diff -up8 pngwrite.c pngwrite.c
 --- pngwrite.c	2012-06-14 07:28:00 -0400
-+++ pngwrite.c	2012-07-04 16:27:29 -0400
++++ pngwrite.c	2012-07-07 10:21:31 -0400
 @@ -53,16 +53,20 @@ png_write_info_before_PLTE(png_structp p
  #ifdef PNG_WRITE_INTERLACING_SUPPORTED
         info_ptr->interlace_type);
  #else
         0);
  #endif
     /* The rest of these check to see if the valid field has the appropriate
      * flag set, and if it does, writes the chunk.
@@ -1655,17 +1657,17 @@ diff -up8 pngwrite.c pngwrite.c
 +    png_ptr->num_frames_written++;
 +
 +    PNG_UNUSED(info_ptr)
 +}
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
  #endif /* PNG_WRITE_SUPPORTED */
 diff -up8 pngwutil.c pngwutil.c
 --- pngwutil.c	2012-06-14 07:28:00 -0400
-+++ pngwutil.c	2012-07-04 16:27:29 -0400
++++ pngwutil.c	2012-04-24 20:51:09 -0400
 @@ -816,16 +816,21 @@ png_write_IHDR(png_structp png_ptr, png_
     buf[9] = (png_byte)color_type;
     buf[10] = (png_byte)compression_type;
     buf[11] = (png_byte)filter_type;
     buf[12] = (png_byte)interlace_type;
  
     /* Write the chunk */
     png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
--- a/media/libpng/pngpread.c
+++ b/media/libpng/pngpread.c
@@ -1034,16 +1034,25 @@ png_push_read_IDAT(png_structp png_ptr)
 void /* PRIVATE */
 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
    png_size_t buffer_length)
 {
    /* The caller checks for a non-zero buffer length. */
    if (!(buffer_length > 0) || buffer == NULL)
       png_error(png_ptr, "No IDAT data (internal error)");
 
+#ifdef PNG_READ_APNG_SUPPORTED
+   /* If the app is not APNG-aware, decode only the first frame */
+   if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
+   {
+     png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+     return;
+   }
+#endif
+
    /* This routine must process all the data it has been given
     * before returning, calling the row callback as required to
     * handle the uncompressed results.
     */
    png_ptr->zstream.next_in = buffer;
    png_ptr->zstream.avail_in = (uInt)buffer_length;
 
    /* Keep going until the decompressed data is all processed
@@ -1487,16 +1496,17 @@ png_set_progressive_read_fn(png_structp 
 #ifdef PNG_READ_APNG_SUPPORTED
 void PNGAPI
 png_set_progressive_frame_fn(png_structp png_ptr,
    png_progressive_frame_ptr frame_info_fn,
    png_progressive_frame_ptr frame_end_fn)
 {
    png_ptr->frame_info_fn = frame_info_fn;
    png_ptr->frame_end_fn = frame_end_fn;
+   png_ptr->apng_flags |= PNG_APNG_APP;
 }
 #endif
 
 png_voidp PNGAPI
 png_get_progressive_ptr(png_const_structp png_ptr)
 {
    if (png_ptr == NULL)
       return (NULL);
--- a/media/libpng/pngpriv.h
+++ b/media/libpng/pngpriv.h
@@ -668,16 +668,17 @@ PNG_EXTERN png_fixed_point png_fixed PNG
 
 #ifdef PNG_APNG_SUPPORTED
 #define png_acTL PNG_CHUNK( 97,  99,  84,  76)
 #define png_fcTL PNG_CHUNK(102,  99,  84,  76)
 #define png_fdAT PNG_CHUNK(102, 100,  65,  84)
 
 /* For png_struct.apng_flags: */
 #define PNG_FIRST_FRAME_HIDDEN       0x0001
+#define PNG_APNG_APP                 0x0002
 #endif
 
 /* The following will work on (signed char*) strings, whereas the get_uint_32
  * macro will fail on top-bit-set values because of the sign extension.
  */
 #define PNG_CHUNK_FROM_STRING(s)\
    PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
 
--- a/media/libpng/pngread.c
+++ b/media/libpng/pngread.c
@@ -1044,25 +1044,16 @@ png_read_end(png_structp png_ptr, png_in
          png_handle_zTXt(png_ptr, info_ptr, length);
 #endif
 
 #ifdef PNG_READ_iTXt_SUPPORTED
       else if (chunk_name == png_iTXt)
          png_handle_iTXt(png_ptr, info_ptr, length);
 #endif
 
-#ifdef PNG_READ_APNG_SUPPORTED
-      else if (chunk_name == png_acTL)
-         png_handle_acTL(png_ptr, info_ptr, length);
-      else if (chunk_name == png_fcTL)
-         png_handle_fcTL(png_ptr, info_ptr, length);
-      else if (chunk_name == png_fdAT)
-         png_handle_fdAT(png_ptr, info_ptr, length);
-#endif
-
       else
          png_handle_unknown(png_ptr, info_ptr, length);
    } while (!(png_ptr->mode & PNG_HAVE_IEND));
 }
 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
 
 /* Free all memory used by the read */
 void PNGAPI