diff options
Diffstat (limited to 'abs/core/libpng')
-rw-r--r-- | abs/core/libpng/ChangeLog | 55 | ||||
-rw-r--r-- | abs/core/libpng/libpng-1.2.29-apng.patch | 1671 | ||||
-rw-r--r-- | abs/core/libpng/libpng-1.2.31-apng.patch | 1644 |
3 files changed, 0 insertions, 3370 deletions
diff --git a/abs/core/libpng/ChangeLog b/abs/core/libpng/ChangeLog deleted file mode 100644 index 98aa66d..0000000 --- a/abs/core/libpng/ChangeLog +++ /dev/null @@ -1,55 +0,0 @@ - -2008-10-06 Douglas Soares de Andrade <douglas@archlinux.org> - - * Updated for i686: 1.2.32 - -2008-08-23 Douglas Soares de Andrade <douglas@archlinux.org> - - * Updated for i686: 1.2.31 - * Thanks to Hussam Al-Tayeb - -2008-08-17 Douglas Soares de Andrade <douglas@archlinux.org> - - * Had to return to 1.2.29 because xul depends on - png with apng patch - -2008-08-17 Douglas Soares de Andrade <douglas@archlinux.org> - - * Updated for i686: 1.2.30 - * Fixes some security issues - * Remove the apng patch as there was no compatible version - for this version - -2008-07-04 Douglas Soares de Andrade <douglas@archlinux.org> - - * Updated for i686 - 1.2.29-1 - * Updated the apng patch for 1.2.29 - -2008-05-06 Travis Willard <travis@archlinux.org> - - * 1.2.28-1 - Upstream update - Uses same APNG patchset as 1.2.27 - -2008-05-01 Jan de Groot <jgc@archlinux.org> - - * 1.2.27-1 - Upstream update (security update!) - Fix APNG patchset to apply to 1.2.27 - Fix build with newer libtool versions - -2008-03-12 Travis Willard <travis@archlinux.org> - - * 1.2.25-1 - Upstream update - -2008-02-18 Travis Willard <travis@archlinux.org> - - * 1.2.24-3 - Corrected ChangeLog - -2008-02-18 Travis Willard <travis@archlinux.org> - - * 1.2.24-2 - Added ChangeLog - Added APNG patchset from <http://littlesvr.ca/apng/> diff --git a/abs/core/libpng/libpng-1.2.29-apng.patch b/abs/core/libpng/libpng-1.2.29-apng.patch deleted file mode 100644 index cc27ca3..0000000 --- a/abs/core/libpng/libpng-1.2.29-apng.patch +++ /dev/null @@ -1,1671 +0,0 @@ -Submitted By: Jens Ornot <oj_webstar@t-online.de> -Resubmitted by: Jens Ornot <oj_webstar@t-online.de> - Fix APNG patchset to apply to 1.2.27 -Date: 2008-05-24 -Initial Package Version: 1.2.10 -Upstream Status: Unknown -Origin: Andrew Smith -Description: APNG is an extension of the [PNG][pngspec] format, adding support for animated images. - It is intended to be a replacement for simple animated images - that have traditionally used the [GIF][gifspec] format, - while adding support for 24-bit images and 8-bit transparency. - APNG is a simpler alternative to MNG, - providing a spec suitable for the most common usage of animated images on the Internet. - - APNG is backwards-compatible with PNG; - any PNG decoder should be able to ignore the APNG-specific chunks and display a single image. - -diff -ruN libpng-1.2.27/png.c libpng-1.2.27.apng/png.c ---- libpng-1.2.27/png.c 2008-04-30 10:23:12.000000000 +0000 -+++ libpng-1.2.27.apng/png.c 2008-05-01 09:49:58.000000000 +0000 -@@ -51,6 +51,9 @@ - PNG_tIME; - PNG_tRNS; - PNG_zTXt; -+PNG_acTL; -+PNG_fcTL; -+PNG_fdAT; - - #ifdef PNG_READ_SUPPORTED - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ -diff -ruN libpng-1.2.27/png.h libpng-1.2.27.apng/png.h ---- libpng-1.2.27/png.h 2008-04-30 10:23:11.000000000 +0000 -+++ libpng-1.2.27.apng/png.h 2008-05-01 09:49:58.000000000 +0000 -@@ -958,6 +958,19 @@ - png_fixed_point int_y_blue; - #endif - -+#if defined(PNG_APNG_SUPPORTED) -+ png_uint_32 num_frames; /* including default image */ -+ png_uint_32 num_plays; -+ png_uint_32 next_frame_width; -+ png_uint_32 next_frame_height; -+ png_uint_32 next_frame_x_offset; -+ png_uint_32 next_frame_y_offset; -+ png_uint_16 next_frame_delay_num; -+ png_uint_16 next_frame_delay_den; -+ png_byte next_frame_dispose_op; -+ png_byte next_frame_blend_op; -+#endif -+ - } png_info; - - typedef png_info FAR * png_infop; -@@ -1059,6 +1072,8 @@ - #define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ - #define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ - #define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ -+#define PNG_INFO_acTL 0x10000L -+#define PNG_INFO_fcTL 0x20000L - - /* This is used for the transformation routines, as some of them - * change these values for the row. It also should enable using -@@ -1099,6 +1114,10 @@ - typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); - typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, - png_uint_32, int)); -+#if defined(PNG_APNG_SUPPORTED) -+typedef void (PNGAPI *png_progressive_frame_ptr) PNGARG((png_structp, -+ png_uint_32)); -+#endif - #endif - - #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ -@@ -1430,6 +1449,39 @@ - png_uint_32 user_height_max; - #endif - -+#if defined(PNG_APNG_SUPPORTED) -+ png_uint_32 apng_flags; -+ png_uint_32 next_seq_num; /* next fcTL/fdAT chunk sequence number */ -+ png_uint_32 first_frame_width; -+ png_uint_32 first_frame_height; -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_uint_32 num_frames_read; /* incremented after all image data of */ -+ /* a frame is read */ -+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -+ png_progressive_frame_ptr frame_info_fn; /* frame info read callback */ -+ png_progressive_frame_ptr frame_end_fn; /* frame data read callback */ -+#endif -+#endif -+ -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ png_uint_32 num_frames_to_write; -+ png_uint_32 num_frames_written; -+#endif -+#endif -+ -+/* For png_struct.apng_flags: */ -+#define PNG_FIRST_FRAME_HIDDEN 0x0001 -+ -+/* dispose_op flags from inside fcTL */ -+#define PNG_DISPOSE_OP_NONE 0x00 -+#define PNG_DISPOSE_OP_BACKGROUND 0x01 -+#define PNG_DISPOSE_OP_PREVIOUS 0x02 -+ -+/* blend_op flags from inside fcTL */ -+#define PNG_BLEND_OP_SOURCE 0x00 -+#define PNG_BLEND_OP_OVER 0x01 -+ - /* New member added in libpng-1.0.25 and 1.2.17 */ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - /* storage for unknown chunk that the library doesn't recognize. */ -@@ -1759,6 +1811,18 @@ - extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, - png_bytepp image)); - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+extern PNG_EXPORT (void,png_write_frame_head) PNGARG((png_structp png_ptr, -+ png_infop png_info, png_bytepp row_pointers, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op)); -+ -+extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr, -+ png_infop png_info)); -+#endif -+ - /* writes the end of the PNG file. */ - extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, - png_infop info_ptr)); -@@ -2007,6 +2071,11 @@ - png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn)); -+#if defined(PNG_READ_APNG_SUPPORTED) -+extern PNG_EXPORT(void,png_set_progressive_frame_fn) PNGARG((png_structp png_ptr, -+ png_progressive_frame_ptr frame_info_fn, -+ png_progressive_frame_ptr frame_end_fn)); -+#endif - - /* returns the user pointer associated with the push read functions */ - extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) -@@ -2444,6 +2513,59 @@ - #endif - #endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ - -+#if defined(PNG_APNG_SUPPORTED) -+extern PNG_EXPORT(png_uint_32,png_get_acTL) PNGARG((png_structp png_ptr, -+ png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays)); -+extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr, -+ png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays)); -+extern PNG_EXPORT(png_uint_32,png_get_num_frames) PNGARG((png_structp png_ptr, -+ png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_num_plays) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+ -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL) -+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, -+ png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset, -+ png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op, -+ png_byte *blend_op)); -+extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL) -+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width, -+ png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op)); -+extern PNG_EXPORT(void,png_ensure_fcTL_is_valid) -+ PNGARG((png_structp png_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_width) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_height) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_x_offset) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_y_offset) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_num) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_den) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_byte,png_get_next_frame_dispose_op) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_byte,png_get_next_frame_blend_op) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_byte,png_get_first_frame_is_hidden) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_set_first_frame_is_hidden) -+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_byte is_hidden)); -+#endif /* PNG_APNG_SUPPORTED */ -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+extern PNG_EXPORT(void,png_read_frame_head) PNGARG((png_structp png_ptr, -+ png_infop info_ptr)); -+#endif -+ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - /* provide a list of chunks and how they are to be handled, if the built-in - handling or default unknown chunk handling is not desired. Any chunks not -@@ -2750,6 +2872,8 @@ - #define PNG_BACKGROUND_IS_GRAY 0x800 - #define PNG_HAVE_PNG_SIGNATURE 0x1000 - #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ -+#define PNG_HAVE_acTL 0x4000 -+#define PNG_HAVE_fcTL 0x8000L - - /* flags for the transformations the PNG library does on the image data */ - #define PNG_BGR 0x0001 -@@ -2890,6 +3014,9 @@ - #define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} - #define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} - #define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} -+#define PNG_acTL png_byte png_acTL[5] = { 97, 99, 84, 76, '\0'} -+#define PNG_fcTL png_byte png_fcTL[5] = {102, 99, 84, 76, '\0'} -+#define PNG_fdAT png_byte png_fdAT[5] = {102, 100, 65, 84, '\0'} - - #ifdef PNG_USE_GLOBAL_ARRAYS - PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5]; -@@ -2913,6 +3040,9 @@ - PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5]; - PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5]; - PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5]; -+PNG_EXPORT_VAR (png_byte FARDATA) png_acTL[5]; -+PNG_EXPORT_VAR (png_byte FARDATA) png_fcTL[5]; -+PNG_EXPORT_VAR (png_byte FARDATA) png_fdAT[5]; - #endif /* PNG_USE_GLOBAL_ARRAYS */ - - #if defined(PNG_1_0_X) || defined (PNG_1_2_X) -@@ -3187,6 +3317,17 @@ - #endif - #endif - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr, -+ png_uint_32 num_frames, png_uint_32 num_plays)); -+ -+PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op)); -+#endif -+ - /* Called when finished processing a row of data */ - PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); - -@@ -3238,6 +3379,20 @@ - PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, - png_infop info_ptr)); - -+#if defined(PNG_READ_APNG_SUPPORTED) -+/* private, reset some things to become ready for reading next frame */ -+PNG_EXTERN void png_read_reset PNGARG((png_structp png_ptr)); -+PNG_EXTERN void png_read_reinit PNGARG((png_structp png_ptr, -+ png_infop info_ptr)); -+PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr)); -+#endif -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+/* private, reset some things to become ready for writing next frame */ -+PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr)); -+PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr, -+ png_infop info_ptr, png_uint_32 width, png_uint_32 height)); -+#endif -+ - /* these are the functions that do the transformations */ - #if defined(PNG_READ_FILLER_SUPPORTED) - PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, -@@ -3453,6 +3608,18 @@ - png_uint_32 length)); - #endif - -+#if defined(PNG_READ_APNG_SUPPORTED) -+PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 length)); -+PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 length)); -+PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr)); -+PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 length)); -+PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr, -+ png_uint_32 length)); -+#endif -+ - PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); - -diff -ruN libpng-1.2.27/pngconf.h libpng-1.2.27.apng/pngconf.h ---- libpng-1.2.27/pngconf.h 2008-04-30 10:23:11.000000000 +0000 -+++ libpng-1.2.27.apng/pngconf.h 2008-05-01 09:49:58.000000000 +0000 -@@ -925,6 +925,10 @@ - # define PNG_READ_zTXt_SUPPORTED - # define PNG_zTXt_SUPPORTED - #endif -+#ifndef PNG_NO_READ_APNG -+# define PNG_READ_APNG_SUPPORTED -+# define PNG_APNG_SUPPORTED -+#endif - #ifndef PNG_NO_READ_UNKNOWN_CHUNKS - # define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED -@@ -1067,6 +1071,12 @@ - # define PNG_zTXt_SUPPORTED - # endif - #endif -+#ifndef PNG_NO_WRITE_APNG -+# define PNG_WRITE_APNG_SUPPORTED -+# ifndef PNG_APNG_SUPPORTED -+# define PNG_APNG_SUPPORTED -+# endif -+#endif - #ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS - # define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED -diff -ruN libpng-1.2.27/pngget.c libpng-1.2.27.apng/pngget.c ---- libpng-1.2.27/pngget.c 2008-04-30 10:23:12.000000000 +0000 -+++ libpng-1.2.27.apng/pngget.c 2008-05-01 09:49:58.000000000 +0000 -@@ -797,6 +797,167 @@ - } - #endif - -+#if defined(PNG_APNG_SUPPORTED) -+png_uint_32 PNGAPI -+png_get_acTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 *num_frames, png_uint_32 *num_plays) -+{ -+ png_debug1(1, "in %s retrieval function\n", "acTL"); -+ -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_acTL) && -+ num_frames != NULL && num_plays != NULL) -+ { -+ *num_frames = info_ptr->num_frames; -+ *num_plays = info_ptr->num_plays; -+ return (1); -+ } -+ -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_num_frames(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_num_frames()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->num_frames); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_num_plays(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_num_plays()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->num_plays); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 *width, png_uint_32 *height, -+ png_uint_32 *x_offset, png_uint_32 *y_offset, -+ png_uint_16 *delay_num, png_uint_16 *delay_den, -+ png_byte *dispose_op, png_byte *blend_op) -+{ -+ png_debug1(1, "in %s retrieval function\n", "fcTL"); -+ -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_fcTL) && -+ width != NULL && height != NULL && -+ x_offset != NULL && x_offset != NULL && -+ delay_num != NULL && delay_den != NULL && -+ dispose_op != NULL && blend_op != NULL) -+ { -+ *width = info_ptr->next_frame_width; -+ *height = info_ptr->next_frame_height; -+ *x_offset = info_ptr->next_frame_x_offset; -+ *y_offset = info_ptr->next_frame_y_offset; -+ *delay_num = info_ptr->next_frame_delay_num; -+ *delay_den = info_ptr->next_frame_delay_den; -+ *dispose_op = info_ptr->next_frame_dispose_op; -+ *blend_op = info_ptr->next_frame_blend_op; -+ return (1); -+ } -+ -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_width()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_width); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_height()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_height); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_x_offset()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_x_offset); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_y_offset()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_y_offset); -+ return (0); -+} -+ -+png_uint_16 PNGAPI -+png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_delay_num()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_delay_num); -+ return (0); -+} -+ -+png_uint_16 PNGAPI -+png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_delay_den()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_delay_den); -+ return (0); -+} -+ -+png_byte PNGAPI -+png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_dispose_op()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_dispose_op); -+ return (0); -+} -+ -+png_byte PNGAPI -+png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_blend_op()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_blend_op); -+ return (0); -+} -+ -+png_byte PNGAPI -+png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_first_frame_is_hidden()\n"); -+ -+ if (png_ptr != NULL) -+ return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN); -+ -+ return 0; -+} -+#endif /* PNG_APNG_SUPPORTED */ -+ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - png_uint_32 PNGAPI - png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr, -diff -ruN libpng-1.2.27/pngpread.c libpng-1.2.27.apng/pngpread.c ---- libpng-1.2.27/pngpread.c 2008-04-30 10:23:12.000000000 +0000 -+++ libpng-1.2.27.apng/pngpread.c 2008-05-01 09:49:58.000000000 +0000 -@@ -192,6 +192,11 @@ - #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_CONST PNG_zTXt; - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_acTL; -+ PNG_CONST PNG_fcTL; -+ PNG_CONST PNG_fdAT; -+#endif - #endif /* PNG_USE_LOCAL_ARRAYS */ - /* 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 -@@ -215,7 +220,104 @@ - png_crc_read(png_ptr, png_ptr->chunk_name, 4); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - } -- -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_ptr->num_frames_read > 0 && -+ png_ptr->num_frames_read < info_ptr->num_frames) -+ { -+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+ { -+ /* discard trailing IDATs for the first frame */ -+ if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1) -+ png_error(png_ptr, "out of place IDAT"); -+ -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_push_crc_skip(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ if (png_ptr->buffer_size < 4) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_ensure_sequence_number(png_ptr, 4); -+ -+ if (!(png_ptr->mode & PNG_HAVE_fcTL)) -+ { -+ /* discard trailing fdATs for frames other than the first */ -+ if (png_ptr->num_frames_read < 2) -+ png_error(png_ptr, "out of place fdAT"); -+ -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_push_crc_skip(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ else -+ { -+ /* frame data follows */ -+ png_ptr->idat_size = png_ptr->push_length - 4; -+ png_ptr->mode |= PNG_HAVE_IDAT; -+ png_ptr->process_mode = PNG_READ_IDAT_MODE; -+ -+ return; -+ } -+ } -+ else if(!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ -+ png_read_reset(png_ptr); -+ png_ptr->mode &= ~PNG_HAVE_fcTL; -+ -+ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length); -+ -+ if (!(png_ptr->mode & PNG_HAVE_fcTL)) -+ png_error(png_ptr, "missing required fcTL chunk"); -+ -+ png_read_reinit(png_ptr, info_ptr); -+ png_progressive_read_reset(png_ptr); -+ -+ if (png_ptr->frame_info_fn != NULL) -+ (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read); -+ -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ -+ return; -+ } -+ else -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_warning(png_ptr, "Skipped (ignored) a chunk " -+ "between APNG chunks"); -+ png_push_crc_skip(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ -+ return; -+ } -+#endif /* PNG_READ_APNG_SUPPORTED */ -+ - if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) - if(png_ptr->mode & PNG_AFTER_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; -@@ -297,6 +399,9 @@ - png_error(png_ptr, "Too many IDAT's found"); - } - -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_have_info(png_ptr, info_ptr); -+#endif - png_ptr->idat_size = png_ptr->push_length; - png_ptr->mode |= PNG_HAVE_IDAT; - png_ptr->process_mode = PNG_READ_IDAT_MODE; -@@ -492,6 +597,35 @@ - png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); - } - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4)) -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length); -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ { -+ 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); -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_handle_fdAT(png_ptr, info_ptr, png_ptr->push_length); -+ } -+#endif /* PNG_READ_APNG_SUPPORTED */ - else - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) -@@ -662,13 +796,17 @@ - png_push_read_IDAT(png_structp png_ptr) - { - #ifdef PNG_USE_LOCAL_ARRAYS -- PNG_CONST PNG_IDAT; -+ PNG_IDAT; -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_fdAT; -+ PNG_IEND; -+#endif - #endif - if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) - { - png_byte chunk_length[4]; - -- if (png_ptr->buffer_size < 8) -+ if (png_ptr->buffer_size < 12) - { - png_push_save_buffer(png_ptr); - return; -@@ -680,15 +818,59 @@ - png_crc_read(png_ptr, png_ptr->chunk_name, 4); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - -- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_fdAT, 4) -+ && png_ptr->num_frames_read > 0) -+ { -+ if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) -+ { -+ png_ptr->process_mode = PNG_READ_CHUNK_MODE; -+ if (png_ptr->frame_end_fn != NULL) -+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); -+ png_ptr->num_frames_read++; -+ return; -+ } -+ else -+ { -+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) -+ png_error(png_ptr, "Not enough image data"); -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_warning(png_ptr, "Skipping (ignoring) a chunk between " -+ "APNG chunks"); -+ png_crc_finish(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ } -+ else -+#endif -+ if ( png_memcmp(png_ptr->chunk_name, png_IDAT, 4) -+ && (png_ptr->num_frames_read == 0) ) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - png_error(png_ptr, "Not enough compressed data"); -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_ptr->frame_end_fn != NULL) -+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); -+ png_ptr->num_frames_read++; -+#endif - return; - } - - png_ptr->idat_size = png_ptr->push_length; -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if(png_ptr->num_frames_read > 0) -+ { -+ png_ensure_sequence_number(png_ptr, 4); -+ png_ptr->idat_size -= 4; -+ } -+#endif - } - if (png_ptr->idat_size && png_ptr->save_buffer_size) - { -@@ -1589,6 +1771,17 @@ - png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); - } - -+#if defined(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; -+} -+#endif -+ - png_voidp PNGAPI - png_get_progressive_ptr(png_structp png_ptr) - { -diff -ruN libpng-1.2.27/pngread.c libpng-1.2.27.apng/pngread.c ---- libpng-1.2.27/pngread.c 2008-04-30 10:23:12.000000000 +0000 -+++ libpng-1.2.27.apng/pngread.c 2008-05-01 09:49:58.000000000 +0000 -@@ -405,6 +405,11 @@ - #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_CONST PNG_zTXt; - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_acTL; -+ PNG_CONST PNG_fcTL; -+ PNG_CONST PNG_fdAT; -+#endif - #endif /* PNG_USE_LOCAL_ARRAYS */ - png_byte chunk_length[4]; - png_uint_32 length; -@@ -458,6 +463,9 @@ - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); - -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_have_info(png_ptr, info_ptr); -+#endif - png_ptr->idat_size = length; - png_ptr->mode |= PNG_HAVE_IDAT; - break; -@@ -530,12 +538,97 @@ - else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) - png_handle_iTXt(png_ptr, info_ptr, length); - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4)) -+ png_handle_acTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ png_handle_fcTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ png_handle_fdAT(png_ptr, info_ptr, length); -+#endif - else - png_handle_unknown(png_ptr, info_ptr, length); - } - } - #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ - -+#if defined(PNG_READ_APNG_SUPPORTED) -+void PNGAPI -+png_read_frame_head(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */ -+ -+ png_debug(0, "Reading frame head\n"); -+ -+ if (!(png_ptr->mode & PNG_HAVE_acTL)) -+ png_error(png_ptr, "attempt to png_read_frame_head() but " -+ "no acTL present"); -+ -+ /* do nothing for the main IDAT */ -+ if (png_ptr->num_frames_read == 0) -+ return; -+ -+ png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */ -+ -+ png_read_reset(png_ptr); -+ png_ptr->mode &= ~PNG_HAVE_fcTL; -+ -+ have_chunk_after_DAT = 0; -+ for (;;) -+ { -+#ifdef PNG_USE_LOCAL_ARRAYS -+ PNG_IDAT; -+ PNG_fdAT; -+ PNG_fcTL; -+#endif -+ png_byte chunk_length[4]; -+ png_uint_32 length; -+ -+ png_read_data(png_ptr, chunk_length, 4); -+ length = png_get_uint_31(png_ptr, chunk_length); -+ -+ png_reset_crc(png_ptr); -+ png_crc_read(png_ptr, png_ptr->chunk_name, 4); -+ -+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+ { -+ /* discard trailing IDATs for the first frame */ -+ if (have_chunk_after_DAT || png_ptr->num_frames_read > 1) -+ png_error(png_ptr, "png_read_frame_head(): out of place IDAT"); -+ png_crc_finish(png_ptr, length); -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ { -+ png_handle_fcTL(png_ptr, info_ptr, length); -+ have_chunk_after_DAT = 1; -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ png_ensure_sequence_number(png_ptr, length); -+ -+ /* discard trailing fdATs for frames other than the first */ -+ if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1) -+ png_crc_finish(png_ptr, length - 4); -+ else if(png_ptr->mode & PNG_HAVE_fcTL) -+ { -+ png_ptr->idat_size = length - 4; -+ png_ptr->mode |= PNG_HAVE_IDAT; -+ -+ break; -+ } -+ else -+ png_error(png_ptr, "png_read_frame_head(): out of place fdAT"); -+ } -+ else -+ { -+ png_warning(png_ptr, "Skipped (ignored) a chunk " -+ "between APNG chunks"); -+ png_crc_finish(png_ptr, length); -+ } -+ } -+} -+#endif /* PNG_READ_APNG_SUPPORTED */ -+ - /* optional call to update the users info_ptr structure */ - void PNGAPI - png_read_update_info(png_structp png_ptr, png_infop info_ptr) -@@ -572,6 +665,10 @@ - { - #ifdef PNG_USE_LOCAL_ARRAYS - PNG_CONST PNG_IDAT; -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_fdAT; -+ PNG_CONST PNG_IEND; -+#endif - PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, - 0xff}; - PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; -@@ -701,19 +798,46 @@ - { - if (!(png_ptr->zstream.avail_in)) - { -- while (!png_ptr->idat_size) -+ png_uint_32 bytes_to_skip = 0; -+ -+ while (!png_ptr->idat_size || bytes_to_skip != 0) - { - png_byte chunk_length[4]; - -- png_crc_finish(png_ptr, 0); -- -+ png_crc_finish(png_ptr, bytes_to_skip); -+ bytes_to_skip = 0; -+ - png_read_data(png_ptr, chunk_length, 4); - png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length); -- -+ - png_reset_crc(png_ptr); - png_crc_read(png_ptr, png_ptr->chunk_name, 4); -- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -- png_error(png_ptr, "Not enough image data"); -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_ptr->num_frames_read == 0) -+ { -+#endif -+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+ png_error(png_ptr, "Not enough image data"); -+#if defined(PNG_READ_APNG_SUPPORTED) -+ } -+ else -+ { -+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) -+ png_error(png_ptr, "Not enough image data"); -+ if (png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ png_warning(png_ptr, "Skipped (ignored) a chunk " -+ "between APNG chunks"); -+ bytes_to_skip = png_ptr->idat_size; -+ continue; -+ } -+ -+ png_ensure_sequence_number(png_ptr, png_ptr->idat_size); -+ -+ png_ptr->idat_size -= 4; -+ } -+#endif - } - png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_in = png_ptr->zbuf; -@@ -731,6 +855,9 @@ - png_error(png_ptr, "Extra compressed data"); - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_ptr->num_frames_read++; -+#endif - break; - } - if (ret != Z_OK) -@@ -985,6 +1112,11 @@ - #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_CONST PNG_zTXt; - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_acTL; -+ PNG_CONST PNG_fcTL; -+ PNG_CONST PNG_fdAT; -+#endif - #endif /* PNG_USE_LOCAL_ARRAYS */ - - png_read_data(png_ptr, chunk_length, 4); -@@ -1091,6 +1223,14 @@ - else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) - png_handle_iTXt(png_ptr, info_ptr, length); - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4)) -+ png_handle_acTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ png_handle_fcTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ 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)); -diff -ruN libpng-1.2.27/pngrtran.c libpng-1.2.27.apng/pngrtran.c ---- libpng-1.2.27/pngrtran.c 2008-04-30 10:23:13.000000000 +0000 -+++ libpng-1.2.27.apng/pngrtran.c 2008-05-01 09:49:58.000000000 +0000 -@@ -1286,7 +1286,7 @@ - * or png_read_update_info() after setting transforms that expand - * pixels. This check added to libpng-1.2.19 */ - #if (PNG_WARN_UNINITIALIZED_ROW==1) -- png_error(png_ptr, "Uninitialized row"); -+ png_warning(png_ptr, "Uninitialized row"); - #else - png_warning(png_ptr, "Uninitialized row"); - #endif -diff -ruN libpng-1.2.27/pngrutil.c libpng-1.2.27.apng/pngrutil.c ---- libpng-1.2.27/pngrutil.c 2008-04-30 10:23:13.000000000 +0000 -+++ libpng-1.2.27.apng/pngrutil.c 2008-05-01 09:49:58.000000000 +0000 -@@ -374,6 +374,11 @@ - filter_type = buf[11]; - interlace_type = buf[12]; - -+#if defined(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; -@@ -2169,6 +2174,168 @@ - } - #endif - -+#if defined(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]; -+ png_uint_32 num_frames; -+ png_uint_32 num_plays; -+ png_uint_32 didSet; -+ -+ png_debug(1, "in png_handle_acTL\n"); -+ -+ if (!(png_ptr->mode & PNG_HAVE_IHDR)) -+ { -+ png_error(png_ptr, "Missing IHDR before acTL"); -+ } -+ else if (png_ptr->mode & PNG_HAVE_IDAT) -+ { -+ png_warning(png_ptr, "Invalid acTL after IDAT skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (png_ptr->mode & PNG_HAVE_acTL) -+ { -+ png_warning(png_ptr, "Duplicate acTL skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (length != 8) -+ { -+ png_warning(png_ptr, "acTL with invalid length skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ -+ png_crc_read(png_ptr, data, 8); -+ png_crc_finish(png_ptr, 0); -+ -+ num_frames = png_get_uint_31(png_ptr, data); -+ num_plays = png_get_uint_31(png_ptr, data + 4); -+ -+ /* the set function will do error checking on num_frames */ -+ didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays); -+ if(didSet) -+ png_ptr->mode |= PNG_HAVE_acTL; -+} -+ -+void /* PRIVATE */ -+png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+{ -+ png_byte data[22]; -+ png_uint_32 width; -+ png_uint_32 height; -+ png_uint_32 x_offset; -+ png_uint_32 y_offset; -+ png_uint_16 delay_num; -+ png_uint_16 delay_den; -+ png_byte dispose_op; -+ png_byte blend_op; -+ -+ png_debug(1, "in png_handle_fcTL\n"); -+ -+ if (!(png_ptr->mode & PNG_HAVE_IHDR)) -+ { -+ png_error(png_ptr, "Missing IHDR before fcTL"); -+ } -+ else if (png_ptr->mode & PNG_HAVE_IDAT) -+ { -+ /* for any frames other then the first this message may be misleading, -+ * but correct. PNG_HAVE_IDAT is unset before the frame head is read -+ * i can't think of a better message */ -+ png_warning(png_ptr, "Invalid fcTL after IDAT skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (png_ptr->mode & PNG_HAVE_fcTL) -+ { -+ png_warning(png_ptr, "Duplicate fcTL within one frame skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (length != 26) -+ { -+ png_warning(png_ptr, "fcTL with invalid length skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ -+ png_ensure_sequence_number(png_ptr, length); -+ -+ png_crc_read(png_ptr, data, 22); -+ png_crc_finish(png_ptr, 0); -+ -+ width = png_get_uint_31(png_ptr, data); -+ height = png_get_uint_31(png_ptr, data + 4); -+ x_offset = png_get_uint_31(png_ptr, data + 8); -+ y_offset = png_get_uint_31(png_ptr, data + 12); -+ delay_num = png_get_uint_16(data + 16); -+ delay_den = png_get_uint_16(data + 18); -+ dispose_op = data[20]; -+ blend_op = data[21]; -+ -+ if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0)) -+ png_error(png_ptr, "fcTL for the first frame must have zero offset"); -+ if (png_ptr->num_frames_read == 0 && -+ (width != info_ptr->width || height != info_ptr->height)) -+ png_error(png_ptr, "size in first frame's fcTL must match " -+ "the size in IHDR"); -+ -+ /* the set function will do more error checking */ -+ png_set_next_frame_fcTL(png_ptr, info_ptr, width, height, -+ x_offset, y_offset, delay_num, delay_den, -+ dispose_op, blend_op); -+ -+ png_read_reinit(png_ptr, info_ptr); -+ -+ png_ptr->mode |= PNG_HAVE_fcTL; -+} -+ -+void /* PRIVATE */ -+png_have_info(png_structp png_ptr, png_infop info_ptr) -+{ -+ if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL)) -+ { -+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN; -+ info_ptr->num_frames++; -+ } -+} -+ -+void /* PRIVATE */ -+png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+{ -+ png_ensure_sequence_number(png_ptr, length); -+ -+ /* This function is only called from png_read_end(), png_read_info(), -+ * and png_push_read_chunk() which means that: -+ * - the user doesn't want to read this frame -+ * - or this is an out-of-place fdAT -+ * in either case it is safe to ignore the chunk with a warning */ -+ png_warning(png_ptr, "ignoring fdAT chunk"); -+ png_crc_finish(png_ptr, length - 4); -+} -+ -+void /* PRIVATE */ -+png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length) -+{ -+ png_byte data[4]; -+ png_uint_32 sequence_number; -+ -+ if (length < 4) -+ png_error(png_ptr, "invalid fcTL or fdAT chunk found"); -+ -+ png_crc_read(png_ptr, data, 4); -+ sequence_number = png_get_uint_31(png_ptr, data); -+ -+ if (sequence_number != png_ptr->next_seq_num) -+ png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence " -+ "number found"); -+ -+ png_ptr->next_seq_num++; -+} -+#endif /* PNG_READ_APNG_SUPPORTED */ -+ - /* This function is called when we haven't found a handler for a - chunk. If there isn't a problem with the chunk itself (ie bad - chunk name, CRC, or a critical chunk), the chunk is silently ignored -@@ -3180,4 +3347,82 @@ - - png_ptr->flags |= PNG_FLAG_ROW_INIT; - } -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+/* This function is to be called after the main IDAT set has been read and -+ * before a new IDAT is read. It resets some parts of png_ptr -+ * to make them usable by the read functions again */ -+void /* PRIVATE */ -+png_read_reset(png_structp png_ptr) -+{ -+ png_ptr->mode &= ~PNG_HAVE_IDAT; -+ png_ptr->mode &= ~PNG_AFTER_IDAT; -+ png_ptr->row_number = 0; -+ png_ptr->pass = 0; -+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -+} -+ -+void /* PRIVATE */ -+png_read_reinit(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_ptr->width = info_ptr->next_frame_width; -+ png_ptr->height = info_ptr->next_frame_height; -+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); -+} -+ -+/* same as png_read_reset() but for the progressive reader */ -+void /* PRIVATE */ -+png_progressive_read_reset(png_structp png_ptr) -+{ -+#ifdef PNG_USE_LOCAL_ARRAYS -+ /* start of interlace block */ -+ const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; -+ -+ /* offset to next interlace block */ -+ const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; -+ -+ /* start of interlace block in the y direction */ -+ const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; -+ -+ /* offset to next interlace block in the y direction */ -+ const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; -+#endif -+ png_uint_32 row_bytes; -+ -+ if (png_ptr->interlaced) -+ { -+ if (!(png_ptr->transformations & PNG_INTERLACE)) -+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - -+ png_pass_ystart[0]) / png_pass_yinc[0]; -+ else -+ png_ptr->num_rows = png_ptr->height; -+ -+ png_ptr->iwidth = (png_ptr->width + -+ png_pass_inc[png_ptr->pass] - 1 - -+ png_pass_start[png_ptr->pass]) / -+ png_pass_inc[png_ptr->pass]; -+ -+ row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1; -+ -+ png_ptr->irowbytes = (png_size_t)row_bytes; -+ if((png_uint_32)png_ptr->irowbytes != row_bytes) -+ png_error(png_ptr, "png_progressive_read_reset(): Rowbytes " -+ "overflow"); -+ } -+ else -+ { -+ png_ptr->num_rows = png_ptr->height; -+ png_ptr->iwidth = png_ptr->width; -+ png_ptr->irowbytes = png_ptr->rowbytes + 1; -+ } -+ -+ png_ptr->flags &= ~PNG_FLAG_ZLIB_FINISHED; -+ if (inflateReset(&(png_ptr->zstream)) != Z_OK) -+ png_error(png_ptr, "inflateReset failed"); -+ png_ptr->zstream.avail_in = 0; -+ png_ptr->zstream.next_in = 0; -+ png_ptr->zstream.next_out = png_ptr->row_buf; -+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; -+} -+#endif /* PNG_READ_APNG_SUPPORTED */ - #endif /* PNG_READ_SUPPORTED */ -diff -ruN libpng-1.2.27/pngset.c libpng-1.2.27.apng/pngset.c ---- libpng-1.2.27/pngset.c 2008-04-30 10:23:13.000000000 +0000 -+++ libpng-1.2.27.apng/pngset.c 2008-05-01 09:49:58.000000000 +0000 -@@ -364,6 +364,11 @@ - info_ptr->rowbytes = (png_size_t)0; - else - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width); -+ -+#if defined(PNG_APNG_SUPPORTED) -+ /* for non-animated png. this may be overritten from an acTL chunk later */ -+ info_ptr->num_frames = 1; -+#endif - } - - #if defined(PNG_oFFs_SUPPORTED) -@@ -1025,6 +1030,141 @@ - } - #endif /* PNG_sPLT_SUPPORTED */ - -+#if defined(PNG_APNG_SUPPORTED) -+png_uint_32 PNGAPI -+png_set_acTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 num_frames, png_uint_32 num_plays) -+{ -+ png_debug1(1, "in %s storage function\n", "acTL"); -+ -+ if (png_ptr == NULL || info_ptr == NULL) -+ { -+ png_warning(png_ptr, -+ "Call to png_set_acTL() with NULL png_ptr " -+ "or info_ptr ignored"); -+ return (0); -+ } -+ if (num_frames == 0) -+ { -+ png_warning(png_ptr, -+ "Ignoring attempt to set acTL with num_frames zero"); -+ return (0); -+ } -+ if (num_frames > PNG_UINT_31_MAX) -+ { -+ png_warning(png_ptr, -+ "Ignoring attempt to set acTL with num_frames > 2^31-1"); -+ return (0); -+ } -+ if (num_plays > PNG_UINT_31_MAX) -+ { -+ png_warning(png_ptr, -+ "Ignoring attempt to set acTL with num_plays " -+ "> 2^31-1"); -+ return (0); -+ } -+ -+ info_ptr->num_frames = num_frames; -+ info_ptr->num_plays = num_plays; -+ -+ info_ptr->valid |= PNG_INFO_acTL; -+ -+ return (1); -+} -+ -+/* delay_num and delay_den can hold any 16-bit values including zero */ -+png_uint_32 PNGAPI -+png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op) -+{ -+ png_debug1(1, "in %s storage function\n", "fcTL"); -+ -+ if (png_ptr == NULL || info_ptr == NULL) -+ { -+ png_warning(png_ptr, -+ "Call to png_set_fcTL() with NULL png_ptr or info_ptr " -+ "ignored"); -+ return (0); -+ } -+ -+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, -+ delay_num, delay_den, dispose_op, blend_op); -+ -+ info_ptr->next_frame_width = width; -+ info_ptr->next_frame_height = height; -+ info_ptr->next_frame_x_offset = x_offset; -+ info_ptr->next_frame_y_offset = y_offset; -+ info_ptr->next_frame_delay_num = delay_num; -+ info_ptr->next_frame_delay_den = delay_den; -+ info_ptr->next_frame_dispose_op = dispose_op; -+ info_ptr->next_frame_blend_op = blend_op; -+ -+ info_ptr->valid |= PNG_INFO_fcTL; -+ -+ return (1); -+} -+ -+void /* PRIVATE */ -+png_ensure_fcTL_is_valid(png_structp png_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op) -+{ -+ if (width + x_offset > png_ptr->first_frame_width || -+ height + y_offset > png_ptr->first_frame_height) -+ png_error(png_ptr, "dimensions of a frame are greater than" -+ "the ones in IHDR"); -+ if (width > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid width in fcTL (> 2^31-1)"); -+ if (height > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid height in fcTL (> 2^31-1)"); -+ if (x_offset > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)"); -+ if (y_offset > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)"); -+ -+ if (dispose_op != PNG_DISPOSE_OP_NONE && -+ dispose_op != PNG_DISPOSE_OP_BACKGROUND && -+ dispose_op != PNG_DISPOSE_OP_PREVIOUS) -+ png_error(png_ptr, "invalid dispose_op in fcTL"); -+ -+ if (blend_op != PNG_BLEND_OP_SOURCE && -+ blend_op != PNG_BLEND_OP_OVER) -+ png_error(png_ptr, "invalid blend_op in fcTL"); -+ -+ if (blend_op == PNG_BLEND_OP_OVER) { -+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) -+ png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for " -+ "color type 'greyscale without alpha'"); -+ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) && -+ !(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)) -+ png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for " -+ "color type 'truecolor without alpha'"); -+ } -+} -+ -+png_uint_32 PNGAPI -+png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr, -+ png_byte is_hidden) -+{ -+ png_debug(1, "in png_first_frame_is_hidden()\n"); -+ -+ if (png_ptr == NULL) -+ return 0; -+ -+ if(is_hidden) -+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN; -+ else -+ png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN; -+ -+ return 1; -+} -+#endif /* PNG_APNG_SUPPORTED */ -+ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - void PNGAPI - png_set_unknown_chunks(png_structp png_ptr, -diff -ruN libpng-1.2.27/pngtrans.c libpng-1.2.27.apng/pngtrans.c ---- libpng-1.2.27/pngtrans.c 2008-04-30 10:23:14.000000000 +0000 -+++ libpng-1.2.27.apng/pngtrans.c 2008-05-01 09:49:58.000000000 +0000 -@@ -652,11 +652,10 @@ - png_voidp PNGAPI - png_get_user_transform_ptr(png_structp png_ptr) - { --#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) - if (png_ptr == NULL) return (NULL); -+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) - return ((png_voidp)png_ptr->user_transform_ptr); --#else -- return (NULL); - #endif -+ return (NULL); - } - #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ -diff -ruN libpng-1.2.27/pngwrite.c libpng-1.2.27.apng/pngwrite.c ---- libpng-1.2.27/pngwrite.c 2008-04-30 10:23:14.000000000 +0000 -+++ libpng-1.2.27.apng/pngwrite.c 2008-05-01 09:49:58.000000000 +0000 -@@ -263,6 +263,10 @@ - } - } - #endif -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ if (info_ptr->valid & PNG_INFO_acTL) -+ png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays); -+#endif - #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) - if (info_ptr->unknown_chunks_num) - { -@@ -301,6 +305,10 @@ - return; - if (!(png_ptr->mode & PNG_HAVE_IDAT)) - png_error(png_ptr, "No IDATs written into file"); -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ if (png_ptr->num_frames_written != png_ptr->num_frames_to_write) -+ png_error(png_ptr, "Not enough frames written"); -+#endif - - /* see if user wants us to write information chunks */ - if (info_ptr != NULL) -@@ -1529,4 +1537,39 @@ - params = params; - } - #endif -+ -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+void PNGAPI -+png_write_frame_head(png_structp png_ptr, png_infop info_ptr, -+ png_bytepp row_pointers, png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op) -+{ -+ png_debug(1, "in png_write_frame_head\n"); -+ -+ /* there is a chance this has been set after png_write_info was called, -+ * so it would be set but not written. is there a way to be sure? */ -+ if (!(info_ptr->valid & PNG_INFO_acTL)) -+ png_error(png_ptr, "png_write_frame_head(): acTL not set"); -+ -+ png_write_reset(png_ptr); -+ -+ png_write_reinit(png_ptr, info_ptr, width, height); -+ -+ if ( !(png_ptr->num_frames_written == 0 && -+ (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) ) -+ png_write_fcTL(png_ptr, width, height, x_offset, y_offset, -+ delay_num, delay_den, dispose_op, blend_op); -+} -+ -+void PNGAPI -+png_write_frame_tail(png_structp png_ptr, png_infop png_info) -+{ -+ png_debug(1, "in png_write_frame_tail\n"); -+ -+ png_ptr->num_frames_written++; -+} -+#endif /* PNG_WRITE_APNG_SUPPORTED */ -+ - #endif /* PNG_WRITE_SUPPORTED */ -diff -ruN libpng-1.2.27/pngwutil.c libpng-1.2.27.apng/pngwutil.c ---- libpng-1.2.27/pngwutil.c 2008-04-30 10:23:14.000000000 +0000 -+++ libpng-1.2.27.apng/pngwutil.c 2008-05-01 09:49:58.000000000 +0000 -@@ -498,6 +498,11 @@ - /* write the chunk */ - png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ png_ptr->first_frame_width = width; -+ png_ptr->first_frame_height = height; -+#endif -+ - /* initialize zlib with PNG info */ - png_ptr->zstream.zalloc = png_zalloc; - png_ptr->zstream.zfree = png_zfree; -@@ -619,6 +624,9 @@ - { - #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IDAT; -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ PNG_fdAT; -+#endif - #endif - png_debug(1, "in png_write_IDAT\n"); - -@@ -661,7 +669,28 @@ - "Invalid zlib compression method or flags in IDAT"); - } - -- png_write_chunk(png_ptr, png_IDAT, data, length); -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ if(png_ptr->num_frames_written == 0) -+#endif -+ png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ else -+ { -+ png_byte buf[4]; -+ -+ png_write_chunk_start(png_ptr, (png_bytep)png_fdAT, 4 + length); -+ -+ png_save_uint_32(buf, png_ptr->next_seq_num); -+ png_write_chunk_data(png_ptr, buf, 4); -+ -+ png_write_chunk_data(png_ptr, data, length); -+ -+ png_write_chunk_end(png_ptr); -+ -+ png_ptr->next_seq_num++; -+ } -+#endif -+ - png_ptr->mode |= PNG_HAVE_IDAT; - } - -@@ -673,7 +702,7 @@ - PNG_IEND; - #endif - png_debug(1, "in png_write_IEND\n"); -- png_write_chunk(png_ptr, png_IEND, png_bytep_NULL, -+ png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, - (png_size_t)0); - png_ptr->mode |= PNG_HAVE_IEND; - } -@@ -1732,6 +1761,70 @@ - } - #endif - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+void /* PRIVATE */ -+png_write_acTL(png_structp png_ptr, -+ png_uint_32 num_frames, png_uint_32 num_plays) -+{ -+#ifdef PNG_USE_LOCAL_ARRAYS -+ PNG_acTL; -+#endif -+ png_byte data[16]; -+ -+ png_debug(1, "in png_write_acTL\n"); -+ -+ png_ptr->num_frames_to_write = num_frames; -+ -+ if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) -+ num_frames--; -+ -+ png_save_uint_32(data, num_frames); -+ png_save_uint_32(data + 4, num_plays); -+ -+ png_write_chunk(png_ptr, (png_bytep)png_acTL, data, (png_size_t)8); -+} -+ -+void /* PRIVATE */ -+png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op) -+{ -+#ifdef PNG_USE_LOCAL_ARRAYS -+ PNG_fcTL; -+#endif -+ png_byte data[26]; -+ -+ png_debug(1, "in png_write_fcTL\n"); -+ -+ if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0)) -+ png_error(png_ptr, "x and/or y offset for the first frame aren't 0\n"); -+ if (png_ptr->num_frames_written == 0 && -+ (width != png_ptr->first_frame_width || -+ height != png_ptr->first_frame_height)) -+ png_error(png_ptr, "width and/or height in the first frame's fcTL " -+ "don't match the ones in IHDR\n"); -+ -+ /* more error checking */ -+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, -+ delay_num, delay_den, dispose_op, blend_op); -+ -+ png_save_uint_32(data, png_ptr->next_seq_num); -+ png_save_uint_32(data + 4, width); -+ png_save_uint_32(data + 8, height); -+ png_save_uint_32(data + 12, x_offset); -+ png_save_uint_32(data + 16, y_offset); -+ png_save_uint_16(data + 20, delay_num); -+ png_save_uint_16(data + 22, delay_den); -+ data[24] = dispose_op; -+ data[25] = blend_op; -+ -+ png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)26); -+ -+ png_ptr->next_seq_num++; -+} -+#endif /* PNG_WRITE_APNG_SUPPORTED */ -+ - /* initializes the row writing capability of libpng */ - void /* PRIVATE */ - png_write_start_row(png_structp png_ptr) -@@ -2799,4 +2892,39 @@ - } - #endif - } -+ -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+void /* PRIVATE */ -+png_write_reset(png_structp png_ptr) -+{ -+ png_ptr->row_number = 0; -+ png_ptr->pass = 0; -+ png_ptr->mode &= ~PNG_HAVE_IDAT; -+} -+ -+void /* PRIVATE */ -+png_write_reinit(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 width, png_uint_32 height) -+{ -+ if (png_ptr->num_frames_written == 0 && -+ (width != png_ptr->first_frame_width || -+ height != png_ptr->first_frame_height)) -+ png_error(png_ptr, "width and/or height in the first frame's fcTL " -+ "don't match the ones in IHDR\n"); -+ if (width > png_ptr->first_frame_width || -+ height > png_ptr->first_frame_height) -+ png_error(png_ptr, "width and/or height for a frame greater than" -+ "the ones in IHDR"); -+ -+ png_set_IHDR(png_ptr, info_ptr, width, height, -+ info_ptr->bit_depth, info_ptr->color_type, -+ info_ptr->interlace_type, info_ptr->compression_type, -+ info_ptr->filter_type); -+ -+ png_ptr->width = width; -+ png_ptr->height = height; -+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); -+ png_ptr->usr_width = png_ptr->width; -+} -+#endif - #endif /* PNG_WRITE_SUPPORTED */ diff --git a/abs/core/libpng/libpng-1.2.31-apng.patch b/abs/core/libpng/libpng-1.2.31-apng.patch deleted file mode 100644 index 92bd20a..0000000 --- a/abs/core/libpng/libpng-1.2.31-apng.patch +++ /dev/null @@ -1,1644 +0,0 @@ -Index: pngread.c -=================================================================== ---- pngread.c (révision 149) -+++ pngread.c (copie de travail) -@@ -407,6 +407,11 @@ - #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_CONST PNG_zTXt; - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_acTL; -+ PNG_CONST PNG_fcTL; -+ PNG_CONST PNG_fdAT; -+#endif - #endif /* PNG_USE_LOCAL_ARRAYS */ - png_uint_32 length = png_read_chunk_header(png_ptr); - PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; -@@ -451,6 +456,9 @@ - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); - -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_have_info(png_ptr, info_ptr); -+#endif - png_ptr->idat_size = length; - png_ptr->mode |= PNG_HAVE_IDAT; - break; -@@ -523,12 +531,97 @@ - else if (!png_memcmp(chunk_name, png_iTXt, 4)) - png_handle_iTXt(png_ptr, info_ptr, length); - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4)) -+ png_handle_acTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ png_handle_fcTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ png_handle_fdAT(png_ptr, info_ptr, length); -+#endif - else - png_handle_unknown(png_ptr, info_ptr, length); - } - } - #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ - -+#if defined(PNG_READ_APNG_SUPPORTED) -+void PNGAPI -+png_read_frame_head(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */ -+ -+ png_debug(0, "Reading frame head\n"); -+ -+ if (!(png_ptr->mode & PNG_HAVE_acTL)) -+ png_error(png_ptr, "attempt to png_read_frame_head() but " -+ "no acTL present"); -+ -+ /* do nothing for the main IDAT */ -+ if (png_ptr->num_frames_read == 0) -+ return; -+ -+ png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */ -+ -+ png_read_reset(png_ptr); -+ png_ptr->mode &= ~PNG_HAVE_fcTL; -+ -+ have_chunk_after_DAT = 0; -+ for (;;) -+ { -+#ifdef PNG_USE_LOCAL_ARRAYS -+ PNG_IDAT; -+ PNG_fdAT; -+ PNG_fcTL; -+#endif -+ png_byte chunk_length[4]; -+ png_uint_32 length; -+ -+ png_read_data(png_ptr, chunk_length, 4); -+ length = png_get_uint_31(png_ptr, chunk_length); -+ -+ png_reset_crc(png_ptr); -+ png_crc_read(png_ptr, png_ptr->chunk_name, 4); -+ -+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+ { -+ /* discard trailing IDATs for the first frame */ -+ if (have_chunk_after_DAT || png_ptr->num_frames_read > 1) -+ png_error(png_ptr, "png_read_frame_head(): out of place IDAT"); -+ png_crc_finish(png_ptr, length); -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ { -+ png_handle_fcTL(png_ptr, info_ptr, length); -+ have_chunk_after_DAT = 1; -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ png_ensure_sequence_number(png_ptr, length); -+ -+ /* discard trailing fdATs for frames other than the first */ -+ if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1) -+ png_crc_finish(png_ptr, length - 4); -+ else if(png_ptr->mode & PNG_HAVE_fcTL) -+ { -+ png_ptr->idat_size = length - 4; -+ png_ptr->mode |= PNG_HAVE_IDAT; -+ -+ break; -+ } -+ else -+ png_error(png_ptr, "png_read_frame_head(): out of place fdAT"); -+ } -+ else -+ { -+ png_warning(png_ptr, "Skipped (ignored) a chunk " -+ "between APNG chunks"); -+ png_crc_finish(png_ptr, length); -+ } -+ } -+} -+#endif /* PNG_READ_APNG_SUPPORTED */ -+ - /* optional call to update the users info_ptr structure */ - void PNGAPI - png_read_update_info(png_structp png_ptr, png_infop info_ptr) -@@ -565,6 +658,10 @@ - { - #ifdef PNG_USE_LOCAL_ARRAYS - PNG_CONST PNG_IDAT; -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_fdAT; -+ PNG_CONST PNG_IEND; -+#endif - PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, - 0xff}; - PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; -@@ -694,13 +791,40 @@ - { - if (!(png_ptr->zstream.avail_in)) - { -- while (!png_ptr->idat_size) -+ png_uint_32 bytes_to_skip = 0; -+ -+ while (!png_ptr->idat_size || bytes_to_skip != 0) - { -- png_crc_finish(png_ptr, 0); -+ png_crc_finish(png_ptr, bytes_to_skip); -+ bytes_to_skip = 0; - - png_ptr->idat_size = png_read_chunk_header(png_ptr); -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_ptr->num_frames_read == 0) -+ { -+#endif - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) - png_error(png_ptr, "Not enough image data"); -+#if defined(PNG_READ_APNG_SUPPORTED) -+ } -+ else -+ { -+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) -+ png_error(png_ptr, "Not enough image data"); -+ if (png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ png_warning(png_ptr, "Skipped (ignored) a chunk " -+ "between APNG chunks"); -+ bytes_to_skip = png_ptr->idat_size; -+ continue; -+ } -+ -+ png_ensure_sequence_number(png_ptr, png_ptr->idat_size); -+ -+ png_ptr->idat_size -= 4; -+ } -+#endif - } - png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_in = png_ptr->zbuf; -@@ -718,6 +842,9 @@ - png_error(png_ptr, "Extra compressed data"); - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_ptr->num_frames_read++; -+#endif - break; - } - if (ret != Z_OK) -@@ -969,6 +1096,11 @@ - #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_CONST PNG_zTXt; - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_acTL; -+ PNG_CONST PNG_fcTL; -+ PNG_CONST PNG_fdAT; -+#endif - #endif /* PNG_USE_LOCAL_ARRAYS */ - png_uint_32 length = png_read_chunk_header(png_ptr); - PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; -@@ -1069,6 +1201,14 @@ - else if (!png_memcmp(chunk_name, png_iTXt, 4)) - png_handle_iTXt(png_ptr, info_ptr, length); - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4)) -+ png_handle_acTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ png_handle_fcTL(png_ptr, info_ptr, length); -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ 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)); -Index: pngget.c -=================================================================== ---- pngget.c (révision 149) -+++ pngget.c (copie de travail) -@@ -797,6 +797,167 @@ - } - #endif - -+#if defined(PNG_APNG_SUPPORTED) -+png_uint_32 PNGAPI -+png_get_acTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 *num_frames, png_uint_32 *num_plays) -+{ -+ png_debug1(1, "in %s retrieval function\n", "acTL"); -+ -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_acTL) && -+ num_frames != NULL && num_plays != NULL) -+ { -+ *num_frames = info_ptr->num_frames; -+ *num_plays = info_ptr->num_plays; -+ return (1); -+ } -+ -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_num_frames(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_num_frames()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->num_frames); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_num_plays(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_num_plays()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->num_plays); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 *width, png_uint_32 *height, -+ png_uint_32 *x_offset, png_uint_32 *y_offset, -+ png_uint_16 *delay_num, png_uint_16 *delay_den, -+ png_byte *dispose_op, png_byte *blend_op) -+{ -+ png_debug1(1, "in %s retrieval function\n", "fcTL"); -+ -+ if (png_ptr != NULL && info_ptr != NULL && -+ (info_ptr->valid & PNG_INFO_fcTL) && -+ width != NULL && height != NULL && -+ x_offset != NULL && x_offset != NULL && -+ delay_num != NULL && delay_den != NULL && -+ dispose_op != NULL && blend_op != NULL) -+ { -+ *width = info_ptr->next_frame_width; -+ *height = info_ptr->next_frame_height; -+ *x_offset = info_ptr->next_frame_x_offset; -+ *y_offset = info_ptr->next_frame_y_offset; -+ *delay_num = info_ptr->next_frame_delay_num; -+ *delay_den = info_ptr->next_frame_delay_den; -+ *dispose_op = info_ptr->next_frame_dispose_op; -+ *blend_op = info_ptr->next_frame_blend_op; -+ return (1); -+ } -+ -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_width()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_width); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_height()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_height); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_x_offset()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_x_offset); -+ return (0); -+} -+ -+png_uint_32 PNGAPI -+png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_y_offset()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_y_offset); -+ return (0); -+} -+ -+png_uint_16 PNGAPI -+png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_delay_num()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_delay_num); -+ return (0); -+} -+ -+png_uint_16 PNGAPI -+png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_delay_den()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_delay_den); -+ return (0); -+} -+ -+png_byte PNGAPI -+png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_dispose_op()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_dispose_op); -+ return (0); -+} -+ -+png_byte PNGAPI -+png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_get_next_frame_blend_op()\n"); -+ -+ if (png_ptr != NULL && info_ptr != NULL) -+ return (info_ptr->next_frame_blend_op); -+ return (0); -+} -+ -+png_byte PNGAPI -+png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_debug(1, "in png_first_frame_is_hidden()\n"); -+ -+ if (png_ptr != NULL) -+ return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN); -+ -+ return 0; -+} -+#endif /* PNG_APNG_SUPPORTED */ -+ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - png_uint_32 PNGAPI - png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr, -Index: png.c -=================================================================== ---- png.c (révision 149) -+++ png.c (copie de travail) -@@ -51,6 +51,9 @@ - PNG_tIME; - PNG_tRNS; - PNG_zTXt; -+PNG_acTL; -+PNG_fcTL; -+PNG_fdAT; - - #ifdef PNG_READ_SUPPORTED - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ -Index: png.h -=================================================================== ---- png.h (révision 149) -+++ png.h (copie de travail) -@@ -949,6 +949,19 @@ - png_fixed_point int_y_blue; - #endif - -+#if defined(PNG_APNG_SUPPORTED) -+ png_uint_32 num_frames; /* including default image */ -+ png_uint_32 num_plays; -+ png_uint_32 next_frame_width; -+ png_uint_32 next_frame_height; -+ png_uint_32 next_frame_x_offset; -+ png_uint_32 next_frame_y_offset; -+ png_uint_16 next_frame_delay_num; -+ png_uint_16 next_frame_delay_den; -+ png_byte next_frame_dispose_op; -+ png_byte next_frame_blend_op; -+#endif -+ - } png_info; - - typedef png_info FAR * png_infop; -@@ -1050,6 +1063,8 @@ - #define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ - #define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ - #define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ -+#define PNG_INFO_acTL 0x10000L -+#define PNG_INFO_fcTL 0x20000L - - /* This is used for the transformation routines, as some of them - * change these values for the row. It also should enable using -@@ -1090,7 +1105,11 @@ - typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); - typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, - png_uint_32, int)); -+#if defined(PNG_APNG_SUPPORTED) -+typedef void (PNGAPI *png_progressive_frame_ptr) PNGARG((png_structp, -+ png_uint_32)); - #endif -+#endif - - #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ -@@ -1421,6 +1440,39 @@ - png_uint_32 user_height_max; - #endif - -+#if defined(PNG_APNG_SUPPORTED) -+ png_uint_32 apng_flags; -+ png_uint_32 next_seq_num; /* next fcTL/fdAT chunk sequence number */ -+ png_uint_32 first_frame_width; -+ png_uint_32 first_frame_height; -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_uint_32 num_frames_read; /* incremented after all image data of */ -+ /* a frame is read */ -+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -+ png_progressive_frame_ptr frame_info_fn; /* frame info read callback */ -+ png_progressive_frame_ptr frame_end_fn; /* frame data read callback */ -+#endif -+#endif -+ -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ png_uint_32 num_frames_to_write; -+ png_uint_32 num_frames_written; -+#endif -+#endif -+ -+/* For png_struct.apng_flags: */ -+#define PNG_FIRST_FRAME_HIDDEN 0x0001 -+ -+/* dispose_op flags from inside fcTL */ -+#define PNG_DISPOSE_OP_NONE 0x00 -+#define PNG_DISPOSE_OP_BACKGROUND 0x01 -+#define PNG_DISPOSE_OP_PREVIOUS 0x02 -+ -+/* blend_op flags from inside fcTL */ -+#define PNG_BLEND_OP_SOURCE 0x00 -+#define PNG_BLEND_OP_OVER 0x01 -+ - /* New member added in libpng-1.0.25 and 1.2.17 */ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - /* storage for unknown chunk that the library doesn't recognize. */ -@@ -1747,6 +1799,18 @@ - extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, - png_bytepp image)); - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+extern PNG_EXPORT (void,png_write_frame_head) PNGARG((png_structp png_ptr, -+ png_infop png_info, png_bytepp row_pointers, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op)); -+ -+extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr, -+ png_infop png_info)); -+#endif -+ - /* writes the end of the PNG file. */ - extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, - png_infop info_ptr)); -@@ -1995,6 +2059,11 @@ - png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn)); -+#if defined(PNG_READ_APNG_SUPPORTED) -+extern PNG_EXPORT(void,png_set_progressive_frame_fn) PNGARG((png_structp png_ptr, -+ png_progressive_frame_ptr frame_info_fn, -+ png_progressive_frame_ptr frame_end_fn)); -+#endif - - /* returns the user pointer associated with the push read functions */ - extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) -@@ -2432,6 +2501,59 @@ - #endif - #endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ - -+#if defined(PNG_APNG_SUPPORTED) -+extern PNG_EXPORT(png_uint_32,png_get_acTL) PNGARG((png_structp png_ptr, -+ png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays)); -+extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr, -+ png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays)); -+extern PNG_EXPORT(png_uint_32,png_get_num_frames) PNGARG((png_structp png_ptr, -+ png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_num_plays) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+ -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL) -+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, -+ png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset, -+ png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op, -+ png_byte *blend_op)); -+extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL) -+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width, -+ png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op)); -+extern PNG_EXPORT(void,png_ensure_fcTL_is_valid) -+ PNGARG((png_structp png_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_width) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_height) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_x_offset) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_get_next_frame_y_offset) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_num) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_den) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_byte,png_get_next_frame_dispose_op) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_byte,png_get_next_frame_blend_op) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_byte,png_get_first_frame_is_hidden) -+ PNGARG((png_structp png_ptr, png_infop info_ptr)); -+extern PNG_EXPORT(png_uint_32,png_set_first_frame_is_hidden) -+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_byte is_hidden)); -+#endif /* PNG_APNG_SUPPORTED */ -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+extern PNG_EXPORT(void,png_read_frame_head) PNGARG((png_structp png_ptr, -+ png_infop info_ptr)); -+#endif -+ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - /* provide a list of chunks and how they are to be handled, if the built-in - handling or default unknown chunk handling is not desired. Any chunks not -@@ -2738,6 +2860,8 @@ - #define PNG_BACKGROUND_IS_GRAY 0x800 - #define PNG_HAVE_PNG_SIGNATURE 0x1000 - #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ -+#define PNG_HAVE_acTL 0x4000 -+#define PNG_HAVE_fcTL 0x8000L - - /* flags for the transformations the PNG library does on the image data */ - #define PNG_BGR 0x0001 -@@ -2878,6 +3002,9 @@ - #define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} - #define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} - #define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} -+#define PNG_acTL png_byte png_acTL[5] = { 97, 99, 84, 76, '\0'} -+#define PNG_fcTL png_byte png_fcTL[5] = {102, 99, 84, 76, '\0'} -+#define PNG_fdAT png_byte png_fdAT[5] = {102, 100, 65, 84, '\0'} - - #ifdef PNG_USE_GLOBAL_ARRAYS - PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5]; -@@ -2901,6 +3028,9 @@ - PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5]; - PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5]; - PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5]; -+PNG_EXPORT_VAR (png_byte FARDATA) png_acTL[5]; -+PNG_EXPORT_VAR (png_byte FARDATA) png_fcTL[5]; -+PNG_EXPORT_VAR (png_byte FARDATA) png_fdAT[5]; - #endif /* PNG_USE_GLOBAL_ARRAYS */ - - #if defined(PNG_1_0_X) || defined (PNG_1_2_X) -@@ -3175,6 +3305,17 @@ - #endif - #endif - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr, -+ png_uint_32 num_frames, png_uint_32 num_plays)); -+ -+PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op)); -+#endif -+ - /* Called when finished processing a row of data */ - PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); - -@@ -3226,6 +3367,20 @@ - PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, - png_infop info_ptr)); - -+#if defined(PNG_READ_APNG_SUPPORTED) -+/* private, reset some things to become ready for reading next frame */ -+PNG_EXTERN void png_read_reset PNGARG((png_structp png_ptr)); -+PNG_EXTERN void png_read_reinit PNGARG((png_structp png_ptr, -+ png_infop info_ptr)); -+PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr)); -+#endif -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+/* private, reset some things to become ready for writing next frame */ -+PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr)); -+PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr, -+ png_infop info_ptr, png_uint_32 width, png_uint_32 height)); -+#endif -+ - /* these are the functions that do the transformations */ - #if defined(PNG_READ_FILLER_SUPPORTED) - PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, -@@ -3441,6 +3596,18 @@ - png_uint_32 length)); - #endif - -+#if defined(PNG_READ_APNG_SUPPORTED) -+PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 length)); -+PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 length)); -+PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr)); -+PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 length)); -+PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr, -+ png_uint_32 length)); -+#endif -+ - PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); - -Index: pngwrite.c -=================================================================== ---- pngwrite.c (révision 149) -+++ pngwrite.c (copie de travail) -@@ -261,6 +261,10 @@ - } - } - #endif -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ if (info_ptr->valid & PNG_INFO_acTL) -+ png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays); -+#endif - #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) - if (info_ptr->unknown_chunks_num) - { -@@ -299,6 +303,10 @@ - return; - if (!(png_ptr->mode & PNG_HAVE_IDAT)) - png_error(png_ptr, "No IDATs written into file"); -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ if (png_ptr->num_frames_written != png_ptr->num_frames_to_write) -+ png_error(png_ptr, "Not enough frames written"); -+#endif - - /* see if user wants us to write information chunks */ - if (info_ptr != NULL) -@@ -1527,4 +1535,39 @@ - params = params; - } - #endif -+ -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+void PNGAPI -+png_write_frame_head(png_structp png_ptr, png_infop info_ptr, -+ png_bytepp row_pointers, png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op) -+{ -+ png_debug(1, "in png_write_frame_head\n"); -+ -+ /* there is a chance this has been set after png_write_info was called, -+ * so it would be set but not written. is there a way to be sure? */ -+ if (!(info_ptr->valid & PNG_INFO_acTL)) -+ png_error(png_ptr, "png_write_frame_head(): acTL not set"); -+ -+ png_write_reset(png_ptr); -+ -+ png_write_reinit(png_ptr, info_ptr, width, height); -+ -+ if ( !(png_ptr->num_frames_written == 0 && -+ (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) ) -+ png_write_fcTL(png_ptr, width, height, x_offset, y_offset, -+ delay_num, delay_den, dispose_op, blend_op); -+} -+ -+void PNGAPI -+png_write_frame_tail(png_structp png_ptr, png_infop png_info) -+{ -+ png_debug(1, "in png_write_frame_tail\n"); -+ -+ png_ptr->num_frames_written++; -+} -+#endif /* PNG_WRITE_APNG_SUPPORTED */ -+ - #endif /* PNG_WRITE_SUPPORTED */ -Index: pngconf.h -=================================================================== ---- pngconf.h (révision 149) -+++ pngconf.h (copie de travail) -@@ -925,6 +925,10 @@ - # define PNG_READ_zTXt_SUPPORTED - # define PNG_zTXt_SUPPORTED - #endif -+#ifndef PNG_NO_READ_APNG -+# define PNG_READ_APNG_SUPPORTED -+# define PNG_APNG_SUPPORTED -+#endif - #ifndef PNG_NO_READ_UNKNOWN_CHUNKS - # define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED -@@ -1067,6 +1071,12 @@ - # define PNG_zTXt_SUPPORTED - # endif - #endif -+#ifndef PNG_NO_WRITE_APNG -+# define PNG_WRITE_APNG_SUPPORTED -+# ifndef PNG_APNG_SUPPORTED -+# define PNG_APNG_SUPPORTED -+# endif -+#endif - #ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS - # define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED -Index: pngpread.c -=================================================================== ---- pngpread.c (révision 149) -+++ pngpread.c (copie de travail) -@@ -192,6 +192,11 @@ - #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_CONST PNG_zTXt; - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_CONST PNG_acTL; -+ PNG_CONST PNG_fcTL; -+ PNG_CONST PNG_fdAT; -+#endif - #endif /* PNG_USE_LOCAL_ARRAYS */ - /* 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 -@@ -215,7 +220,104 @@ - png_crc_read(png_ptr, png_ptr->chunk_name, 4); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - } -- -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_ptr->num_frames_read > 0 && -+ png_ptr->num_frames_read < info_ptr->num_frames) -+ { -+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+ { -+ /* discard trailing IDATs for the first frame */ -+ if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1) -+ png_error(png_ptr, "out of place IDAT"); -+ -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_push_crc_skip(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ if (png_ptr->buffer_size < 4) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_ensure_sequence_number(png_ptr, 4); -+ -+ if (!(png_ptr->mode & PNG_HAVE_fcTL)) -+ { -+ /* discard trailing fdATs for frames other than the first */ -+ if (png_ptr->num_frames_read < 2) -+ png_error(png_ptr, "out of place fdAT"); -+ -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_push_crc_skip(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ else -+ { -+ /* frame data follows */ -+ png_ptr->idat_size = png_ptr->push_length - 4; -+ png_ptr->mode |= PNG_HAVE_IDAT; -+ png_ptr->process_mode = PNG_READ_IDAT_MODE; -+ -+ return; -+ } -+ } -+ else if(!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ -+ png_read_reset(png_ptr); -+ png_ptr->mode &= ~PNG_HAVE_fcTL; -+ -+ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length); -+ -+ if (!(png_ptr->mode & PNG_HAVE_fcTL)) -+ png_error(png_ptr, "missing required fcTL chunk"); -+ -+ png_read_reinit(png_ptr, info_ptr); -+ png_progressive_read_reset(png_ptr); -+ -+ if (png_ptr->frame_info_fn != NULL) -+ (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read); -+ -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ -+ return; -+ } -+ else -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_warning(png_ptr, "Skipped (ignored) a chunk " -+ "between APNG chunks"); -+ png_push_crc_skip(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ -+ return; -+ } -+#endif /* PNG_READ_APNG_SUPPORTED */ -+ - if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) - if(png_ptr->mode & PNG_AFTER_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; -@@ -295,6 +397,9 @@ - png_error(png_ptr, "Too many IDAT's found"); - } - -+#if defined(PNG_READ_APNG_SUPPORTED) -+ png_have_info(png_ptr, info_ptr); -+#endif - png_ptr->idat_size = png_ptr->push_length; - png_ptr->mode |= PNG_HAVE_IDAT; - png_ptr->process_mode = PNG_READ_IDAT_MODE; -@@ -490,6 +595,35 @@ - png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); - } - #endif -+#if defined(PNG_READ_APNG_SUPPORTED) -+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4)) -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length); -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4)) -+ { -+ 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); -+ } -+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4)) -+ { -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_handle_fdAT(png_ptr, info_ptr, png_ptr->push_length); -+ } -+#endif /* PNG_READ_APNG_SUPPORTED */ - else - { - if (png_ptr->push_length + 4 > png_ptr->buffer_size) -@@ -660,13 +794,17 @@ - png_push_read_IDAT(png_structp png_ptr) - { - #ifdef PNG_USE_LOCAL_ARRAYS -- PNG_CONST PNG_IDAT; -+ PNG_IDAT; -+#if defined(PNG_READ_APNG_SUPPORTED) -+ PNG_fdAT; -+ PNG_IEND; - #endif -+#endif - if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) - { - png_byte chunk_length[4]; - -- if (png_ptr->buffer_size < 8) -+ if (png_ptr->buffer_size < 12) - { - png_push_save_buffer(png_ptr); - return; -@@ -678,15 +816,59 @@ - png_crc_read(png_ptr, png_ptr->chunk_name, 4); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - -- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_fdAT, 4) -+ && png_ptr->num_frames_read > 0) - { -+ if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) -+ { -+ png_ptr->process_mode = PNG_READ_CHUNK_MODE; -+ if (png_ptr->frame_end_fn != NULL) -+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); -+ png_ptr->num_frames_read++; -+ return; -+ } -+ else -+ { -+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) -+ png_error(png_ptr, "Not enough image data"); -+ if (png_ptr->push_length + 4 > png_ptr->buffer_size) -+ { -+ png_push_save_buffer(png_ptr); -+ return; -+ } -+ png_warning(png_ptr, "Skipping (ignoring) a chunk between " -+ "APNG chunks"); -+ png_crc_finish(png_ptr, png_ptr->push_length); -+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -+ return; -+ } -+ } -+ else -+#endif -+ if ( png_memcmp(png_ptr->chunk_name, png_IDAT, 4) -+ && (png_ptr->num_frames_read == 0) ) -+ { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - png_error(png_ptr, "Not enough compressed data"); -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if (png_ptr->frame_end_fn != NULL) -+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); -+ png_ptr->num_frames_read++; -+#endif - return; - } - - png_ptr->idat_size = png_ptr->push_length; -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+ if(png_ptr->num_frames_read > 0) -+ { -+ png_ensure_sequence_number(png_ptr, 4); -+ png_ptr->idat_size -= 4; -+ } -+#endif - } - if (png_ptr->idat_size && png_ptr->save_buffer_size) - { -@@ -1582,6 +1764,17 @@ - png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); - } - -+#if defined(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; -+} -+#endif -+ - png_voidp PNGAPI - png_get_progressive_ptr(png_structp png_ptr) - { -Index: pngset.c -=================================================================== ---- pngset.c (révision 149) -+++ pngset.c (copie de travail) -@@ -363,6 +363,11 @@ - info_ptr->rowbytes = (png_size_t)0; - else - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); -+ -+#if defined(PNG_APNG_SUPPORTED) -+ /* for non-animated png. this may be overritten from an acTL chunk later */ -+ info_ptr->num_frames = 1; -+#endif - } - - #if defined(PNG_oFFs_SUPPORTED) -@@ -1043,6 +1048,141 @@ - } - #endif /* PNG_sPLT_SUPPORTED */ - -+#if defined(PNG_APNG_SUPPORTED) -+png_uint_32 PNGAPI -+png_set_acTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 num_frames, png_uint_32 num_plays) -+{ -+ png_debug1(1, "in %s storage function\n", "acTL"); -+ -+ if (png_ptr == NULL || info_ptr == NULL) -+ { -+ png_warning(png_ptr, -+ "Call to png_set_acTL() with NULL png_ptr " -+ "or info_ptr ignored"); -+ return (0); -+ } -+ if (num_frames == 0) -+ { -+ png_warning(png_ptr, -+ "Ignoring attempt to set acTL with num_frames zero"); -+ return (0); -+ } -+ if (num_frames > PNG_UINT_31_MAX) -+ { -+ png_warning(png_ptr, -+ "Ignoring attempt to set acTL with num_frames > 2^31-1"); -+ return (0); -+ } -+ if (num_plays > PNG_UINT_31_MAX) -+ { -+ png_warning(png_ptr, -+ "Ignoring attempt to set acTL with num_plays " -+ "> 2^31-1"); -+ return (0); -+ } -+ -+ info_ptr->num_frames = num_frames; -+ info_ptr->num_plays = num_plays; -+ -+ info_ptr->valid |= PNG_INFO_acTL; -+ -+ return (1); -+} -+ -+/* delay_num and delay_den can hold any 16-bit values including zero */ -+png_uint_32 PNGAPI -+png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op) -+{ -+ png_debug1(1, "in %s storage function\n", "fcTL"); -+ -+ if (png_ptr == NULL || info_ptr == NULL) -+ { -+ png_warning(png_ptr, -+ "Call to png_set_fcTL() with NULL png_ptr or info_ptr " -+ "ignored"); -+ return (0); -+ } -+ -+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, -+ delay_num, delay_den, dispose_op, blend_op); -+ -+ info_ptr->next_frame_width = width; -+ info_ptr->next_frame_height = height; -+ info_ptr->next_frame_x_offset = x_offset; -+ info_ptr->next_frame_y_offset = y_offset; -+ info_ptr->next_frame_delay_num = delay_num; -+ info_ptr->next_frame_delay_den = delay_den; -+ info_ptr->next_frame_dispose_op = dispose_op; -+ info_ptr->next_frame_blend_op = blend_op; -+ -+ info_ptr->valid |= PNG_INFO_fcTL; -+ -+ return (1); -+} -+ -+void /* PRIVATE */ -+png_ensure_fcTL_is_valid(png_structp png_ptr, -+ png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, -+ png_byte dispose_op, png_byte blend_op) -+{ -+ if (width + x_offset > png_ptr->first_frame_width || -+ height + y_offset > png_ptr->first_frame_height) -+ png_error(png_ptr, "dimensions of a frame are greater than" -+ "the ones in IHDR"); -+ if (width > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid width in fcTL (> 2^31-1)"); -+ if (height > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid height in fcTL (> 2^31-1)"); -+ if (x_offset > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)"); -+ if (y_offset > PNG_UINT_31_MAX) -+ png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)"); -+ -+ if (dispose_op != PNG_DISPOSE_OP_NONE && -+ dispose_op != PNG_DISPOSE_OP_BACKGROUND && -+ dispose_op != PNG_DISPOSE_OP_PREVIOUS) -+ png_error(png_ptr, "invalid dispose_op in fcTL"); -+ -+ if (blend_op != PNG_BLEND_OP_SOURCE && -+ blend_op != PNG_BLEND_OP_OVER) -+ png_error(png_ptr, "invalid blend_op in fcTL"); -+ -+ if (blend_op == PNG_BLEND_OP_OVER) { -+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) -+ png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for " -+ "color type 'greyscale without alpha'"); -+ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) && -+ !(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)) -+ png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for " -+ "color type 'truecolor without alpha'"); -+ } -+} -+ -+png_uint_32 PNGAPI -+png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr, -+ png_byte is_hidden) -+{ -+ png_debug(1, "in png_first_frame_is_hidden()\n"); -+ -+ if (png_ptr == NULL) -+ return 0; -+ -+ if(is_hidden) -+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN; -+ else -+ png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN; -+ -+ return 1; -+} -+#endif /* PNG_APNG_SUPPORTED */ -+ - #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - void PNGAPI - png_set_unknown_chunks(png_structp png_ptr, -Index: pngrutil.c -=================================================================== ---- pngrutil.c (révision 149) -+++ pngrutil.c (copie de travail) -@@ -414,6 +414,11 @@ - filter_type = buf[11]; - interlace_type = buf[12]; - -+#if defined(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; -@@ -2220,6 +2225,168 @@ - } - #endif - -+#if defined(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]; -+ png_uint_32 num_frames; -+ png_uint_32 num_plays; -+ png_uint_32 didSet; -+ -+ png_debug(1, "in png_handle_acTL\n"); -+ -+ if (!(png_ptr->mode & PNG_HAVE_IHDR)) -+ { -+ png_error(png_ptr, "Missing IHDR before acTL"); -+ } -+ else if (png_ptr->mode & PNG_HAVE_IDAT) -+ { -+ png_warning(png_ptr, "Invalid acTL after IDAT skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (png_ptr->mode & PNG_HAVE_acTL) -+ { -+ png_warning(png_ptr, "Duplicate acTL skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (length != 8) -+ { -+ png_warning(png_ptr, "acTL with invalid length skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ -+ png_crc_read(png_ptr, data, 8); -+ png_crc_finish(png_ptr, 0); -+ -+ num_frames = png_get_uint_31(png_ptr, data); -+ num_plays = png_get_uint_31(png_ptr, data + 4); -+ -+ /* the set function will do error checking on num_frames */ -+ didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays); -+ if(didSet) -+ png_ptr->mode |= PNG_HAVE_acTL; -+} -+ -+void /* PRIVATE */ -+png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+{ -+ png_byte data[22]; -+ png_uint_32 width; -+ png_uint_32 height; -+ png_uint_32 x_offset; -+ png_uint_32 y_offset; -+ png_uint_16 delay_num; -+ png_uint_16 delay_den; -+ png_byte dispose_op; -+ png_byte blend_op; -+ -+ png_debug(1, "in png_handle_fcTL\n"); -+ -+ if (!(png_ptr->mode & PNG_HAVE_IHDR)) -+ { -+ png_error(png_ptr, "Missing IHDR before fcTL"); -+ } -+ else if (png_ptr->mode & PNG_HAVE_IDAT) -+ { -+ /* for any frames other then the first this message may be misleading, -+ * but correct. PNG_HAVE_IDAT is unset before the frame head is read -+ * i can't think of a better message */ -+ png_warning(png_ptr, "Invalid fcTL after IDAT skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (png_ptr->mode & PNG_HAVE_fcTL) -+ { -+ png_warning(png_ptr, "Duplicate fcTL within one frame skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ else if (length != 26) -+ { -+ png_warning(png_ptr, "fcTL with invalid length skipped"); -+ png_crc_finish(png_ptr, length); -+ return; -+ } -+ -+ png_ensure_sequence_number(png_ptr, length); -+ -+ png_crc_read(png_ptr, data, 22); -+ png_crc_finish(png_ptr, 0); -+ -+ width = png_get_uint_31(png_ptr, data); -+ height = png_get_uint_31(png_ptr, data + 4); -+ x_offset = png_get_uint_31(png_ptr, data + 8); -+ y_offset = png_get_uint_31(png_ptr, data + 12); -+ delay_num = png_get_uint_16(data + 16); -+ delay_den = png_get_uint_16(data + 18); -+ dispose_op = data[20]; -+ blend_op = data[21]; -+ -+ if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0)) -+ png_error(png_ptr, "fcTL for the first frame must have zero offset"); -+ if (png_ptr->num_frames_read == 0 && -+ (width != info_ptr->width || height != info_ptr->height)) -+ png_error(png_ptr, "size in first frame's fcTL must match " -+ "the size in IHDR"); -+ -+ /* the set function will do more error checking */ -+ png_set_next_frame_fcTL(png_ptr, info_ptr, width, height, -+ x_offset, y_offset, delay_num, delay_den, -+ dispose_op, blend_op); -+ -+ png_read_reinit(png_ptr, info_ptr); -+ -+ png_ptr->mode |= PNG_HAVE_fcTL; -+} -+ -+void /* PRIVATE */ -+png_have_info(png_structp png_ptr, png_infop info_ptr) -+{ -+ if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL)) -+ { -+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN; -+ info_ptr->num_frames++; -+ } -+} -+ -+void /* PRIVATE */ -+png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -+{ -+ png_ensure_sequence_number(png_ptr, length); -+ -+ /* This function is only called from png_read_end(), png_read_info(), -+ * and png_push_read_chunk() which means that: -+ * - the user doesn't want to read this frame -+ * - or this is an out-of-place fdAT -+ * in either case it is safe to ignore the chunk with a warning */ -+ png_warning(png_ptr, "ignoring fdAT chunk"); -+ png_crc_finish(png_ptr, length - 4); -+} -+ -+void /* PRIVATE */ -+png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length) -+{ -+ png_byte data[4]; -+ png_uint_32 sequence_number; -+ -+ if (length < 4) -+ png_error(png_ptr, "invalid fcTL or fdAT chunk found"); -+ -+ png_crc_read(png_ptr, data, 4); -+ sequence_number = png_get_uint_31(png_ptr, data); -+ -+ if (sequence_number != png_ptr->next_seq_num) -+ png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence " -+ "number found"); -+ -+ png_ptr->next_seq_num++; -+} -+#endif /* PNG_READ_APNG_SUPPORTED */ -+ - /* This function is called when we haven't found a handler for a - chunk. If there isn't a problem with the chunk itself (ie bad - chunk name, CRC, or a critical chunk), the chunk is silently ignored -@@ -3195,8 +3362,10 @@ - if (row_bytes + 64 > png_ptr->old_big_row_buf_size) - { - png_free(png_ptr, png_ptr->big_row_buf); -- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); -- png_ptr->row_buf = png_ptr->big_row_buf+32; -+ if (png_ptr->big_row_buf == NULL) -+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); -+ if (png_ptr->row_buf == NULL) -+ png_ptr->row_buf = png_ptr->big_row_buf+32; - png_ptr->old_big_row_buf_size = row_bytes+64; - } - -@@ -3226,4 +3395,82 @@ - - png_ptr->flags |= PNG_FLAG_ROW_INIT; - } -+ -+#if defined(PNG_READ_APNG_SUPPORTED) -+/* This function is to be called after the main IDAT set has been read and -+ * before a new IDAT is read. It resets some parts of png_ptr -+ * to make them usable by the read functions again */ -+void /* PRIVATE */ -+png_read_reset(png_structp png_ptr) -+{ -+ png_ptr->mode &= ~PNG_HAVE_IDAT; -+ png_ptr->mode &= ~PNG_AFTER_IDAT; -+ png_ptr->row_number = 0; -+ png_ptr->pass = 0; -+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT; -+} -+ -+void /* PRIVATE */ -+png_read_reinit(png_structp png_ptr, png_infop info_ptr) -+{ -+ png_ptr->width = info_ptr->next_frame_width; -+ png_ptr->height = info_ptr->next_frame_height; -+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); -+} -+ -+/* same as png_read_reset() but for the progressive reader */ -+void /* PRIVATE */ -+png_progressive_read_reset(png_structp png_ptr) -+{ -+#ifdef PNG_USE_LOCAL_ARRAYS -+ /* start of interlace block */ -+ const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; -+ -+ /* offset to next interlace block */ -+ const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; -+ -+ /* start of interlace block in the y direction */ -+ const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; -+ -+ /* offset to next interlace block in the y direction */ -+ const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; -+#endif -+ png_uint_32 row_bytes; -+ -+ if (png_ptr->interlaced) -+ { -+ if (!(png_ptr->transformations & PNG_INTERLACE)) -+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - -+ png_pass_ystart[0]) / png_pass_yinc[0]; -+ else -+ png_ptr->num_rows = png_ptr->height; -+ -+ png_ptr->iwidth = (png_ptr->width + -+ png_pass_inc[png_ptr->pass] - 1 - -+ png_pass_start[png_ptr->pass]) / -+ png_pass_inc[png_ptr->pass]; -+ -+ row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1; -+ -+ png_ptr->irowbytes = (png_size_t)row_bytes; -+ if((png_uint_32)png_ptr->irowbytes != row_bytes) -+ png_error(png_ptr, "png_progressive_read_reset(): Rowbytes " -+ "overflow"); -+ } -+ else -+ { -+ png_ptr->num_rows = png_ptr->height; -+ png_ptr->iwidth = png_ptr->width; -+ png_ptr->irowbytes = png_ptr->rowbytes + 1; -+ } -+ -+ png_ptr->flags &= ~PNG_FLAG_ZLIB_FINISHED; -+ if (inflateReset(&(png_ptr->zstream)) != Z_OK) -+ png_error(png_ptr, "inflateReset failed"); -+ png_ptr->zstream.avail_in = 0; -+ png_ptr->zstream.next_in = 0; -+ png_ptr->zstream.next_out = png_ptr->row_buf; -+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; -+} -+#endif /* PNG_READ_APNG_SUPPORTED */ - #endif /* PNG_READ_SUPPORTED */ -Index: pngwutil.c -=================================================================== ---- pngwutil.c (révision 149) -+++ pngwutil.c (copie de travail) -@@ -506,6 +506,11 @@ - /* write the chunk */ - png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13); - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ png_ptr->first_frame_width = width; -+ png_ptr->first_frame_height = height; -+#endif -+ - /* initialize zlib with PNG info */ - png_ptr->zstream.zalloc = png_zalloc; - png_ptr->zstream.zfree = png_zfree; -@@ -628,6 +633,9 @@ - { - #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IDAT; -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ PNG_fdAT; -+#endif - #endif - png_debug(1, "in png_write_IDAT\n"); - -@@ -670,7 +678,28 @@ - "Invalid zlib compression method or flags in IDAT"); - } - -- png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ if(png_ptr->num_frames_written == 0) -+#endif -+ png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+ else -+ { -+ png_byte buf[4]; -+ -+ png_write_chunk_start(png_ptr, (png_bytep)png_fdAT, 4 + length); -+ -+ png_save_uint_32(buf, png_ptr->next_seq_num); -+ png_write_chunk_data(png_ptr, buf, 4); -+ -+ png_write_chunk_data(png_ptr, data, length); -+ -+ png_write_chunk_end(png_ptr); -+ -+ png_ptr->next_seq_num++; -+ } -+#endif -+ - png_ptr->mode |= PNG_HAVE_IDAT; - } - -@@ -1755,6 +1784,70 @@ - } - #endif - -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+void /* PRIVATE */ -+png_write_acTL(png_structp png_ptr, -+ png_uint_32 num_frames, png_uint_32 num_plays) -+{ -+#ifdef PNG_USE_LOCAL_ARRAYS -+ PNG_acTL; -+#endif -+ png_byte data[16]; -+ -+ png_debug(1, "in png_write_acTL\n"); -+ -+ png_ptr->num_frames_to_write = num_frames; -+ -+ if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) -+ num_frames--; -+ -+ png_save_uint_32(data, num_frames); -+ png_save_uint_32(data + 4, num_plays); -+ -+ png_write_chunk(png_ptr, (png_bytep)png_acTL, data, (png_size_t)8); -+} -+ -+void /* PRIVATE */ -+png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height, -+ png_uint_32 x_offset, png_uint_32 y_offset, -+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, -+ png_byte blend_op) -+{ -+#ifdef PNG_USE_LOCAL_ARRAYS -+ PNG_fcTL; -+#endif -+ png_byte data[26]; -+ -+ png_debug(1, "in png_write_fcTL\n"); -+ -+ if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0)) -+ png_error(png_ptr, "x and/or y offset for the first frame aren't 0\n"); -+ if (png_ptr->num_frames_written == 0 && -+ (width != png_ptr->first_frame_width || -+ height != png_ptr->first_frame_height)) -+ png_error(png_ptr, "width and/or height in the first frame's fcTL " -+ "don't match the ones in IHDR\n"); -+ -+ /* more error checking */ -+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, -+ delay_num, delay_den, dispose_op, blend_op); -+ -+ png_save_uint_32(data, png_ptr->next_seq_num); -+ png_save_uint_32(data + 4, width); -+ png_save_uint_32(data + 8, height); -+ png_save_uint_32(data + 12, x_offset); -+ png_save_uint_32(data + 16, y_offset); -+ png_save_uint_16(data + 20, delay_num); -+ png_save_uint_16(data + 22, delay_den); -+ data[24] = dispose_op; -+ data[25] = blend_op; -+ -+ png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)26); -+ -+ png_ptr->next_seq_num++; -+} -+#endif /* PNG_WRITE_APNG_SUPPORTED */ -+ - /* initializes the row writing capability of libpng */ - void /* PRIVATE */ - png_write_start_row(png_structp png_ptr) -@@ -2824,4 +2917,39 @@ - } - #endif - } -+ -+#if defined(PNG_WRITE_APNG_SUPPORTED) -+void /* PRIVATE */ -+png_write_reset(png_structp png_ptr) -+{ -+ png_ptr->row_number = 0; -+ png_ptr->pass = 0; -+ png_ptr->mode &= ~PNG_HAVE_IDAT; -+} -+ -+void /* PRIVATE */ -+png_write_reinit(png_structp png_ptr, png_infop info_ptr, -+ png_uint_32 width, png_uint_32 height) -+{ -+ if (png_ptr->num_frames_written == 0 && -+ (width != png_ptr->first_frame_width || -+ height != png_ptr->first_frame_height)) -+ png_error(png_ptr, "width and/or height in the first frame's fcTL " -+ "don't match the ones in IHDR\n"); -+ if (width > png_ptr->first_frame_width || -+ height > png_ptr->first_frame_height) -+ png_error(png_ptr, "width and/or height for a frame greater than" -+ "the ones in IHDR"); -+ -+ png_set_IHDR(png_ptr, info_ptr, width, height, -+ info_ptr->bit_depth, info_ptr->color_type, -+ info_ptr->interlace_type, info_ptr->compression_type, -+ info_ptr->filter_type); -+ -+ png_ptr->width = width; -+ png_ptr->height = height; -+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); -+ png_ptr->usr_width = png_ptr->width; -+} -+#endif - #endif /* PNG_WRITE_SUPPORTED */ -Index: pngrtran.c -=================================================================== ---- pngrtran.c (révision 149) -+++ pngrtran.c (copie de travail) -@@ -1293,7 +1293,7 @@ - * or png_read_update_info() after setting transforms that expand - * pixels. This check added to libpng-1.2.19 */ - #if (PNG_WARN_UNINITIALIZED_ROW==1) -- png_error(png_ptr, "Uninitialized row"); -+ png_warning(png_ptr, "Uninitialized row"); - #else - png_warning(png_ptr, "Uninitialized row"); - #endif |