]> git.pld-linux.org Git - packages/libpng.git/blame - libpng-apng.patch
- updated APNG patch, rel. 1
[packages/libpng.git] / libpng-apng.patch
CommitLineData
580fd6fc
TP
1diff -Naru libpng-1.2.41.org/png.c libpng-1.2.41/png.c
2--- libpng-1.2.41.org/png.c 2009-12-04 21:30:08.000000000 +0900
3+++ libpng-1.2.41/png.c 2009-12-04 21:30:08.000000000 +0900
4@@ -56,6 +56,11 @@
e4744232
ER
5 PNG_tIME;
6 PNG_tRNS;
7 PNG_zTXt;
92006fdd 8+#ifdef PNG_APNG_SUPPORTED
e4744232
ER
9+PNG_acTL;
10+PNG_fcTL;
11+PNG_fdAT;
92006fdd 12+#endif
e4744232
ER
13
14 #ifdef PNG_READ_SUPPORTED
6df9a45f 15 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
580fd6fc
TP
16diff -Naru libpng-1.2.41.org/png.h libpng-1.2.41/png.h
17--- libpng-1.2.41.org/png.h 2009-12-04 21:30:08.000000000 +0900
18+++ libpng-1.2.41/png.h 2009-12-04 21:30:08.000000000 +0900
19@@ -1029,6 +1029,19 @@
20 png_fixed_point int_y_blue PNG_DEPSTRUCT;
259182b6
ER
21 #endif
22
92006fdd 23+#ifdef PNG_APNG_SUPPORTED
580fd6fc
TP
24+ png_uint_32 num_frames PNG_DEPSTRUCT; /* including default image */
25+ png_uint_32 num_plays PNG_DEPSTRUCT;
26+ png_uint_32 next_frame_width PNG_DEPSTRUCT;
27+ png_uint_32 next_frame_height PNG_DEPSTRUCT;
28+ png_uint_32 next_frame_x_offset PNG_DEPSTRUCT;
29+ png_uint_32 next_frame_y_offset PNG_DEPSTRUCT;
30+ png_uint_16 next_frame_delay_num PNG_DEPSTRUCT;
31+ png_uint_16 next_frame_delay_den PNG_DEPSTRUCT;
32+ png_byte next_frame_dispose_op PNG_DEPSTRUCT;
33+ png_byte next_frame_blend_op PNG_DEPSTRUCT;
259182b6
ER
34+#endif
35+
36 } png_info;
37
38 typedef png_info FAR * png_infop;
580fd6fc 39@@ -1130,6 +1143,10 @@
259182b6
ER
40 #define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
41 #define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
42 #define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */
92006fdd 43+#ifdef PNG_APNG_SUPPORTED
259182b6
ER
44+#define PNG_INFO_acTL 0x10000L
45+#define PNG_INFO_fcTL 0x20000L
92006fdd 46+#endif
259182b6
ER
47
48 /* This is used for the transformation routines, as some of them
49 * change these values for the row. It also should enable using
580fd6fc 50@@ -1170,6 +1187,10 @@
259182b6
ER
51 typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
52 typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
53 png_uint_32, int));
92006fdd 54+#ifdef PNG_APNG_SUPPORTED
259182b6
ER
55+typedef void (PNGAPI *png_progressive_frame_ptr) PNGARG((png_structp,
56+ png_uint_32));
259182b6 57+#endif
6df9a45f 58 #endif
259182b6
ER
59
60 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
580fd6fc
TP
61@@ -1506,6 +1527,39 @@
62 png_uint_32 user_height_max PNG_DEPSTRUCT;
259182b6
ER
63 #endif
64
92006fdd 65+#ifdef PNG_APNG_SUPPORTED
580fd6fc
TP
66+ png_uint_32 apng_flags PNG_DEPSTRUCT;
67+ png_uint_32 next_seq_num PNG_DEPSTRUCT; /* next fcTL/fdAT chunk sequence number */
68+ png_uint_32 first_frame_width PNG_DEPSTRUCT;
69+ png_uint_32 first_frame_height PNG_DEPSTRUCT;
259182b6 70+
92006fdd 71+#ifdef PNG_READ_APNG_SUPPORTED
580fd6fc 72+ png_uint_32 num_frames_read PNG_DEPSTRUCT; /* incremented after all image data of */
259182b6
ER
73+ /* a frame is read */
74+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
580fd6fc
TP
75+ png_progressive_frame_ptr frame_info_fn PNG_DEPSTRUCT; /* frame info read callback */
76+ png_progressive_frame_ptr frame_end_fn PNG_DEPSTRUCT; /* frame data read callback */
259182b6
ER
77+#endif
78+#endif
79+
92006fdd 80+#ifdef PNG_WRITE_APNG_SUPPORTED
580fd6fc
TP
81+ png_uint_32 num_frames_to_write PNG_DEPSTRUCT;
82+ png_uint_32 num_frames_written PNG_DEPSTRUCT;
259182b6 83+#endif
259182b6
ER
84+
85+/* For png_struct.apng_flags: */
86+#define PNG_FIRST_FRAME_HIDDEN 0x0001
87+
88+/* dispose_op flags from inside fcTL */
89+#define PNG_DISPOSE_OP_NONE 0x00
90+#define PNG_DISPOSE_OP_BACKGROUND 0x01
91+#define PNG_DISPOSE_OP_PREVIOUS 0x02
92+
93+/* blend_op flags from inside fcTL */
94+#define PNG_BLEND_OP_SOURCE 0x00
95+#define PNG_BLEND_OP_OVER 0x01
92006fdd 96+#endif /* PNG_APNG_SUPPORTED */
259182b6
ER
97+
98 /* New member added in libpng-1.0.25 and 1.2.17 */
580fd6fc 99 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
9f147502 100 /* Storage for unknown chunk that the library doesn't recognize. */
580fd6fc 101@@ -1840,6 +1894,18 @@
259182b6
ER
102 extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
103 png_bytepp image));
104
92006fdd 105+#ifdef PNG_WRITE_APNG_SUPPORTED
259182b6
ER
106+extern PNG_EXPORT (void,png_write_frame_head) PNGARG((png_structp png_ptr,
107+ png_infop png_info, png_bytepp row_pointers,
108+ png_uint_32 width, png_uint_32 height,
109+ png_uint_32 x_offset, png_uint_32 y_offset,
110+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
111+ png_byte blend_op));
112+
113+extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr,
114+ png_infop png_info));
115+#endif
116+
9f147502 117 /* Writes the end of the PNG file. */
259182b6
ER
118 extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
119 png_infop info_ptr));
580fd6fc 120@@ -2093,6 +2159,11 @@
259182b6
ER
121 png_voidp progressive_ptr,
122 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
123 png_progressive_end_ptr end_fn));
92006fdd 124+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
125+extern PNG_EXPORT(void,png_set_progressive_frame_fn) PNGARG((png_structp png_ptr,
126+ png_progressive_frame_ptr frame_info_fn,
127+ png_progressive_frame_ptr frame_end_fn));
128+#endif
129
9f147502 130 /* Returns the user pointer associated with the push read functions */
259182b6 131 extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
580fd6fc 132@@ -2533,6 +2604,59 @@
259182b6
ER
133 #endif
134 #endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
135
92006fdd 136+#ifdef PNG_APNG_SUPPORTED
259182b6
ER
137+extern PNG_EXPORT(png_uint_32,png_get_acTL) PNGARG((png_structp png_ptr,
138+ png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
139+extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr,
140+ png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
141+extern PNG_EXPORT(png_uint_32,png_get_num_frames) PNGARG((png_structp png_ptr,
142+ png_infop info_ptr));
143+extern PNG_EXPORT(png_uint_32,png_get_num_plays)
144+ PNGARG((png_structp png_ptr, png_infop info_ptr));
145+
146+extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL)
147+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
148+ png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
149+ png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
150+ png_byte *blend_op));
151+extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL)
152+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
153+ png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
154+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
155+ png_byte blend_op));
156+extern PNG_EXPORT(void,png_ensure_fcTL_is_valid)
157+ PNGARG((png_structp png_ptr,
158+ png_uint_32 width, png_uint_32 height,
159+ png_uint_32 x_offset, png_uint_32 y_offset,
160+ png_uint_16 delay_num, png_uint_16 delay_den,
161+ png_byte dispose_op, png_byte blend_op));
162+extern PNG_EXPORT(png_uint_32,png_get_next_frame_width)
163+ PNGARG((png_structp png_ptr, png_infop info_ptr));
164+extern PNG_EXPORT(png_uint_32,png_get_next_frame_height)
165+ PNGARG((png_structp png_ptr, png_infop info_ptr));
166+extern PNG_EXPORT(png_uint_32,png_get_next_frame_x_offset)
167+ PNGARG((png_structp png_ptr, png_infop info_ptr));
168+extern PNG_EXPORT(png_uint_32,png_get_next_frame_y_offset)
169+ PNGARG((png_structp png_ptr, png_infop info_ptr));
170+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_num)
171+ PNGARG((png_structp png_ptr, png_infop info_ptr));
172+extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_den)
173+ PNGARG((png_structp png_ptr, png_infop info_ptr));
174+extern PNG_EXPORT(png_byte,png_get_next_frame_dispose_op)
175+ PNGARG((png_structp png_ptr, png_infop info_ptr));
176+extern PNG_EXPORT(png_byte,png_get_next_frame_blend_op)
177+ PNGARG((png_structp png_ptr, png_infop info_ptr));
178+extern PNG_EXPORT(png_byte,png_get_first_frame_is_hidden)
179+ PNGARG((png_structp png_ptr, png_infop info_ptr));
180+extern PNG_EXPORT(png_uint_32,png_set_first_frame_is_hidden)
181+ PNGARG((png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
182+#endif /* PNG_APNG_SUPPORTED */
183+
92006fdd 184+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
185+extern PNG_EXPORT(void,png_read_frame_head) PNGARG((png_structp png_ptr,
186+ png_infop info_ptr));
187+#endif
188+
9f147502
KK
189 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
190 /* Provide a list of chunks and how they are to be handled, if the built-in
259182b6 191 handling or default unknown chunk handling is not desired. Any chunks not
580fd6fc 192@@ -2897,6 +3021,10 @@
259182b6
ER
193 #define PNG_BACKGROUND_IS_GRAY 0x800
194 #define PNG_HAVE_PNG_SIGNATURE 0x1000
195 #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
92006fdd 196+#ifdef PNG_APNG_SUPPORTED
259182b6
ER
197+#define PNG_HAVE_acTL 0x4000
198+#define PNG_HAVE_fcTL 0x8000L
92006fdd 199+#endif
259182b6 200
9f147502 201 /* Flags for the transformations the PNG library does on the image data */
259182b6 202 #define PNG_BGR 0x0001
580fd6fc 203@@ -3039,6 +3167,11 @@
259182b6
ER
204 #define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
205 #define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
206 #define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
92006fdd 207+#ifdef PNG_APNG_SUPPORTED
259182b6
ER
208+#define PNG_acTL png_byte png_acTL[5] = { 97, 99, 84, 76, '\0'}
209+#define PNG_fcTL png_byte png_fcTL[5] = {102, 99, 84, 76, '\0'}
210+#define PNG_fdAT png_byte png_fdAT[5] = {102, 100, 65, 84, '\0'}
92006fdd 211+#endif
259182b6
ER
212
213 #ifdef PNG_USE_GLOBAL_ARRAYS
214 PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5];
580fd6fc 215@@ -3062,6 +3195,11 @@
259182b6
ER
216 PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5];
217 PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5];
218 PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5];
92006fdd 219+#ifdef PNG_APNG_SUPPORTED
259182b6
ER
220+PNG_EXPORT_VAR (png_byte FARDATA) png_acTL[5];
221+PNG_EXPORT_VAR (png_byte FARDATA) png_fcTL[5];
222+PNG_EXPORT_VAR (png_byte FARDATA) png_fdAT[5];
580fd6fc
TP
223+#endif
224 #endif /* PNG_USE_GLOBAL_ARRAYS */
225
226 #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
227@@ -3344,6 +3482,17 @@
228 #endif
229 #endif
230
231+#ifdef PNG_WRITE_APNG_SUPPORTED
232+PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
233+ png_uint_32 num_frames, png_uint_32 num_plays)) PNG_PRIVATE;
259182b6 234+
580fd6fc
TP
235+PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
236+ png_uint_32 width, png_uint_32 height,
237+ png_uint_32 x_offset, png_uint_32 y_offset,
238+ png_uint_16 delay_num, png_uint_16 delay_den,
239+ png_byte dispose_op, png_byte blend_op)) PNG_PRIVATE;
240+#endif
259182b6 241+
580fd6fc
TP
242 /* Called when finished processing a row of data */
243 PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)) PNG_PRIVATE;
244
245@@ -3396,6 +3545,20 @@
246 PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
247 png_infop info_ptr)) PNG_PRIVATE;
248
249+#ifdef PNG_READ_APNG_SUPPORTED
250+/* Private, reset some things to become ready for reading next frame */
251+PNG_EXTERN void png_read_reset PNGARG((png_structp png_ptr)) PNG_PRIVATE;
252+PNG_EXTERN void png_read_reinit PNGARG((png_structp png_ptr,
253+ png_infop info_ptr)) PNG_PRIVATE;
254+PNG_EXTERN void png_progressive_read_reset PNGARG((png_structp png_ptr)) PNG_PRIVATE;
255+#endif
256+#ifdef PNG_WRITE_APNG_SUPPORTED
257+/* Private, reset some things to become ready for writing next frame */
258+PNG_EXTERN void png_write_reset PNGARG((png_structp png_ptr)) PNG_PRIVATE;
259+PNG_EXTERN void png_write_reinit PNGARG((png_structp png_ptr,
260+ png_infop info_ptr, png_uint_32 width, png_uint_32 height)) PNG_PRIVATE;
261+#endif
262+
263 /* These are the functions that do the transformations */
264 #ifdef PNG_READ_FILLER_SUPPORTED
265 PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
266@@ -3619,6 +3782,18 @@
267 png_uint_32 length)) PNG_PRIVATE;
268 #endif
269
270+#ifdef PNG_READ_APNG_SUPPORTED
271+PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr,
272+ png_uint_32 length)) PNG_PRIVATE;
273+PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr,
274+ png_uint_32 length)) PNG_PRIVATE;
275+PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr));
276+PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr,
277+ png_uint_32 length)) PNG_PRIVATE;
278+PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr,
279+ png_uint_32 length)) PNG_PRIVATE;
280+#endif
281+
282 PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
283 png_infop info_ptr, png_uint_32 length)) PNG_PRIVATE;
284
285diff -Naru libpng-1.2.41.org/pngconf.h libpng-1.2.41/pngconf.h
286--- libpng-1.2.41.org/pngconf.h 2009-12-04 21:30:08.000000000 +0900
287+++ libpng-1.2.41/pngconf.h 2009-12-04 21:30:08.000000000 +0900
288@@ -1008,6 +1008,10 @@
289 # define PNG_READ_tIME_SUPPORTED
290 # define PNG_tIME_SUPPORTED
e4744232
ER
291 #endif
292+#ifndef PNG_NO_READ_APNG
293+# define PNG_READ_APNG_SUPPORTED
294+# define PNG_APNG_SUPPORTED
259182b6 295+#endif
580fd6fc
TP
296 #ifndef PNG_NO_READ_tRNS
297 # define PNG_READ_tRNS_SUPPORTED
298 # define PNG_tRNS_SUPPORTED
299@@ -1170,6 +1174,14 @@
92006fdd 300 # define PNG_TEXT_SUPPORTED
e4744232
ER
301 # endif
302 #endif
303+#ifndef PNG_NO_WRITE_APNG
92006fdd
KK
304+# ifndef PNG_WRITE_APNG_SUPPORTED
305+# define PNG_WRITE_APNG_SUPPORTED
306+# endif
e4744232
ER
307+# ifndef PNG_APNG_SUPPORTED
308+# define PNG_APNG_SUPPORTED
309+# endif
310+#endif
92006fdd 311
580fd6fc
TP
312 #ifdef PNG_WRITE_tIME_SUPPORTED
313 # ifndef PNG_NO_CONVERT_tIME
314diff -Naru libpng-1.2.41.org/pngget.c libpng-1.2.41/pngget.c
315--- libpng-1.2.41.org/pngget.c 2009-12-04 21:30:08.000000000 +0900
316+++ libpng-1.2.41/pngget.c 2009-12-04 21:30:08.000000000 +0900
317@@ -842,6 +842,167 @@
318 }
319 #endif
92006fdd 320
580fd6fc
TP
321+#ifdef PNG_APNG_SUPPORTED
322+png_uint_32 PNGAPI
323+png_get_acTL(png_structp png_ptr, png_infop info_ptr,
324+ png_uint_32 *num_frames, png_uint_32 *num_plays)
325+{
326+ png_debug1(1, "in %s retrieval function", "acTL");
327+
328+ if (png_ptr != NULL && info_ptr != NULL &&
329+ (info_ptr->valid & PNG_INFO_acTL) &&
330+ num_frames != NULL && num_plays != NULL)
331+ {
332+ *num_frames = info_ptr->num_frames;
333+ *num_plays = info_ptr->num_plays;
334+ return (1);
335+ }
336+
337+ return (0);
338+}
339+
340+png_uint_32 PNGAPI
341+png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
342+{
343+ png_debug(1, "in png_get_num_frames()");
344+
345+ if (png_ptr != NULL && info_ptr != NULL)
346+ return (info_ptr->num_frames);
347+ return (0);
348+}
349+
350+png_uint_32 PNGAPI
351+png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
352+{
353+ png_debug(1, "in png_get_num_plays()");
354+
355+ if (png_ptr != NULL && info_ptr != NULL)
356+ return (info_ptr->num_plays);
357+ return (0);
358+}
359+
360+png_uint_32 PNGAPI
361+png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
362+ png_uint_32 *width, png_uint_32 *height,
363+ png_uint_32 *x_offset, png_uint_32 *y_offset,
364+ png_uint_16 *delay_num, png_uint_16 *delay_den,
365+ png_byte *dispose_op, png_byte *blend_op)
366+{
367+ png_debug1(1, "in %s retrieval function", "fcTL");
368+
369+ if (png_ptr != NULL && info_ptr != NULL &&
370+ (info_ptr->valid & PNG_INFO_fcTL) &&
371+ width != NULL && height != NULL &&
372+ x_offset != NULL && x_offset != NULL &&
373+ delay_num != NULL && delay_den != NULL &&
374+ dispose_op != NULL && blend_op != NULL)
375+ {
376+ *width = info_ptr->next_frame_width;
377+ *height = info_ptr->next_frame_height;
378+ *x_offset = info_ptr->next_frame_x_offset;
379+ *y_offset = info_ptr->next_frame_y_offset;
380+ *delay_num = info_ptr->next_frame_delay_num;
381+ *delay_den = info_ptr->next_frame_delay_den;
382+ *dispose_op = info_ptr->next_frame_dispose_op;
383+ *blend_op = info_ptr->next_frame_blend_op;
384+ return (1);
385+ }
386+
387+ return (0);
388+}
389+
390+png_uint_32 PNGAPI
391+png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
392+{
393+ png_debug(1, "in png_get_next_frame_width()");
394+
395+ if (png_ptr != NULL && info_ptr != NULL)
396+ return (info_ptr->next_frame_width);
397+ return (0);
398+}
399+
400+png_uint_32 PNGAPI
401+png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
402+{
403+ png_debug(1, "in png_get_next_frame_height()");
404+
405+ if (png_ptr != NULL && info_ptr != NULL)
406+ return (info_ptr->next_frame_height);
407+ return (0);
408+}
409+
410+png_uint_32 PNGAPI
411+png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
412+{
413+ png_debug(1, "in png_get_next_frame_x_offset()");
414+
415+ if (png_ptr != NULL && info_ptr != NULL)
416+ return (info_ptr->next_frame_x_offset);
417+ return (0);
418+}
419+
420+png_uint_32 PNGAPI
421+png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
422+{
423+ png_debug(1, "in png_get_next_frame_y_offset()");
424+
425+ if (png_ptr != NULL && info_ptr != NULL)
426+ return (info_ptr->next_frame_y_offset);
427+ return (0);
428+}
429+
430+png_uint_16 PNGAPI
431+png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
432+{
433+ png_debug(1, "in png_get_next_frame_delay_num()");
434+
435+ if (png_ptr != NULL && info_ptr != NULL)
436+ return (info_ptr->next_frame_delay_num);
437+ return (0);
438+}
439+
440+png_uint_16 PNGAPI
441+png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
442+{
443+ png_debug(1, "in png_get_next_frame_delay_den()");
444+
445+ if (png_ptr != NULL && info_ptr != NULL)
446+ return (info_ptr->next_frame_delay_den);
447+ return (0);
448+}
449+
450+png_byte PNGAPI
451+png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
452+{
453+ png_debug(1, "in png_get_next_frame_dispose_op()");
454+
455+ if (png_ptr != NULL && info_ptr != NULL)
456+ return (info_ptr->next_frame_dispose_op);
457+ return (0);
458+}
459+
460+png_byte PNGAPI
461+png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
462+{
463+ png_debug(1, "in png_get_next_frame_blend_op()");
464+
465+ if (png_ptr != NULL && info_ptr != NULL)
466+ return (info_ptr->next_frame_blend_op);
467+ return (0);
468+}
469+
470+png_byte PNGAPI
471+png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
472+{
473+ png_debug(1, "in png_first_frame_is_hidden()");
474+
475+ if (png_ptr != NULL)
476+ return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
477+
478+ return 0;
479+}
480+#endif /* PNG_APNG_SUPPORTED */
481+
482 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
483 png_uint_32 PNGAPI
484 png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
485diff -Naru libpng-1.2.41.org/pngpread.c libpng-1.2.41/pngpread.c
486--- libpng-1.2.41.org/pngpread.c 2009-12-04 21:30:08.000000000 +0900
487+++ libpng-1.2.41/pngpread.c 2009-12-04 21:30:08.000000000 +0900
488@@ -206,6 +206,11 @@
489 #ifdef PNG_READ_zTXt_SUPPORTED
259182b6
ER
490 PNG_CONST PNG_zTXt;
491 #endif
580fd6fc 492+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
493+ PNG_CONST PNG_acTL;
494+ PNG_CONST PNG_fcTL;
495+ PNG_CONST PNG_fdAT;
496+#endif
497 #endif /* PNG_USE_LOCAL_ARRAYS */
580fd6fc 498
259182b6 499 /* First we make sure we have enough data for the 4 byte chunk name
580fd6fc 500@@ -232,6 +237,103 @@
259182b6
ER
501 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
502 }
6df9a45f 503
580fd6fc 504+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
505+ if (png_ptr->num_frames_read > 0 &&
506+ png_ptr->num_frames_read < info_ptr->num_frames)
507+ {
508+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
509+ {
92006fdd 510+ /* Discard trailing IDATs for the first frame */
259182b6
ER
511+ if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
512+ png_error(png_ptr, "out of place IDAT");
513+
514+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
515+ {
516+ png_push_save_buffer(png_ptr);
517+ return;
518+ }
519+ png_push_crc_skip(png_ptr, png_ptr->push_length);
520+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
521+ return;
522+ }
523+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
524+ {
525+ if (png_ptr->buffer_size < 4)
526+ {
527+ png_push_save_buffer(png_ptr);
528+ return;
529+ }
530+ png_ensure_sequence_number(png_ptr, 4);
531+
532+ if (!(png_ptr->mode & PNG_HAVE_fcTL))
533+ {
92006fdd 534+ /* Discard trailing fdATs for frames other than the first */
259182b6
ER
535+ if (png_ptr->num_frames_read < 2)
536+ png_error(png_ptr, "out of place fdAT");
537+
538+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
539+ {
540+ png_push_save_buffer(png_ptr);
541+ return;
542+ }
543+ png_push_crc_skip(png_ptr, png_ptr->push_length);
544+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
545+ return;
546+ }
547+ else
548+ {
549+ /* frame data follows */
550+ png_ptr->idat_size = png_ptr->push_length - 4;
551+ png_ptr->mode |= PNG_HAVE_IDAT;
552+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
553+
554+ return;
555+ }
556+ }
557+ else if(!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
558+ {
559+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
560+ {
561+ png_push_save_buffer(png_ptr);
562+ return;
563+ }
564+
565+ png_read_reset(png_ptr);
566+ png_ptr->mode &= ~PNG_HAVE_fcTL;
567+
568+ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
569+
570+ if (!(png_ptr->mode & PNG_HAVE_fcTL))
571+ png_error(png_ptr, "missing required fcTL chunk");
572+
573+ png_read_reinit(png_ptr, info_ptr);
574+ png_progressive_read_reset(png_ptr);
575+
576+ if (png_ptr->frame_info_fn != NULL)
577+ (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
578+
579+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
580+
581+ return;
582+ }
583+ else
584+ {
585+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
586+ {
587+ png_push_save_buffer(png_ptr);
588+ return;
589+ }
590+ png_warning(png_ptr, "Skipped (ignored) a chunk "
591+ "between APNG chunks");
592+ png_push_crc_skip(png_ptr, png_ptr->push_length);
593+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
594+ return;
595+ }
596+
597+ return;
598+ }
599+#endif /* PNG_READ_APNG_SUPPORTED */
580fd6fc 600+
259182b6 601 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
6df9a45f 602 if (png_ptr->mode & PNG_AFTER_IDAT)
259182b6 603 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
580fd6fc 604@@ -327,6 +429,9 @@
259182b6
ER
605 png_error(png_ptr, "Too many IDAT's found");
606 }
607
580fd6fc 608+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
609+ png_have_info(png_ptr, info_ptr);
610+#endif
611 png_ptr->idat_size = png_ptr->push_length;
612 png_ptr->mode |= PNG_HAVE_IDAT;
613 png_ptr->process_mode = PNG_READ_IDAT_MODE;
580fd6fc 614@@ -557,6 +662,38 @@
259182b6 615 }
6df9a45f 616
259182b6 617 #endif
580fd6fc 618+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
619+ else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4))
620+ {
621+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
622+ {
623+ png_push_save_buffer(png_ptr);
624+ return;
625+ }
92006fdd 626+
259182b6
ER
627+ png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
628+ }
629+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
630+ {
631+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
632+ {
633+ png_push_save_buffer(png_ptr);
634+ return;
635+ }
92006fdd 636+
259182b6
ER
637+ png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
638+ }
639+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
640+ {
641+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
642+ {
643+ png_push_save_buffer(png_ptr);
644+ return;
645+ }
92006fdd 646+
259182b6
ER
647+ png_handle_fdAT(png_ptr, info_ptr, png_ptr->push_length);
648+ }
649+#endif /* PNG_READ_APNG_SUPPORTED */
650 else
651 {
652 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
580fd6fc 653@@ -731,13 +868,17 @@
259182b6
ER
654 png_push_read_IDAT(png_structp png_ptr)
655 {
656 #ifdef PNG_USE_LOCAL_ARRAYS
657- PNG_CONST PNG_IDAT;
658+ PNG_IDAT;
580fd6fc 659+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
660+ PNG_fdAT;
661+ PNG_IEND;
259182b6 662+#endif
6df9a45f 663 #endif
259182b6
ER
664 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
665 {
666 png_byte chunk_length[4];
667
668- if (png_ptr->buffer_size < 8)
669+ if (png_ptr->buffer_size < 12)
670 {
671 png_push_save_buffer(png_ptr);
672 return;
580fd6fc 673@@ -749,15 +890,62 @@
259182b6
ER
674 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
675 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
676
677- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
580fd6fc 678+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
679+ if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_fdAT, 4)
680+ && png_ptr->num_frames_read > 0)
6df9a45f 681+ {
259182b6
ER
682+ if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)
683+ {
684+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
685+ if (png_ptr->frame_end_fn != NULL)
686+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
687+ png_ptr->num_frames_read++;
688+ return;
689+ }
690+ else
691+ {
692+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
693+ png_error(png_ptr, "Not enough image data");
694+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
695+ {
696+ png_push_save_buffer(png_ptr);
697+ return;
698+ }
699+ png_warning(png_ptr, "Skipping (ignoring) a chunk between "
700+ "APNG chunks");
701+ png_crc_finish(png_ptr, png_ptr->push_length);
702+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
703+ return;
704+ }
705+ }
706+ else
707+#endif
6df9a45f 708+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)
580fd6fc 709+#ifdef PNG_READ_APNG_SUPPORTED
92006fdd 710+ && (png_ptr->num_frames_read == 0)
6df9a45f 711+#endif
92006fdd 712+ )
6df9a45f 713 {
259182b6
ER
714 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
715 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
716 png_error(png_ptr, "Not enough compressed data");
580fd6fc 717+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
718+ if (png_ptr->frame_end_fn != NULL)
719+ (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
720+ png_ptr->num_frames_read++;
721+#endif
722 return;
723 }
724
725 png_ptr->idat_size = png_ptr->push_length;
580fd6fc
TP
726+
727+#ifdef PNG_READ_APNG_SUPPORTED
92006fdd 728+ if (png_ptr->num_frames_read > 0)
259182b6
ER
729+ {
730+ png_ensure_sequence_number(png_ptr, 4);
731+ png_ptr->idat_size -= 4;
732+ }
733+#endif
734 }
735 if (png_ptr->idat_size && png_ptr->save_buffer_size)
736 {
580fd6fc 737@@ -1719,6 +1907,17 @@
259182b6
ER
738 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
739 }
740
580fd6fc 741+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
742+void PNGAPI
743+png_set_progressive_frame_fn(png_structp png_ptr,
744+ png_progressive_frame_ptr frame_info_fn,
745+ png_progressive_frame_ptr frame_end_fn)
746+{
747+ png_ptr->frame_info_fn = frame_info_fn;
748+ png_ptr->frame_end_fn = frame_end_fn;
749+}
750+#endif
751+
752 png_voidp PNGAPI
753 png_get_progressive_ptr(png_structp png_ptr)
754 {
580fd6fc
TP
755diff -Naru libpng-1.2.41.org/pngread.c libpng-1.2.41/pngread.c
756--- libpng-1.2.41.org/pngread.c 2009-12-04 21:30:08.000000000 +0900
757+++ libpng-1.2.41/pngread.c 2009-12-04 21:30:08.000000000 +0900
758@@ -423,6 +423,11 @@
759 #ifdef PNG_READ_zTXt_SUPPORTED
760 PNG_CONST PNG_zTXt;
761 #endif
762+#ifdef PNG_READ_APNG_SUPPORTED
763+ PNG_CONST PNG_acTL;
764+ PNG_CONST PNG_fcTL;
765+ PNG_CONST PNG_fdAT;
766+#endif
767 #endif /* PNG_USE_LOCAL_ARRAYS */
768 png_uint_32 length = png_read_chunk_header(png_ptr);
769 PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
770@@ -467,6 +472,9 @@
771 !(png_ptr->mode & PNG_HAVE_PLTE))
772 png_error(png_ptr, "Missing PLTE before IDAT");
773
774+#ifdef PNG_READ_APNG_SUPPORTED
775+ png_have_info(png_ptr, info_ptr);
776+#endif
777 png_ptr->idat_size = length;
778 png_ptr->mode |= PNG_HAVE_IDAT;
779 break;
780@@ -539,12 +547,97 @@
781 else if (!png_memcmp(chunk_name, png_iTXt, 4))
782 png_handle_iTXt(png_ptr, info_ptr, length);
783 #endif
784+#ifdef PNG_READ_APNG_SUPPORTED
785+ else if (!png_memcmp(chunk_name, png_acTL, 4))
786+ png_handle_acTL(png_ptr, info_ptr, length);
787+ else if (!png_memcmp(chunk_name, png_fcTL, 4))
788+ png_handle_fcTL(png_ptr, info_ptr, length);
789+ else if (!png_memcmp(chunk_name, png_fdAT, 4))
790+ png_handle_fdAT(png_ptr, info_ptr, length);
e4744232 791+#endif
580fd6fc
TP
792 else
793 png_handle_unknown(png_ptr, info_ptr, length);
794 }
e4744232 795 }
580fd6fc 796 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
e4744232 797
580fd6fc
TP
798+#ifdef PNG_READ_APNG_SUPPORTED
799+void PNGAPI
800+png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
e4744232 801+{
580fd6fc 802+ png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
e4744232 803+
580fd6fc 804+ png_debug(0, "Reading frame head");
e4744232 805+
580fd6fc
TP
806+ if (!(png_ptr->mode & PNG_HAVE_acTL))
807+ png_error(png_ptr, "attempt to png_read_frame_head() but "
808+ "no acTL present");
e4744232 809+
580fd6fc
TP
810+ /* do nothing for the main IDAT */
811+ if (png_ptr->num_frames_read == 0)
812+ return;
e4744232 813+
580fd6fc 814+ png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
e4744232 815+
580fd6fc
TP
816+ png_read_reset(png_ptr);
817+ png_ptr->mode &= ~PNG_HAVE_fcTL;
818+
819+ have_chunk_after_DAT = 0;
820+ for (;;)
6df9a45f 821+ {
580fd6fc
TP
822+#ifdef PNG_USE_LOCAL_ARRAYS
823+ PNG_IDAT;
824+ PNG_fdAT;
825+ PNG_fcTL;
826+#endif
827+ png_byte chunk_length[4];
828+ png_uint_32 length;
829+
830+ png_read_data(png_ptr, chunk_length, 4);
831+ length = png_get_uint_31(png_ptr, chunk_length);
832+
833+ png_reset_crc(png_ptr);
834+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
835+
836+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
6df9a45f 837+ {
580fd6fc
TP
838+ /* discard trailing IDATs for the first frame */
839+ if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
840+ png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
841+ png_crc_finish(png_ptr, length);
842+ }
843+ else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
844+ {
845+ png_handle_fcTL(png_ptr, info_ptr, length);
846+ have_chunk_after_DAT = 1;
847+ }
848+ else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
849+ {
850+ png_ensure_sequence_number(png_ptr, length);
851+
852+ /* discard trailing fdATs for frames other than the first */
853+ if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
854+ png_crc_finish(png_ptr, length - 4);
855+ else if(png_ptr->mode & PNG_HAVE_fcTL)
856+ {
857+ png_ptr->idat_size = length - 4;
858+ png_ptr->mode |= PNG_HAVE_IDAT;
859+
860+ break;
861+ }
862+ else
863+ png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
864+ }
865+ else
866+ {
867+ png_warning(png_ptr, "Skipped (ignored) a chunk "
868+ "between APNG chunks");
869+ png_crc_finish(png_ptr, length);
6df9a45f 870+ }
871+ }
e4744232 872+}
580fd6fc 873+#endif /* PNG_READ_APNG_SUPPORTED */
e4744232 874+
580fd6fc 875 /* Optional call to update the users info_ptr structure */
e4744232 876 void PNGAPI
580fd6fc
TP
877 png_read_update_info(png_structp png_ptr, png_infop info_ptr)
878@@ -584,6 +677,10 @@
879 png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
880 {
881 PNG_CONST PNG_IDAT;
882+#ifdef PNG_READ_APNG_SUPPORTED
883+ PNG_CONST PNG_fdAT;
884+ PNG_CONST PNG_IEND;
885+#endif
886 PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
887 0xff};
888 PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
889@@ -716,13 +813,39 @@
890 {
891 if (!(png_ptr->zstream.avail_in))
892 {
893- while (!png_ptr->idat_size)
894+ png_uint_32 bytes_to_skip = 0;
895+
896+ while (!png_ptr->idat_size || bytes_to_skip != 0)
897 {
898- png_crc_finish(png_ptr, 0);
899-
900+ png_crc_finish(png_ptr, bytes_to_skip);
901+ bytes_to_skip = 0;
902+
903 png_ptr->idat_size = png_read_chunk_header(png_ptr);
904- if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
905- png_error(png_ptr, "Not enough image data");
906+#ifdef PNG_READ_APNG_SUPPORTED
907+ if (png_ptr->num_frames_read == 0)
908+ {
909+#endif
910+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
911+ png_error(png_ptr, "Not enough image data");
912+#ifdef PNG_READ_APNG_SUPPORTED
913+ }
914+ else
915+ {
916+ if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
917+ png_error(png_ptr, "Not enough image data");
918+ if (png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
919+ {
920+ png_warning(png_ptr, "Skipped (ignored) a chunk "
921+ "between APNG chunks");
922+ bytes_to_skip = png_ptr->idat_size;
923+ continue;
924+ }
925+
926+ png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
927+
928+ png_ptr->idat_size -= 4;
929+ }
930+#endif
931 }
932 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
933 png_ptr->zstream.next_in = png_ptr->zbuf;
934@@ -740,6 +863,9 @@
935 png_error(png_ptr, "Extra compressed data");
936 png_ptr->mode |= PNG_AFTER_IDAT;
937 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
938+#ifdef PNG_READ_APNG_SUPPORTED
939+ png_ptr->num_frames_read++;
940+#endif
941 break;
942 }
943 if (ret != Z_OK)
944@@ -997,6 +1123,11 @@
945 #ifdef PNG_READ_zTXt_SUPPORTED
946 PNG_CONST PNG_zTXt;
947 #endif
948+#ifdef PNG_READ_APNG_SUPPORTED
949+ PNG_CONST PNG_acTL;
950+ PNG_CONST PNG_fcTL;
951+ PNG_CONST PNG_fdAT;
952+#endif
953 #endif /* PNG_USE_LOCAL_ARRAYS */
954 png_uint_32 length = png_read_chunk_header(png_ptr);
955 PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
956@@ -1097,6 +1228,14 @@
957 else if (!png_memcmp(chunk_name, png_iTXt, 4))
958 png_handle_iTXt(png_ptr, info_ptr, length);
959 #endif
960+#ifdef PNG_READ_APNG_SUPPORTED
961+ else if (!png_memcmp(chunk_name, png_acTL, 4))
962+ png_handle_acTL(png_ptr, info_ptr, length);
963+ else if (!png_memcmp(chunk_name, png_fcTL, 4))
964+ png_handle_fcTL(png_ptr, info_ptr, length);
965+ else if (!png_memcmp(chunk_name, png_fdAT, 4))
966+ png_handle_fdAT(png_ptr, info_ptr, length);
967+#endif
968 else
969 png_handle_unknown(png_ptr, info_ptr, length);
970 } while (!(png_ptr->mode & PNG_HAVE_IEND));
971diff -Naru libpng-1.2.41.org/pngrtran.c libpng-1.2.41/pngrtran.c
972--- libpng-1.2.41.org/pngrtran.c 2009-12-04 21:30:08.000000000 +0900
973+++ libpng-1.2.41/pngrtran.c 2009-12-04 21:30:08.000000000 +0900
974@@ -1346,7 +1346,7 @@
975 * pixels. This check added to libpng-1.2.19
976 */
977 #if (PNG_WARN_UNINITIALIZED_ROW==1)
978- png_error(png_ptr, "Uninitialized row");
979+ png_warning(png_ptr, "Uninitialized row");
980 #else
981 png_warning(png_ptr, "Uninitialized row");
982 #endif
983diff -Naru libpng-1.2.41.org/pngrutil.c libpng-1.2.41/pngrutil.c
984--- libpng-1.2.41.org/pngrutil.c 2009-12-04 21:30:08.000000000 +0900
985+++ libpng-1.2.41/pngrutil.c 2009-12-04 21:30:08.000000000 +0900
986@@ -425,6 +425,11 @@
259182b6
ER
987 filter_type = buf[11];
988 interlace_type = buf[12];
989
580fd6fc 990+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
991+ png_ptr->first_frame_width = width;
992+ png_ptr->first_frame_height = height;
993+#endif
994+
6df9a45f 995 /* Set internal variables */
259182b6
ER
996 png_ptr->width = width;
997 png_ptr->height = height;
580fd6fc 998@@ -2227,6 +2232,168 @@
259182b6
ER
999 }
1000 #endif
1001
580fd6fc 1002+#ifdef PNG_READ_APNG_SUPPORTED
259182b6
ER
1003+void /* PRIVATE */
1004+png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1005+{
1006+ png_byte data[8];
1007+ png_uint_32 num_frames;
1008+ png_uint_32 num_plays;
1009+ png_uint_32 didSet;
1010+
6df9a45f 1011+ png_debug(1, "in png_handle_acTL");
259182b6
ER
1012+
1013+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
1014+ {
1015+ png_error(png_ptr, "Missing IHDR before acTL");
1016+ }
1017+ else if (png_ptr->mode & PNG_HAVE_IDAT)
1018+ {
1019+ png_warning(png_ptr, "Invalid acTL after IDAT skipped");
1020+ png_crc_finish(png_ptr, length);
1021+ return;
1022+ }
1023+ else if (png_ptr->mode & PNG_HAVE_acTL)
1024+ {
1025+ png_warning(png_ptr, "Duplicate acTL skipped");
1026+ png_crc_finish(png_ptr, length);
1027+ return;
1028+ }
1029+ else if (length != 8)
1030+ {
1031+ png_warning(png_ptr, "acTL with invalid length skipped");
1032+ png_crc_finish(png_ptr, length);
1033+ return;
1034+ }
1035+
1036+ png_crc_read(png_ptr, data, 8);
1037+ png_crc_finish(png_ptr, 0);
1038+
1039+ num_frames = png_get_uint_31(png_ptr, data);
1040+ num_plays = png_get_uint_31(png_ptr, data + 4);
1041+
1042+ /* the set function will do error checking on num_frames */
1043+ didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
1044+ if(didSet)
1045+ png_ptr->mode |= PNG_HAVE_acTL;
1046+}
1047+
1048+void /* PRIVATE */
1049+png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1050+{
1051+ png_byte data[22];
1052+ png_uint_32 width;
1053+ png_uint_32 height;
1054+ png_uint_32 x_offset;
1055+ png_uint_32 y_offset;
1056+ png_uint_16 delay_num;
1057+ png_uint_16 delay_den;
1058+ png_byte dispose_op;
1059+ png_byte blend_op;
1060+
6df9a45f 1061+ png_debug(1, "in png_handle_fcTL");
259182b6
ER
1062+
1063+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
1064+ {
1065+ png_error(png_ptr, "Missing IHDR before fcTL");
1066+ }
1067+ else if (png_ptr->mode & PNG_HAVE_IDAT)
1068+ {
1069+ /* for any frames other then the first this message may be misleading,
1070+ * but correct. PNG_HAVE_IDAT is unset before the frame head is read
1071+ * i can't think of a better message */
1072+ png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
1073+ png_crc_finish(png_ptr, length);
1074+ return;
1075+ }
1076+ else if (png_ptr->mode & PNG_HAVE_fcTL)
1077+ {
1078+ png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
1079+ png_crc_finish(png_ptr, length);
1080+ return;
1081+ }
1082+ else if (length != 26)
1083+ {
1084+ png_warning(png_ptr, "fcTL with invalid length skipped");
1085+ png_crc_finish(png_ptr, length);
1086+ return;
1087+ }
1088+
1089+ png_ensure_sequence_number(png_ptr, length);
1090+
1091+ png_crc_read(png_ptr, data, 22);
1092+ png_crc_finish(png_ptr, 0);
1093+
1094+ width = png_get_uint_31(png_ptr, data);
1095+ height = png_get_uint_31(png_ptr, data + 4);
1096+ x_offset = png_get_uint_31(png_ptr, data + 8);
1097+ y_offset = png_get_uint_31(png_ptr, data + 12);
1098+ delay_num = png_get_uint_16(data + 16);
1099+ delay_den = png_get_uint_16(data + 18);
1100+ dispose_op = data[20];
1101+ blend_op = data[21];
1102+
1103+ if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
1104+ png_error(png_ptr, "fcTL for the first frame must have zero offset");
1105+ if (png_ptr->num_frames_read == 0 &&
1106+ (width != info_ptr->width || height != info_ptr->height))
1107+ png_error(png_ptr, "size in first frame's fcTL must match "
1108+ "the size in IHDR");
1109+
1110+ /* the set function will do more error checking */
1111+ png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
1112+ x_offset, y_offset, delay_num, delay_den,
1113+ dispose_op, blend_op);
1114+
1115+ png_read_reinit(png_ptr, info_ptr);
1116+
1117+ png_ptr->mode |= PNG_HAVE_fcTL;
1118+}
1119+
1120+void /* PRIVATE */
1121+png_have_info(png_structp png_ptr, png_infop info_ptr)
1122+{
1123+ if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
1124+ {
1125+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
1126+ info_ptr->num_frames++;
1127+ }
1128+}
1129+
1130+void /* PRIVATE */
580fd6fc
TP
1131+png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1132+{
1133+ png_ensure_sequence_number(png_ptr, length);
1134+
1135+ /* This function is only called from png_read_end(), png_read_info(),
1136+ * and png_push_read_chunk() which means that:
1137+ * - the user doesn't want to read this frame
1138+ * - or this is an out-of-place fdAT
1139+ * in either case it is safe to ignore the chunk with a warning */
1140+ png_warning(png_ptr, "ignoring fdAT chunk");
1141+ png_crc_finish(png_ptr, length - 4);
1142+}
1143+
1144+void /* PRIVATE */
1145+png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
1146+{
1147+ png_byte data[4];
1148+ png_uint_32 sequence_number;
1149+
1150+ if (length < 4)
1151+ png_error(png_ptr, "invalid fcTL or fdAT chunk found");
1152+
1153+ png_crc_read(png_ptr, data, 4);
1154+ sequence_number = png_get_uint_31(png_ptr, data);
1155+
1156+ if (sequence_number != png_ptr->next_seq_num)
1157+ png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
1158+ "number found");
1159+
1160+ png_ptr->next_seq_num++;
1161+}
1162+#endif /* PNG_READ_APNG_SUPPORTED */
1163+
1164 /* This function is called when we haven't found a handler for a
1165 chunk. If there isn't a problem with the chunk itself (ie bad
1166 chunk name, CRC, or a critical chunk), the chunk is silently ignored
1167@@ -3240,4 +3407,84 @@
1168
1169 png_ptr->flags |= PNG_FLAG_ROW_INIT;
1170 }
1171+
1172+#ifdef PNG_READ_APNG_SUPPORTED
1173+/* This function is to be called after the main IDAT set has been read and
1174+ * before a new IDAT is read. It resets some parts of png_ptr
1175+ * to make them usable by the read functions again */
1176+void /* PRIVATE */
1177+png_read_reset(png_structp png_ptr)
1178+{
1179+ png_ptr->mode &= ~PNG_HAVE_IDAT;
1180+ png_ptr->mode &= ~PNG_AFTER_IDAT;
1181+ png_ptr->row_number = 0;
1182+ png_ptr->pass = 0;
1183+ png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
1184+}
1185+
1186+void /* PRIVATE */
1187+png_read_reinit(png_structp png_ptr, png_infop info_ptr)
1188+{
1189+ png_ptr->width = info_ptr->next_frame_width;
1190+ png_ptr->height = info_ptr->next_frame_height;
1191+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
1192+ if (png_ptr->prev_row)
1193+ png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
1194+}
1195+
1196+/* same as png_read_reset() but for the progressive reader */
1197+void /* PRIVATE */
1198+png_progressive_read_reset(png_structp png_ptr)
1199+{
1200+#ifdef PNG_USE_LOCAL_ARRAYS
1201+ /* start of interlace block */
1202+ const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1203+
1204+ /* offset to next interlace block */
1205+ const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1206+
1207+ /* start of interlace block in the y direction */
1208+ const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1209+
1210+ /* offset to next interlace block in the y direction */
1211+ const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1212+#endif
1213+ png_uint_32 row_bytes;
1214+
1215+ if (png_ptr->interlaced)
1216+ {
1217+ if (!(png_ptr->transformations & PNG_INTERLACE))
1218+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
1219+ png_pass_ystart[0]) / png_pass_yinc[0];
1220+ else
1221+ png_ptr->num_rows = png_ptr->height;
1222+
1223+ png_ptr->iwidth = (png_ptr->width +
1224+ png_pass_inc[png_ptr->pass] - 1 -
1225+ png_pass_start[png_ptr->pass]) /
1226+ png_pass_inc[png_ptr->pass];
1227+
1228+ row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
1229+
1230+ png_ptr->irowbytes = (png_size_t)row_bytes;
1231+ if((png_uint_32)png_ptr->irowbytes != row_bytes)
1232+ png_error(png_ptr, "png_progressive_read_reset(): Rowbytes "
1233+ "overflow");
1234+ }
1235+ else
1236+ {
1237+ png_ptr->num_rows = png_ptr->height;
1238+ png_ptr->iwidth = png_ptr->width;
1239+ png_ptr->irowbytes = png_ptr->rowbytes + 1;
1240+ }
1241+
1242+ png_ptr->flags &= ~PNG_FLAG_ZLIB_FINISHED;
1243+ if (inflateReset(&(png_ptr->zstream)) != Z_OK)
1244+ png_error(png_ptr, "inflateReset failed");
1245+ png_ptr->zstream.avail_in = 0;
1246+ png_ptr->zstream.next_in = 0;
1247+ png_ptr->zstream.next_out = png_ptr->row_buf;
1248+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
1249+}
1250+#endif /* PNG_READ_APNG_SUPPORTED */
1251 #endif /* PNG_READ_SUPPORTED */
1252diff -Naru libpng-1.2.41.org/pngset.c libpng-1.2.41/pngset.c
1253--- libpng-1.2.41.org/pngset.c 2009-12-04 21:30:08.000000000 +0900
1254+++ libpng-1.2.41/pngset.c 2009-12-04 21:30:08.000000000 +0900
1255@@ -266,6 +266,11 @@
1256 info_ptr->rowbytes = (png_size_t)0;
1257 else
1258 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
1259+
1260+#ifdef PNG_APNG_SUPPORTED
1261+ /* for non-animated png. this may be overritten from an acTL chunk later */
1262+ info_ptr->num_frames = 1;
1263+#endif
1264 }
1265
1266 #ifdef PNG_oFFs_SUPPORTED
1267@@ -960,6 +965,143 @@
1268 }
1269 #endif /* PNG_sPLT_SUPPORTED */
1270
1271+#ifdef PNG_APNG_SUPPORTED
1272+png_uint_32 PNGAPI
1273+png_set_acTL(png_structp png_ptr, png_infop info_ptr,
1274+ png_uint_32 num_frames, png_uint_32 num_plays)
1275+{
1276+ png_debug1(1, "in %s storage function", "acTL");
1277+
1278+ if (png_ptr == NULL || info_ptr == NULL)
1279+ {
1280+ png_warning(png_ptr,
1281+ "Call to png_set_acTL() with NULL png_ptr "
1282+ "or info_ptr ignored");
1283+ return (0);
1284+ }
1285+ if (num_frames == 0)
1286+ {
1287+ png_warning(png_ptr,
1288+ "Ignoring attempt to set acTL with num_frames zero");
1289+ return (0);
1290+ }
1291+ if (num_frames > PNG_UINT_31_MAX)
1292+ {
1293+ png_warning(png_ptr,
1294+ "Ignoring attempt to set acTL with num_frames > 2^31-1");
1295+ return (0);
1296+ }
1297+ if (num_plays > PNG_UINT_31_MAX)
1298+ {
1299+ png_warning(png_ptr,
1300+ "Ignoring attempt to set acTL with num_plays "
1301+ "> 2^31-1");
1302+ return (0);
1303+ }
1304+
1305+ info_ptr->num_frames = num_frames;
1306+ info_ptr->num_plays = num_plays;
1307+
1308+ info_ptr->valid |= PNG_INFO_acTL;
1309+
1310+ return (1);
1311+}
1312+
1313+/* delay_num and delay_den can hold any 16-bit values including zero */
1314+png_uint_32 PNGAPI
1315+png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
1316+ png_uint_32 width, png_uint_32 height,
1317+ png_uint_32 x_offset, png_uint_32 y_offset,
1318+ png_uint_16 delay_num, png_uint_16 delay_den,
1319+ png_byte dispose_op, png_byte blend_op)
1320+{
1321+ png_debug1(1, "in %s storage function", "fcTL");
1322+
1323+ if (png_ptr == NULL || info_ptr == NULL)
1324+ {
1325+ png_warning(png_ptr,
1326+ "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
1327+ "ignored");
1328+ return (0);
1329+ }
1330+
1331+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
1332+ delay_num, delay_den, dispose_op, blend_op);
1333+
1334+ if (blend_op == PNG_BLEND_OP_OVER)
1335+ {
1336+ if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
1337+ !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
1338+ {
1339+ png_warning(png_ptr,
1340+ "PNG_BLEND_OP_OVER is meaningless and wasteful "
1341+ "for opaque images, ignored");
1342+ blend_op = PNG_BLEND_OP_SOURCE;
1343+ }
1344+ }
1345+
1346+ info_ptr->next_frame_width = width;
1347+ info_ptr->next_frame_height = height;
1348+ info_ptr->next_frame_x_offset = x_offset;
1349+ info_ptr->next_frame_y_offset = y_offset;
1350+ info_ptr->next_frame_delay_num = delay_num;
1351+ info_ptr->next_frame_delay_den = delay_den;
1352+ info_ptr->next_frame_dispose_op = dispose_op;
1353+ info_ptr->next_frame_blend_op = blend_op;
1354+
1355+ info_ptr->valid |= PNG_INFO_fcTL;
1356+
1357+ return (1);
1358+}
1359+
1360+void /* PRIVATE */
1361+png_ensure_fcTL_is_valid(png_structp png_ptr,
1362+ png_uint_32 width, png_uint_32 height,
1363+ png_uint_32 x_offset, png_uint_32 y_offset,
1364+ png_uint_16 delay_num, png_uint_16 delay_den,
1365+ png_byte dispose_op, png_byte blend_op)
259182b6 1366+{
580fd6fc
TP
1367+ if (width + x_offset > png_ptr->first_frame_width ||
1368+ height + y_offset > png_ptr->first_frame_height)
1369+ png_error(png_ptr, "dimensions of a frame are greater than"
1370+ "the ones in IHDR");
1371+ if (width > PNG_UINT_31_MAX)
1372+ png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
1373+ if (height > PNG_UINT_31_MAX)
1374+ png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
1375+ if (x_offset > PNG_UINT_31_MAX)
1376+ png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
1377+ if (y_offset > PNG_UINT_31_MAX)
1378+ png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
1379+
1380+ if (dispose_op != PNG_DISPOSE_OP_NONE &&
1381+ dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
1382+ dispose_op != PNG_DISPOSE_OP_PREVIOUS)
1383+ png_error(png_ptr, "invalid dispose_op in fcTL");
1384+
1385+ if (blend_op != PNG_BLEND_OP_SOURCE &&
1386+ blend_op != PNG_BLEND_OP_OVER)
1387+ png_error(png_ptr, "invalid blend_op in fcTL");
259182b6
ER
1388+}
1389+
580fd6fc
TP
1390+png_uint_32 PNGAPI
1391+png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
1392+ png_byte is_hidden)
259182b6 1393+{
580fd6fc 1394+ png_debug(1, "in png_first_frame_is_hidden()");
259182b6 1395+
580fd6fc
TP
1396+ if (png_ptr == NULL)
1397+ return 0;
259182b6 1398+
580fd6fc
TP
1399+ if(is_hidden)
1400+ png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
1401+ else
1402+ png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
259182b6 1403+
580fd6fc 1404+ return 1;
259182b6 1405+}
580fd6fc 1406+#endif /* PNG_APNG_SUPPORTED */
259182b6 1407+
580fd6fc
TP
1408 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1409 void PNGAPI
1410 png_set_unknown_chunks(png_structp png_ptr,
1411diff -Naru libpng-1.2.41.org/pngtest.c libpng-1.2.41/pngtest.c
1412--- libpng-1.2.41.org/pngtest.c 2009-12-04 21:30:08.000000000 +0900
1413+++ libpng-1.2.41/pngtest.c 2009-12-04 21:30:08.000000000 +0900
1414@@ -701,6 +701,10 @@
1415 jmp_buf jmpbuf;
1416 #endif
1417 #endif
1418+#ifdef PNG_APNG_SUPPORTED
1419+ png_uint_32 num_frames;
1420+ png_uint_32 num_plays;
1421+#endif
259182b6 1422
580fd6fc
TP
1423 #ifdef _WIN32_WCE
1424 TCHAR path[MAX_PATH];
1425@@ -1126,6 +1130,20 @@
1426 }
1427 }
1428 #endif
1429+#ifdef PNG_APNG_SUPPORTED
1430+ if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
1431+ {
1432+ if (png_get_acTL(read_ptr, read_info_ptr, &num_frames, &num_plays))
1433+ {
1434+ png_byte is_hidden;
1435+ png_debug2(0, "Handling acTL chunks (frames %ld, plays %ld)",
1436+ num_frames, num_plays);
1437+ png_set_acTL(write_ptr, write_info_ptr, num_frames, num_plays);
1438+ is_hidden = png_get_first_frame_is_hidden(read_ptr, read_info_ptr);
1439+ png_set_first_frame_is_hidden(write_ptr, write_info_ptr, is_hidden);
1440+ }
1441+ }
1442+#endif
1443 #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
1444 {
1445 png_unknown_chunkp unknowns;
1446@@ -1213,6 +1231,89 @@
1447 t_misc += (t_stop - t_start);
1448 t_start = t_stop;
1449 #endif
1450+#ifdef PNG_APNG_SUPPORTED
1451+ if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
1452+ {
1453+ png_uint_32 frame;
1454+ for (frame = 0; frame < num_frames; frame++)
1455+ {
1456+ png_uint_32 frame_width;
1457+ png_uint_32 frame_height;
1458+ png_uint_32 x_offset;
1459+ png_uint_32 y_offset;
1460+ png_uint_16 delay_num;
1461+ png_uint_16 delay_den;
1462+ png_byte dispose_op;
1463+ png_byte blend_op;
1464+ png_read_frame_head(read_ptr, read_info_ptr);
1465+ if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_fcTL))
1466+ {
1467+ png_get_next_frame_fcTL(read_ptr, read_info_ptr,
1468+ &frame_width, &frame_height,
1469+ &x_offset, &y_offset,
1470+ &delay_num, &delay_den,
1471+ &dispose_op, &blend_op);
1472+ }
1473+ else
1474+ {
1475+ frame_width = width;
1476+ frame_height = height;
1477+ x_offset = 0;
1478+ y_offset = 0;
1479+ delay_num = 1;
1480+ delay_den = 1;
1481+ dispose_op = PNG_DISPOSE_OP_NONE;
1482+ blend_op = PNG_BLEND_OP_SOURCE;
1483+ }
1484+#ifdef PNG_WRITE_APNG_SUPPORTED
1485+ png_write_frame_head(write_ptr, write_info_ptr, row_buf,
1486+ frame_width, frame_height,
1487+ x_offset, y_offset,
1488+ delay_num, delay_den,
1489+ dispose_op, blend_op);
1490+#endif
1491+ for (pass = 0; pass < num_pass; pass++)
1492+ {
1493+ png_debug1(0, "Writing row data for pass %d", pass);
1494+ for (y = 0; y < height; y++)
1495+ {
1496+#ifndef SINGLE_ROWBUF_ALLOC
1497+ png_debug2(0, "Allocating row buffer (pass %d, y = %ld)...", pass, y);
1498+ row_buf = (png_bytep)png_malloc(read_ptr,
1499+ png_get_rowbytes(read_ptr, read_info_ptr));
1500+ png_debug2(0, "0x%08lx (%ld bytes)", (unsigned long)row_buf,
1501+ png_get_rowbytes(read_ptr, read_info_ptr));
1502+#endif /* !SINGLE_ROWBUF_ALLOC */
1503+ png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
1504+
1505+#ifdef PNG_WRITE_SUPPORTED
1506+#ifdef PNGTEST_TIMING
1507+ t_stop = (float)clock();
1508+ t_decode += (t_stop - t_start);
1509+ t_start = t_stop;
1510+#endif
1511+ png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
1512+#ifdef PNGTEST_TIMING
1513+ t_stop = (float)clock();
1514+ t_encode += (t_stop - t_start);
1515+ t_start = t_stop;
1516+#endif
1517+#endif /* PNG_WRITE_SUPPORTED */
259182b6 1518+
580fd6fc
TP
1519+#ifndef SINGLE_ROWBUF_ALLOC
1520+ png_debug2(0, "Freeing row buffer (pass %d, y = %ld)", pass, y);
1521+ png_free(read_ptr, row_buf);
1522+ row_buf = NULL;
1523+#endif /* !SINGLE_ROWBUF_ALLOC */
1524+ }
1525+ }
1526+#ifdef PNG_WRITE_APNG_SUPPORTED
1527+ png_write_frame_tail(write_ptr, write_info_ptr);
1528+#endif
1529+ }
1530+ }
1531+ else
1532+#endif
1533 for (pass = 0; pass < num_pass; pass++)
1534 {
1535 png_debug1(0, "Writing row data for pass %d", pass);
1536diff -Naru libpng-1.2.41.org/pngwrite.c libpng-1.2.41/pngwrite.c
1537--- libpng-1.2.41.org/pngwrite.c 2009-12-04 21:30:08.000000000 +0900
1538+++ libpng-1.2.41/pngwrite.c 2009-12-04 21:30:08.000000000 +0900
1539@@ -56,6 +56,10 @@
1540 /* The rest of these check to see if the valid field has the appropriate
1541 * flag set, and if it does, writes the chunk.
1542 */
1543+#ifdef PNG_WRITE_APNG_SUPPORTED
1544+ if (info_ptr->valid & PNG_INFO_acTL)
1545+ png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
1546+#endif
1547 #ifdef PNG_WRITE_gAMA_SUPPORTED
1548 if (info_ptr->valid & PNG_INFO_gAMA)
1549 {
1550@@ -318,6 +322,10 @@
1551 return;
1552 if (!(png_ptr->mode & PNG_HAVE_IDAT))
1553 png_error(png_ptr, "No IDATs written into file");
1554+#ifdef PNG_WRITE_APNG_SUPPORTED
1555+ if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
1556+ png_error(png_ptr, "Not enough frames written");
1557+#endif
1558
1559 /* See if user wants us to write information chunks */
1560 if (info_ptr != NULL)
1561@@ -1582,4 +1590,39 @@
1562 params = params;
1563 }
1564 #endif
259182b6 1565+
580fd6fc
TP
1566+#ifdef PNG_WRITE_APNG_SUPPORTED
1567+void PNGAPI
1568+png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
1569+ png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
1570+ png_uint_32 x_offset, png_uint_32 y_offset,
1571+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
1572+ png_byte blend_op)
259182b6 1573+{
580fd6fc
TP
1574+ png_debug(1, "in png_write_frame_head");
1575+
1576+ /* there is a chance this has been set after png_write_info was called,
1577+ * so it would be set but not written. is there a way to be sure? */
1578+ if (!(info_ptr->valid & PNG_INFO_acTL))
1579+ png_error(png_ptr, "png_write_frame_head(): acTL not set");
1580+
1581+ png_write_reset(png_ptr);
1582+
1583+ png_write_reinit(png_ptr, info_ptr, width, height);
1584+
1585+ if ( !(png_ptr->num_frames_written == 0 &&
1586+ (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
1587+ png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
1588+ delay_num, delay_den, dispose_op, blend_op);
259182b6
ER
1589+}
1590+
580fd6fc
TP
1591+void PNGAPI
1592+png_write_frame_tail(png_structp png_ptr, png_infop png_info)
259182b6 1593+{
580fd6fc 1594+ png_debug(1, "in png_write_frame_tail");
259182b6 1595+
580fd6fc 1596+ png_ptr->num_frames_written++;
259182b6 1597+}
580fd6fc
TP
1598+#endif /* PNG_WRITE_APNG_SUPPORTED */
1599+
1600 #endif /* PNG_WRITE_SUPPORTED */
1601diff -Naru libpng-1.2.41.org/pngwutil.c libpng-1.2.41/pngwutil.c
1602--- libpng-1.2.41.org/pngwutil.c 2009-12-04 21:30:08.000000000 +0900
1603+++ libpng-1.2.41/pngwutil.c 2009-12-04 21:30:08.000000000 +0900
1604@@ -515,6 +515,11 @@
6df9a45f 1605 /* Write the chunk */
c501f448 1606 png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
259182b6 1607
580fd6fc 1608+#ifdef PNG_WRITE_APNG_SUPPORTED
259182b6
ER
1609+ png_ptr->first_frame_width = width;
1610+ png_ptr->first_frame_height = height;
1611+#endif
1612+
6df9a45f 1613 /* Initialize zlib with PNG info */
259182b6
ER
1614 png_ptr->zstream.zalloc = png_zalloc;
1615 png_ptr->zstream.zfree = png_zfree;
580fd6fc 1616@@ -638,6 +643,9 @@
259182b6
ER
1617 {
1618 #ifdef PNG_USE_LOCAL_ARRAYS
1619 PNG_IDAT;
580fd6fc 1620+#ifdef PNG_WRITE_APNG_SUPPORTED
259182b6 1621+ PNG_fdAT;
259182b6 1622+#endif
c501f448 1623 #endif
259182b6 1624
92006fdd 1625 png_debug(1, "in png_write_IDAT");
580fd6fc 1626@@ -683,7 +691,28 @@
259182b6
ER
1627 "Invalid zlib compression method or flags in IDAT");
1628 }
1629
580fd6fc
TP
1630- png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
1631+#ifdef PNG_WRITE_APNG_SUPPORTED
259182b6
ER
1632+ if(png_ptr->num_frames_written == 0)
1633+#endif
580fd6fc
TP
1634+ png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
1635+#ifdef PNG_WRITE_APNG_SUPPORTED
259182b6
ER
1636+ else
1637+ {
1638+ png_byte buf[4];
1639+
1640+ png_write_chunk_start(png_ptr, (png_bytep)png_fdAT, 4 + length);
1641+
1642+ png_save_uint_32(buf, png_ptr->next_seq_num);
1643+ png_write_chunk_data(png_ptr, buf, 4);
1644+
1645+ png_write_chunk_data(png_ptr, data, length);
1646+
1647+ png_write_chunk_end(png_ptr);
1648+
1649+ png_ptr->next_seq_num++;
1650+ }
1651+#endif
1652+
1653 png_ptr->mode |= PNG_HAVE_IDAT;
1654 }
1655
580fd6fc 1656@@ -1750,6 +1779,70 @@
259182b6
ER
1657 }
1658 #endif
1659
580fd6fc 1660+#ifdef PNG_WRITE_APNG_SUPPORTED
259182b6
ER
1661+void /* PRIVATE */
1662+png_write_acTL(png_structp png_ptr,
1663+ png_uint_32 num_frames, png_uint_32 num_plays)
1664+{
1665+#ifdef PNG_USE_LOCAL_ARRAYS
1666+ PNG_acTL;
1667+#endif
1668+ png_byte data[16];
1669+
6df9a45f 1670+ png_debug(1, "in png_write_acTL");
259182b6
ER
1671+
1672+ png_ptr->num_frames_to_write = num_frames;
1673+
1674+ if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
1675+ num_frames--;
1676+
1677+ png_save_uint_32(data, num_frames);
1678+ png_save_uint_32(data + 4, num_plays);
1679+
1680+ png_write_chunk(png_ptr, (png_bytep)png_acTL, data, (png_size_t)8);
1681+}
1682+
1683+void /* PRIVATE */
1684+png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
1685+ png_uint_32 x_offset, png_uint_32 y_offset,
1686+ png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
1687+ png_byte blend_op)
1688+{
1689+#ifdef PNG_USE_LOCAL_ARRAYS
1690+ PNG_fcTL;
1691+#endif
1692+ png_byte data[26];
1693+
6df9a45f 1694+ png_debug(1, "in png_write_fcTL");
259182b6
ER
1695+
1696+ if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
6df9a45f 1697+ png_error(png_ptr, "x and/or y offset for the first frame aren't 0");
259182b6
ER
1698+ if (png_ptr->num_frames_written == 0 &&
1699+ (width != png_ptr->first_frame_width ||
1700+ height != png_ptr->first_frame_height))
1701+ png_error(png_ptr, "width and/or height in the first frame's fcTL "
6df9a45f 1702+ "don't match the ones in IHDR");
259182b6
ER
1703+
1704+ /* more error checking */
1705+ png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
1706+ delay_num, delay_den, dispose_op, blend_op);
1707+
1708+ png_save_uint_32(data, png_ptr->next_seq_num);
1709+ png_save_uint_32(data + 4, width);
1710+ png_save_uint_32(data + 8, height);
1711+ png_save_uint_32(data + 12, x_offset);
1712+ png_save_uint_32(data + 16, y_offset);
1713+ png_save_uint_16(data + 20, delay_num);
1714+ png_save_uint_16(data + 22, delay_den);
1715+ data[24] = dispose_op;
1716+ data[25] = blend_op;
1717+
1718+ png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)26);
1719+
1720+ png_ptr->next_seq_num++;
1721+}
1722+#endif /* PNG_WRITE_APNG_SUPPORTED */
1723+
6df9a45f 1724 /* Initializes the row writing capability of libpng */
259182b6
ER
1725 void /* PRIVATE */
1726 png_write_start_row(png_structp png_ptr)
580fd6fc 1727@@ -2825,4 +2918,39 @@
259182b6
ER
1728 }
1729 #endif
1730 }
1731+
580fd6fc 1732+#ifdef PNG_WRITE_APNG_SUPPORTED
259182b6
ER
1733+void /* PRIVATE */
1734+png_write_reset(png_structp png_ptr)
1735+{
1736+ png_ptr->row_number = 0;
1737+ png_ptr->pass = 0;
1738+ png_ptr->mode &= ~PNG_HAVE_IDAT;
1739+}
1740+
1741+void /* PRIVATE */
1742+png_write_reinit(png_structp png_ptr, png_infop info_ptr,
1743+ png_uint_32 width, png_uint_32 height)
1744+{
1745+ if (png_ptr->num_frames_written == 0 &&
1746+ (width != png_ptr->first_frame_width ||
1747+ height != png_ptr->first_frame_height))
1748+ png_error(png_ptr, "width and/or height in the first frame's fcTL "
6df9a45f 1749+ "don't match the ones in IHDR");
259182b6
ER
1750+ if (width > png_ptr->first_frame_width ||
1751+ height > png_ptr->first_frame_height)
1752+ png_error(png_ptr, "width and/or height for a frame greater than"
1753+ "the ones in IHDR");
1754+
1755+ png_set_IHDR(png_ptr, info_ptr, width, height,
1756+ info_ptr->bit_depth, info_ptr->color_type,
1757+ info_ptr->interlace_type, info_ptr->compression_type,
1758+ info_ptr->filter_type);
1759+
1760+ png_ptr->width = width;
1761+ png_ptr->height = height;
1762+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
1763+ png_ptr->usr_width = png_ptr->width;
1764+}
1765+#endif
1766 #endif /* PNG_WRITE_SUPPORTED */
This page took 0.389574 seconds and 4 git commands to generate.