Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / modules / libimg / png / pngpread.c
blobfe038aa87fbf61da8a9def09800380893c5f6210
2 /* pngpread.c - read a png file in push mode
4 * Last changed in libpng 1.2.30 [August 13, 2008]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2008 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9 */
11 #define PNG_INTERNAL
12 #include "png.h"
13 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
15 /* push model modes */
16 #define PNG_READ_SIG_MODE 0
17 #define PNG_READ_CHUNK_MODE 1
18 #define PNG_READ_IDAT_MODE 2
19 #define PNG_SKIP_MODE 3
20 #define PNG_READ_tEXt_MODE 4
21 #define PNG_READ_zTXt_MODE 5
22 #define PNG_READ_DONE_MODE 6
23 #define PNG_READ_iTXt_MODE 7
24 #define PNG_ERROR_MODE 8
26 void PNGAPI
27 png_process_data(png_structp png_ptr, png_infop info_ptr,
28 png_bytep buffer, png_size_t buffer_size)
30 if (png_ptr == NULL || info_ptr == NULL) return;
31 png_push_restore_buffer(png_ptr, buffer, buffer_size);
33 while (png_ptr->buffer_size)
35 png_process_some_data(png_ptr, info_ptr);
39 /* What we do with the incoming data depends on what we were previously
40 * doing before we ran out of data...
42 void /* PRIVATE */
43 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
45 if (png_ptr == NULL) return;
46 switch (png_ptr->process_mode)
48 case PNG_READ_SIG_MODE:
50 png_push_read_sig(png_ptr, info_ptr);
51 break;
53 case PNG_READ_CHUNK_MODE:
55 png_push_read_chunk(png_ptr, info_ptr);
56 break;
58 case PNG_READ_IDAT_MODE:
60 png_push_read_IDAT(png_ptr);
61 break;
63 #if defined(PNG_READ_tEXt_SUPPORTED)
64 case PNG_READ_tEXt_MODE:
66 png_push_read_tEXt(png_ptr, info_ptr);
67 break;
69 #endif
70 #if defined(PNG_READ_zTXt_SUPPORTED)
71 case PNG_READ_zTXt_MODE:
73 png_push_read_zTXt(png_ptr, info_ptr);
74 break;
76 #endif
77 #if defined(PNG_READ_iTXt_SUPPORTED)
78 case PNG_READ_iTXt_MODE:
80 png_push_read_iTXt(png_ptr, info_ptr);
81 break;
83 #endif
84 case PNG_SKIP_MODE:
86 png_push_crc_finish(png_ptr);
87 break;
89 default:
91 png_ptr->buffer_size = 0;
92 break;
97 /* Read any remaining signature bytes from the stream and compare them with
98 * the correct PNG signature. It is possible that this routine is called
99 * with bytes already read from the signature, either because they have been
100 * checked by the calling application, or because of multiple calls to this
101 * routine.
103 void /* PRIVATE */
104 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
106 png_size_t num_checked = png_ptr->sig_bytes,
107 num_to_check = 8 - num_checked;
109 if (png_ptr->buffer_size < num_to_check)
111 num_to_check = png_ptr->buffer_size;
114 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
115 num_to_check);
116 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
118 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
120 if (num_checked < 4 &&
121 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
122 png_error(png_ptr, "Not a PNG file");
123 else
124 png_error(png_ptr, "PNG file corrupted by ASCII conversion");
126 else
128 if (png_ptr->sig_bytes >= 8)
130 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
135 void /* PRIVATE */
136 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
138 #ifdef PNG_USE_LOCAL_ARRAYS
139 PNG_CONST PNG_IHDR;
140 PNG_CONST PNG_IDAT;
141 PNG_CONST PNG_IEND;
142 PNG_CONST PNG_PLTE;
143 #if defined(PNG_READ_bKGD_SUPPORTED)
144 PNG_CONST PNG_bKGD;
145 #endif
146 #if defined(PNG_READ_cHRM_SUPPORTED)
147 PNG_CONST PNG_cHRM;
148 #endif
149 #if defined(PNG_READ_gAMA_SUPPORTED)
150 PNG_CONST PNG_gAMA;
151 #endif
152 #if defined(PNG_READ_hIST_SUPPORTED)
153 PNG_CONST PNG_hIST;
154 #endif
155 #if defined(PNG_READ_iCCP_SUPPORTED)
156 PNG_CONST PNG_iCCP;
157 #endif
158 #if defined(PNG_READ_iTXt_SUPPORTED)
159 PNG_CONST PNG_iTXt;
160 #endif
161 #if defined(PNG_READ_oFFs_SUPPORTED)
162 PNG_CONST PNG_oFFs;
163 #endif
164 #if defined(PNG_READ_pCAL_SUPPORTED)
165 PNG_CONST PNG_pCAL;
166 #endif
167 #if defined(PNG_READ_pHYs_SUPPORTED)
168 PNG_CONST PNG_pHYs;
169 #endif
170 #if defined(PNG_READ_sBIT_SUPPORTED)
171 PNG_CONST PNG_sBIT;
172 #endif
173 #if defined(PNG_READ_sCAL_SUPPORTED)
174 PNG_CONST PNG_sCAL;
175 #endif
176 #if defined(PNG_READ_sRGB_SUPPORTED)
177 PNG_CONST PNG_sRGB;
178 #endif
179 #if defined(PNG_READ_sPLT_SUPPORTED)
180 PNG_CONST PNG_sPLT;
181 #endif
182 #if defined(PNG_READ_tEXt_SUPPORTED)
183 PNG_CONST PNG_tEXt;
184 #endif
185 #if defined(PNG_READ_tIME_SUPPORTED)
186 PNG_CONST PNG_tIME;
187 #endif
188 #if defined(PNG_READ_tRNS_SUPPORTED)
189 PNG_CONST PNG_tRNS;
190 #endif
191 #if defined(PNG_READ_zTXt_SUPPORTED)
192 PNG_CONST PNG_zTXt;
193 #endif
194 #if defined(PNG_READ_APNG_SUPPORTED)
195 PNG_CONST PNG_acTL;
196 PNG_CONST PNG_fcTL;
197 PNG_CONST PNG_fdAT;
198 #endif
199 #endif /* PNG_USE_LOCAL_ARRAYS */
200 /* First we make sure we have enough data for the 4 byte chunk name
201 * and the 4 byte chunk length before proceeding with decoding the
202 * chunk data. To fully decode each of these chunks, we also make
203 * sure we have enough data in the buffer for the 4 byte CRC at the
204 * end of every chunk (except IDAT, which is handled separately).
206 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
208 png_byte chunk_length[4];
210 if (png_ptr->buffer_size < 8)
212 png_push_save_buffer(png_ptr);
213 return;
216 png_push_fill_buffer(png_ptr, chunk_length, 4);
217 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
218 png_reset_crc(png_ptr);
219 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
220 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
221 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
224 #if defined(PNG_READ_APNG_SUPPORTED)
225 if (png_ptr->num_frames_read > 0 &&
226 png_ptr->num_frames_read < info_ptr->num_frames)
228 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
230 /* discard trailing IDATs for the first frame */
231 if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
232 png_error(png_ptr, "out of place IDAT");
234 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
236 png_push_save_buffer(png_ptr);
237 return;
239 png_push_crc_skip(png_ptr, png_ptr->push_length);
240 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
241 return;
243 else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
245 if (png_ptr->buffer_size < 4)
247 png_push_save_buffer(png_ptr);
248 return;
250 png_ensure_sequence_number(png_ptr, 4);
252 if (!(png_ptr->mode & PNG_HAVE_fcTL))
254 /* discard trailing fdATs for frames other than the first */
255 if (png_ptr->num_frames_read < 2)
256 png_error(png_ptr, "out of place fdAT");
258 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
260 png_push_save_buffer(png_ptr);
261 return;
263 png_push_crc_skip(png_ptr, png_ptr->push_length);
264 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
265 return;
267 else
269 /* frame data follows */
270 png_ptr->idat_size = png_ptr->push_length - 4;
271 png_ptr->mode |= PNG_HAVE_IDAT;
272 png_ptr->process_mode = PNG_READ_IDAT_MODE;
274 return;
277 else if(!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
279 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
281 png_push_save_buffer(png_ptr);
282 return;
285 png_read_reset(png_ptr);
286 png_ptr->mode &= ~PNG_HAVE_fcTL;
288 png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
290 if (!(png_ptr->mode & PNG_HAVE_fcTL))
291 png_error(png_ptr, "missing required fcTL chunk");
293 png_read_reinit(png_ptr, info_ptr);
294 png_progressive_read_reset(png_ptr);
296 if (png_ptr->frame_info_fn != NULL)
297 (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
299 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
301 return;
303 else
305 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
307 png_push_save_buffer(png_ptr);
308 return;
310 png_warning(png_ptr, "Skipped (ignored) a chunk "
311 "between APNG chunks");
312 png_push_crc_skip(png_ptr, png_ptr->push_length);
313 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
314 return;
317 return;
319 #endif /* PNG_READ_APNG_SUPPORTED */
321 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
322 if (png_ptr->mode & PNG_AFTER_IDAT)
323 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
325 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
327 if (png_ptr->push_length != 13)
328 png_error(png_ptr, "Invalid IHDR length");
329 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
331 if (png_ptr->push_length != 13)
332 png_error(png_ptr, "Invalid IHDR length");
333 png_push_save_buffer(png_ptr);
334 return;
336 png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
338 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
340 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
342 png_push_save_buffer(png_ptr);
343 return;
345 png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
347 png_ptr->process_mode = PNG_READ_DONE_MODE;
348 png_push_have_end(png_ptr, info_ptr);
350 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
351 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
353 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
355 png_push_save_buffer(png_ptr);
356 return;
358 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
359 png_ptr->mode |= PNG_HAVE_IDAT;
360 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
361 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
362 png_ptr->mode |= PNG_HAVE_PLTE;
363 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
365 if (!(png_ptr->mode & PNG_HAVE_IHDR))
366 png_error(png_ptr, "Missing IHDR before IDAT");
367 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
368 !(png_ptr->mode & PNG_HAVE_PLTE))
369 png_error(png_ptr, "Missing PLTE before IDAT");
372 #endif
373 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
375 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
377 png_push_save_buffer(png_ptr);
378 return;
380 png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
382 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
384 /* If we reach an IDAT chunk, this means we have read all of the
385 * header chunks, and we can start reading the image (or if this
386 * is called after the image has been read - we have an error).
388 if (!(png_ptr->mode & PNG_HAVE_IHDR))
389 png_error(png_ptr, "Missing IHDR before IDAT");
390 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
391 !(png_ptr->mode & PNG_HAVE_PLTE))
392 png_error(png_ptr, "Missing PLTE before IDAT");
394 if (png_ptr->mode & PNG_HAVE_IDAT)
396 if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
397 if (png_ptr->push_length == 0)
398 return;
400 if (png_ptr->mode & PNG_AFTER_IDAT)
401 png_error(png_ptr, "Too many IDAT's found");
404 #if defined(PNG_READ_APNG_SUPPORTED)
405 png_have_info(png_ptr, info_ptr);
406 #endif
407 png_ptr->idat_size = png_ptr->push_length;
408 png_ptr->mode |= PNG_HAVE_IDAT;
409 png_ptr->process_mode = PNG_READ_IDAT_MODE;
410 png_push_have_info(png_ptr, info_ptr);
411 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
412 png_ptr->zstream.next_out = png_ptr->row_buf;
413 return;
415 #if defined(PNG_READ_gAMA_SUPPORTED)
416 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
418 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
420 png_push_save_buffer(png_ptr);
421 return;
423 png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
425 #endif
426 #if defined(PNG_READ_sBIT_SUPPORTED)
427 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
429 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
431 png_push_save_buffer(png_ptr);
432 return;
434 png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
436 #endif
437 #if defined(PNG_READ_cHRM_SUPPORTED)
438 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
440 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
442 png_push_save_buffer(png_ptr);
443 return;
445 png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
447 #endif
448 #if defined(PNG_READ_sRGB_SUPPORTED)
449 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
451 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
453 png_push_save_buffer(png_ptr);
454 return;
456 png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
458 #endif
459 #if defined(PNG_READ_iCCP_SUPPORTED)
460 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
462 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
464 png_push_save_buffer(png_ptr);
465 return;
467 png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
469 #endif
470 #if defined(PNG_READ_sPLT_SUPPORTED)
471 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
473 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
475 png_push_save_buffer(png_ptr);
476 return;
478 png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
480 #endif
481 #if defined(PNG_READ_tRNS_SUPPORTED)
482 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
484 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
486 png_push_save_buffer(png_ptr);
487 return;
489 png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
491 #endif
492 #if defined(PNG_READ_bKGD_SUPPORTED)
493 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
495 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
497 png_push_save_buffer(png_ptr);
498 return;
500 png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
502 #endif
503 #if defined(PNG_READ_hIST_SUPPORTED)
504 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
506 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
508 png_push_save_buffer(png_ptr);
509 return;
511 png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
513 #endif
514 #if defined(PNG_READ_pHYs_SUPPORTED)
515 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
517 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
519 png_push_save_buffer(png_ptr);
520 return;
522 png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
524 #endif
525 #if defined(PNG_READ_oFFs_SUPPORTED)
526 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
528 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
530 png_push_save_buffer(png_ptr);
531 return;
533 png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
535 #endif
536 #if defined(PNG_READ_pCAL_SUPPORTED)
537 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
539 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
541 png_push_save_buffer(png_ptr);
542 return;
544 png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
546 #endif
547 #if defined(PNG_READ_sCAL_SUPPORTED)
548 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
550 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
552 png_push_save_buffer(png_ptr);
553 return;
555 png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
557 #endif
558 #if defined(PNG_READ_tIME_SUPPORTED)
559 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
561 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
563 png_push_save_buffer(png_ptr);
564 return;
566 png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
568 #endif
569 #if defined(PNG_READ_tEXt_SUPPORTED)
570 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
572 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
574 png_push_save_buffer(png_ptr);
575 return;
577 png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
579 #endif
580 #if defined(PNG_READ_zTXt_SUPPORTED)
581 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
583 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
585 png_push_save_buffer(png_ptr);
586 return;
588 png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
590 #endif
591 #if defined(PNG_READ_iTXt_SUPPORTED)
592 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
594 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
596 png_push_save_buffer(png_ptr);
597 return;
599 png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
601 #endif
602 #if defined(PNG_READ_APNG_SUPPORTED)
603 else if (!png_memcmp(png_ptr->chunk_name, png_acTL, 4))
605 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
607 png_push_save_buffer(png_ptr);
608 return;
610 png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
612 else if (!png_memcmp(png_ptr->chunk_name, png_fcTL, 4))
614 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
616 png_push_save_buffer(png_ptr);
617 return;
619 png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
621 else if (!png_memcmp(png_ptr->chunk_name, png_fdAT, 4))
623 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
625 png_push_save_buffer(png_ptr);
626 return;
628 png_handle_fdAT(png_ptr, info_ptr, png_ptr->push_length);
630 #endif /* PNG_READ_APNG_SUPPORTED */
631 else
633 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
635 png_push_save_buffer(png_ptr);
636 return;
638 png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
641 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
644 void /* PRIVATE */
645 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
647 png_ptr->process_mode = PNG_SKIP_MODE;
648 png_ptr->skip_length = skip;
651 void /* PRIVATE */
652 png_push_crc_finish(png_structp png_ptr)
654 if (png_ptr->skip_length && png_ptr->save_buffer_size)
656 png_size_t save_size;
658 if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
659 save_size = (png_size_t)png_ptr->skip_length;
660 else
661 save_size = png_ptr->save_buffer_size;
663 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
665 png_ptr->skip_length -= save_size;
666 png_ptr->buffer_size -= save_size;
667 png_ptr->save_buffer_size -= save_size;
668 png_ptr->save_buffer_ptr += save_size;
670 if (png_ptr->skip_length && png_ptr->current_buffer_size)
672 png_size_t save_size;
674 if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
675 save_size = (png_size_t)png_ptr->skip_length;
676 else
677 save_size = png_ptr->current_buffer_size;
679 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
681 png_ptr->skip_length -= save_size;
682 png_ptr->buffer_size -= save_size;
683 png_ptr->current_buffer_size -= save_size;
684 png_ptr->current_buffer_ptr += save_size;
686 if (!png_ptr->skip_length)
688 if (png_ptr->buffer_size < 4)
690 png_push_save_buffer(png_ptr);
691 return;
694 png_crc_finish(png_ptr, 0);
695 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
699 void PNGAPI
700 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
702 png_bytep ptr;
704 if (png_ptr == NULL) return;
705 ptr = buffer;
706 if (png_ptr->save_buffer_size)
708 png_size_t save_size;
710 if (length < png_ptr->save_buffer_size)
711 save_size = length;
712 else
713 save_size = png_ptr->save_buffer_size;
715 png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
716 length -= save_size;
717 ptr += save_size;
718 png_ptr->buffer_size -= save_size;
719 png_ptr->save_buffer_size -= save_size;
720 png_ptr->save_buffer_ptr += save_size;
722 if (length && png_ptr->current_buffer_size)
724 png_size_t save_size;
726 if (length < png_ptr->current_buffer_size)
727 save_size = length;
728 else
729 save_size = png_ptr->current_buffer_size;
731 png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
732 png_ptr->buffer_size -= save_size;
733 png_ptr->current_buffer_size -= save_size;
734 png_ptr->current_buffer_ptr += save_size;
738 void /* PRIVATE */
739 png_push_save_buffer(png_structp png_ptr)
741 if (png_ptr->save_buffer_size)
743 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
745 png_size_t i, istop;
746 png_bytep sp;
747 png_bytep dp;
749 istop = png_ptr->save_buffer_size;
750 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
751 i < istop; i++, sp++, dp++)
753 *dp = *sp;
757 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
758 png_ptr->save_buffer_max)
760 png_size_t new_max;
761 png_bytep old_buffer;
763 if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
764 (png_ptr->current_buffer_size + 256))
766 png_error(png_ptr, "Potential overflow of save_buffer");
768 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
769 old_buffer = png_ptr->save_buffer;
770 png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
771 (png_uint_32)new_max);
772 png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
773 png_free(png_ptr, old_buffer);
774 png_ptr->save_buffer_max = new_max;
776 if (png_ptr->current_buffer_size)
778 png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
779 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
780 png_ptr->save_buffer_size += png_ptr->current_buffer_size;
781 png_ptr->current_buffer_size = 0;
783 png_ptr->save_buffer_ptr = png_ptr->save_buffer;
784 png_ptr->buffer_size = 0;
787 void /* PRIVATE */
788 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
789 png_size_t buffer_length)
791 png_ptr->current_buffer = buffer;
792 png_ptr->current_buffer_size = buffer_length;
793 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
794 png_ptr->current_buffer_ptr = png_ptr->current_buffer;
797 void /* PRIVATE */
798 png_push_read_IDAT(png_structp png_ptr)
800 #ifdef PNG_USE_LOCAL_ARRAYS
801 PNG_IDAT;
802 #if defined(PNG_READ_APNG_SUPPORTED)
803 PNG_fdAT;
804 PNG_IEND;
805 #endif
806 #endif
807 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
809 png_byte chunk_length[4];
811 if (png_ptr->buffer_size < 12)
813 png_push_save_buffer(png_ptr);
814 return;
817 png_push_fill_buffer(png_ptr, chunk_length, 4);
818 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
819 png_reset_crc(png_ptr);
820 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
821 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
823 #if defined(PNG_READ_APNG_SUPPORTED)
824 if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_fdAT, 4)
825 && png_ptr->num_frames_read > 0)
827 if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)
829 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
830 if (png_ptr->frame_end_fn != NULL)
831 (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
832 png_ptr->num_frames_read++;
833 return;
835 else
837 if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
838 png_error(png_ptr, "Not enough image data");
839 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
841 png_push_save_buffer(png_ptr);
842 return;
844 png_warning(png_ptr, "Skipping (ignoring) a chunk between "
845 "APNG chunks");
846 png_crc_finish(png_ptr, png_ptr->push_length);
847 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
848 return;
851 else
852 #endif
853 if ( png_memcmp(png_ptr->chunk_name, png_IDAT, 4)
854 && (png_ptr->num_frames_read == 0) )
856 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
857 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
858 png_error(png_ptr, "Not enough compressed data");
859 #if defined(PNG_READ_APNG_SUPPORTED)
860 if (png_ptr->frame_end_fn != NULL)
861 (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
862 png_ptr->num_frames_read++;
863 #endif
864 return;
867 png_ptr->idat_size = png_ptr->push_length;
869 #if defined(PNG_READ_APNG_SUPPORTED)
870 if (png_ptr->num_frames_read > 0)
872 png_ensure_sequence_number(png_ptr, 4);
873 png_ptr->idat_size -= 4;
875 #endif
877 if (png_ptr->idat_size && png_ptr->save_buffer_size)
879 png_size_t save_size;
881 if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
883 save_size = (png_size_t)png_ptr->idat_size;
884 /* check for overflow */
885 if ((png_uint_32)save_size != png_ptr->idat_size)
886 png_error(png_ptr, "save_size overflowed in pngpread");
888 else
889 save_size = png_ptr->save_buffer_size;
891 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
892 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
893 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
894 png_ptr->idat_size -= save_size;
895 png_ptr->buffer_size -= save_size;
896 png_ptr->save_buffer_size -= save_size;
897 png_ptr->save_buffer_ptr += save_size;
899 if (png_ptr->idat_size && png_ptr->current_buffer_size)
901 png_size_t save_size;
903 if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
905 save_size = (png_size_t)png_ptr->idat_size;
906 /* check for overflow */
907 if ((png_uint_32)save_size != png_ptr->idat_size)
908 png_error(png_ptr, "save_size overflowed in pngpread");
910 else
911 save_size = png_ptr->current_buffer_size;
913 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
914 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
915 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
917 png_ptr->idat_size -= save_size;
918 png_ptr->buffer_size -= save_size;
919 png_ptr->current_buffer_size -= save_size;
920 png_ptr->current_buffer_ptr += save_size;
922 if (!png_ptr->idat_size)
924 if (png_ptr->buffer_size < 4)
926 png_push_save_buffer(png_ptr);
927 return;
930 png_crc_finish(png_ptr, 0);
931 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
932 png_ptr->mode |= PNG_AFTER_IDAT;
936 void /* PRIVATE */
937 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
938 png_size_t buffer_length)
940 int ret;
942 if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
943 png_error(png_ptr, "Extra compression data");
945 png_ptr->zstream.next_in = buffer;
946 png_ptr->zstream.avail_in = (uInt)buffer_length;
947 for (;;)
949 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
950 if (ret != Z_OK)
952 if (ret == Z_STREAM_END)
954 if (png_ptr->zstream.avail_in)
955 png_error(png_ptr, "Extra compressed data");
956 if (!(png_ptr->zstream.avail_out))
958 png_push_process_row(png_ptr);
961 png_ptr->mode |= PNG_AFTER_IDAT;
962 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
963 break;
965 else if (ret == Z_BUF_ERROR)
966 break;
967 else
968 png_error(png_ptr, "Decompression Error");
970 if (!(png_ptr->zstream.avail_out))
972 if ((
973 #if defined(PNG_READ_INTERLACING_SUPPORTED)
974 png_ptr->interlaced && png_ptr->pass > 6) ||
975 (!png_ptr->interlaced &&
976 #endif
977 png_ptr->row_number == png_ptr->num_rows))
979 if (png_ptr->zstream.avail_in)
980 png_warning(png_ptr, "Too much data in IDAT chunks");
981 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
982 break;
984 png_push_process_row(png_ptr);
985 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
986 png_ptr->zstream.next_out = png_ptr->row_buf;
988 else
989 break;
993 void /* PRIVATE */
994 png_push_process_row(png_structp png_ptr)
996 png_ptr->row_info.color_type = png_ptr->color_type;
997 png_ptr->row_info.width = png_ptr->iwidth;
998 png_ptr->row_info.channels = png_ptr->channels;
999 png_ptr->row_info.bit_depth = png_ptr->bit_depth;
1000 png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
1002 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
1003 png_ptr->row_info.width);
1005 png_read_filter_row(png_ptr, &(png_ptr->row_info),
1006 png_ptr->row_buf + 1, png_ptr->prev_row + 1,
1007 (int)(png_ptr->row_buf[0]));
1009 png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
1010 png_ptr->rowbytes + 1);
1012 if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
1013 png_do_read_transformations(png_ptr);
1015 #if defined(PNG_READ_INTERLACING_SUPPORTED)
1016 /* blow up interlaced rows to full size */
1017 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
1019 if (png_ptr->pass < 6)
1020 /* old interface (pre-1.0.9):
1021 png_do_read_interlace(&(png_ptr->row_info),
1022 png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
1024 png_do_read_interlace(png_ptr);
1026 switch (png_ptr->pass)
1028 case 0:
1030 int i;
1031 for (i = 0; i < 8 && png_ptr->pass == 0; i++)
1033 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1034 png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
1036 if (png_ptr->pass == 2) /* pass 1 might be empty */
1038 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1040 png_push_have_row(png_ptr, png_bytep_NULL);
1041 png_read_push_finish_row(png_ptr);
1044 if (png_ptr->pass == 4 && png_ptr->height <= 4)
1046 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1048 png_push_have_row(png_ptr, png_bytep_NULL);
1049 png_read_push_finish_row(png_ptr);
1052 if (png_ptr->pass == 6 && png_ptr->height <= 4)
1054 png_push_have_row(png_ptr, png_bytep_NULL);
1055 png_read_push_finish_row(png_ptr);
1057 break;
1059 case 1:
1061 int i;
1062 for (i = 0; i < 8 && png_ptr->pass == 1; i++)
1064 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1065 png_read_push_finish_row(png_ptr);
1067 if (png_ptr->pass == 2) /* skip top 4 generated rows */
1069 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1071 png_push_have_row(png_ptr, png_bytep_NULL);
1072 png_read_push_finish_row(png_ptr);
1075 break;
1077 case 2:
1079 int i;
1080 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1082 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1083 png_read_push_finish_row(png_ptr);
1085 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1087 png_push_have_row(png_ptr, png_bytep_NULL);
1088 png_read_push_finish_row(png_ptr);
1090 if (png_ptr->pass == 4) /* pass 3 might be empty */
1092 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1094 png_push_have_row(png_ptr, png_bytep_NULL);
1095 png_read_push_finish_row(png_ptr);
1098 break;
1100 case 3:
1102 int i;
1103 for (i = 0; i < 4 && png_ptr->pass == 3; i++)
1105 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1106 png_read_push_finish_row(png_ptr);
1108 if (png_ptr->pass == 4) /* skip top two generated rows */
1110 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1112 png_push_have_row(png_ptr, png_bytep_NULL);
1113 png_read_push_finish_row(png_ptr);
1116 break;
1118 case 4:
1120 int i;
1121 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1123 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1124 png_read_push_finish_row(png_ptr);
1126 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1128 png_push_have_row(png_ptr, png_bytep_NULL);
1129 png_read_push_finish_row(png_ptr);
1131 if (png_ptr->pass == 6) /* pass 5 might be empty */
1133 png_push_have_row(png_ptr, png_bytep_NULL);
1134 png_read_push_finish_row(png_ptr);
1136 break;
1138 case 5:
1140 int i;
1141 for (i = 0; i < 2 && png_ptr->pass == 5; i++)
1143 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1144 png_read_push_finish_row(png_ptr);
1146 if (png_ptr->pass == 6) /* skip top generated row */
1148 png_push_have_row(png_ptr, png_bytep_NULL);
1149 png_read_push_finish_row(png_ptr);
1151 break;
1153 case 6:
1155 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1156 png_read_push_finish_row(png_ptr);
1157 if (png_ptr->pass != 6)
1158 break;
1159 png_push_have_row(png_ptr, png_bytep_NULL);
1160 png_read_push_finish_row(png_ptr);
1164 else
1165 #endif
1167 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1168 png_read_push_finish_row(png_ptr);
1172 void /* PRIVATE */
1173 png_read_push_finish_row(png_structp png_ptr)
1175 #ifdef PNG_USE_LOCAL_ARRAYS
1176 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1178 /* start of interlace block */
1179 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1181 /* offset to next interlace block */
1182 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1184 /* start of interlace block in the y direction */
1185 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1187 /* offset to next interlace block in the y direction */
1188 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1190 /* Height of interlace block. This is not currently used - if you need
1191 * it, uncomment it here and in png.h
1192 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
1194 #endif
1196 png_ptr->row_number++;
1197 if (png_ptr->row_number < png_ptr->num_rows)
1198 return;
1200 if (png_ptr->interlaced)
1202 png_ptr->row_number = 0;
1203 png_memset_check(png_ptr, png_ptr->prev_row, 0,
1204 png_ptr->rowbytes + 1);
1207 png_ptr->pass++;
1208 if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1209 (png_ptr->pass == 3 && png_ptr->width < 3) ||
1210 (png_ptr->pass == 5 && png_ptr->width < 2))
1211 png_ptr->pass++;
1213 if (png_ptr->pass > 7)
1214 png_ptr->pass--;
1215 if (png_ptr->pass >= 7)
1216 break;
1218 png_ptr->iwidth = (png_ptr->width +
1219 png_pass_inc[png_ptr->pass] - 1 -
1220 png_pass_start[png_ptr->pass]) /
1221 png_pass_inc[png_ptr->pass];
1223 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
1224 png_ptr->iwidth) + 1;
1226 if (png_ptr->transformations & PNG_INTERLACE)
1227 break;
1229 png_ptr->num_rows = (png_ptr->height +
1230 png_pass_yinc[png_ptr->pass] - 1 -
1231 png_pass_ystart[png_ptr->pass]) /
1232 png_pass_yinc[png_ptr->pass];
1234 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
1238 #if defined(PNG_READ_tEXt_SUPPORTED)
1239 void /* PRIVATE */
1240 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1241 length)
1243 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1245 png_error(png_ptr, "Out of place tEXt");
1246 info_ptr = info_ptr; /* to quiet some compiler warnings */
1249 #ifdef PNG_MAX_MALLOC_64K
1250 png_ptr->skip_length = 0; /* This may not be necessary */
1252 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1254 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1255 png_ptr->skip_length = length - (png_uint_32)65535L;
1256 length = (png_uint_32)65535L;
1258 #endif
1260 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1261 (png_uint_32)(length + 1));
1262 png_ptr->current_text[length] = '\0';
1263 png_ptr->current_text_ptr = png_ptr->current_text;
1264 png_ptr->current_text_size = (png_size_t)length;
1265 png_ptr->current_text_left = (png_size_t)length;
1266 png_ptr->process_mode = PNG_READ_tEXt_MODE;
1269 void /* PRIVATE */
1270 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
1272 if (png_ptr->buffer_size && png_ptr->current_text_left)
1274 png_size_t text_size;
1276 if (png_ptr->buffer_size < png_ptr->current_text_left)
1277 text_size = png_ptr->buffer_size;
1278 else
1279 text_size = png_ptr->current_text_left;
1280 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1281 png_ptr->current_text_left -= text_size;
1282 png_ptr->current_text_ptr += text_size;
1284 if (!(png_ptr->current_text_left))
1286 png_textp text_ptr;
1287 png_charp text;
1288 png_charp key;
1289 int ret;
1291 if (png_ptr->buffer_size < 4)
1293 png_push_save_buffer(png_ptr);
1294 return;
1297 png_push_crc_finish(png_ptr);
1299 #if defined(PNG_MAX_MALLOC_64K)
1300 if (png_ptr->skip_length)
1301 return;
1302 #endif
1304 key = png_ptr->current_text;
1306 for (text = key; *text; text++)
1307 /* empty loop */ ;
1309 if (text < key + png_ptr->current_text_size)
1310 text++;
1312 text_ptr = (png_textp)png_malloc(png_ptr,
1313 (png_uint_32)png_sizeof(png_text));
1314 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1315 text_ptr->key = key;
1316 #ifdef PNG_iTXt_SUPPORTED
1317 text_ptr->lang = NULL;
1318 text_ptr->lang_key = NULL;
1319 #endif
1320 text_ptr->text = text;
1322 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1324 png_free(png_ptr, key);
1325 png_free(png_ptr, text_ptr);
1326 png_ptr->current_text = NULL;
1328 if (ret)
1329 png_warning(png_ptr, "Insufficient memory to store text chunk.");
1332 #endif
1334 #if defined(PNG_READ_zTXt_SUPPORTED)
1335 void /* PRIVATE */
1336 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1337 length)
1339 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1341 png_error(png_ptr, "Out of place zTXt");
1342 info_ptr = info_ptr; /* to quiet some compiler warnings */
1345 #ifdef PNG_MAX_MALLOC_64K
1346 /* We can't handle zTXt chunks > 64K, since we don't have enough space
1347 * to be able to store the uncompressed data. Actually, the threshold
1348 * is probably around 32K, but it isn't as definite as 64K is.
1350 if (length > (png_uint_32)65535L)
1352 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
1353 png_push_crc_skip(png_ptr, length);
1354 return;
1356 #endif
1358 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1359 (png_uint_32)(length + 1));
1360 png_ptr->current_text[length] = '\0';
1361 png_ptr->current_text_ptr = png_ptr->current_text;
1362 png_ptr->current_text_size = (png_size_t)length;
1363 png_ptr->current_text_left = (png_size_t)length;
1364 png_ptr->process_mode = PNG_READ_zTXt_MODE;
1367 void /* PRIVATE */
1368 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
1370 if (png_ptr->buffer_size && png_ptr->current_text_left)
1372 png_size_t text_size;
1374 if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
1375 text_size = png_ptr->buffer_size;
1376 else
1377 text_size = png_ptr->current_text_left;
1378 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1379 png_ptr->current_text_left -= text_size;
1380 png_ptr->current_text_ptr += text_size;
1382 if (!(png_ptr->current_text_left))
1384 png_textp text_ptr;
1385 png_charp text;
1386 png_charp key;
1387 int ret;
1388 png_size_t text_size, key_size;
1390 if (png_ptr->buffer_size < 4)
1392 png_push_save_buffer(png_ptr);
1393 return;
1396 png_push_crc_finish(png_ptr);
1398 key = png_ptr->current_text;
1400 for (text = key; *text; text++)
1401 /* empty loop */ ;
1403 /* zTXt can't have zero text */
1404 if (text >= key + png_ptr->current_text_size)
1406 png_ptr->current_text = NULL;
1407 png_free(png_ptr, key);
1408 return;
1411 text++;
1413 if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
1415 png_ptr->current_text = NULL;
1416 png_free(png_ptr, key);
1417 return;
1420 text++;
1422 png_ptr->zstream.next_in = (png_bytep )text;
1423 png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
1424 (text - key));
1425 png_ptr->zstream.next_out = png_ptr->zbuf;
1426 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1428 key_size = text - key;
1429 text_size = 0;
1430 text = NULL;
1431 ret = Z_STREAM_END;
1433 while (png_ptr->zstream.avail_in)
1435 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
1436 if (ret != Z_OK && ret != Z_STREAM_END)
1438 inflateReset(&png_ptr->zstream);
1439 png_ptr->zstream.avail_in = 0;
1440 png_ptr->current_text = NULL;
1441 png_free(png_ptr, key);
1442 png_free(png_ptr, text);
1443 return;
1445 if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
1447 if (text == NULL)
1449 text = (png_charp)png_malloc(png_ptr,
1450 (png_uint_32)(png_ptr->zbuf_size
1451 - png_ptr->zstream.avail_out + key_size + 1));
1452 png_memcpy(text + key_size, png_ptr->zbuf,
1453 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1454 png_memcpy(text, key, key_size);
1455 text_size = key_size + png_ptr->zbuf_size -
1456 png_ptr->zstream.avail_out;
1457 *(text + text_size) = '\0';
1459 else
1461 png_charp tmp;
1463 tmp = text;
1464 text = (png_charp)png_malloc(png_ptr, text_size +
1465 (png_uint_32)(png_ptr->zbuf_size
1466 - png_ptr->zstream.avail_out));
1467 png_memcpy(text, tmp, text_size);
1468 png_free(png_ptr, tmp);
1469 png_memcpy(text + text_size, png_ptr->zbuf,
1470 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1471 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1472 *(text + text_size) = '\0';
1474 if (ret != Z_STREAM_END)
1476 png_ptr->zstream.next_out = png_ptr->zbuf;
1477 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1480 else
1482 break;
1485 if (ret == Z_STREAM_END)
1486 break;
1489 inflateReset(&png_ptr->zstream);
1490 png_ptr->zstream.avail_in = 0;
1492 if (ret != Z_STREAM_END)
1494 png_ptr->current_text = NULL;
1495 png_free(png_ptr, key);
1496 png_free(png_ptr, text);
1497 return;
1500 png_ptr->current_text = NULL;
1501 png_free(png_ptr, key);
1502 key = text;
1503 text += key_size;
1505 text_ptr = (png_textp)png_malloc(png_ptr,
1506 (png_uint_32)png_sizeof(png_text));
1507 text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
1508 text_ptr->key = key;
1509 #ifdef PNG_iTXt_SUPPORTED
1510 text_ptr->lang = NULL;
1511 text_ptr->lang_key = NULL;
1512 #endif
1513 text_ptr->text = text;
1515 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1517 png_free(png_ptr, key);
1518 png_free(png_ptr, text_ptr);
1520 if (ret)
1521 png_warning(png_ptr, "Insufficient memory to store text chunk.");
1524 #endif
1526 #if defined(PNG_READ_iTXt_SUPPORTED)
1527 void /* PRIVATE */
1528 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1529 length)
1531 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1533 png_error(png_ptr, "Out of place iTXt");
1534 info_ptr = info_ptr; /* to quiet some compiler warnings */
1537 #ifdef PNG_MAX_MALLOC_64K
1538 png_ptr->skip_length = 0; /* This may not be necessary */
1540 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1542 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
1543 png_ptr->skip_length = length - (png_uint_32)65535L;
1544 length = (png_uint_32)65535L;
1546 #endif
1548 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1549 (png_uint_32)(length + 1));
1550 png_ptr->current_text[length] = '\0';
1551 png_ptr->current_text_ptr = png_ptr->current_text;
1552 png_ptr->current_text_size = (png_size_t)length;
1553 png_ptr->current_text_left = (png_size_t)length;
1554 png_ptr->process_mode = PNG_READ_iTXt_MODE;
1557 void /* PRIVATE */
1558 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
1561 if (png_ptr->buffer_size && png_ptr->current_text_left)
1563 png_size_t text_size;
1565 if (png_ptr->buffer_size < png_ptr->current_text_left)
1566 text_size = png_ptr->buffer_size;
1567 else
1568 text_size = png_ptr->current_text_left;
1569 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1570 png_ptr->current_text_left -= text_size;
1571 png_ptr->current_text_ptr += text_size;
1573 if (!(png_ptr->current_text_left))
1575 png_textp text_ptr;
1576 png_charp key;
1577 int comp_flag;
1578 png_charp lang;
1579 png_charp lang_key;
1580 png_charp text;
1581 int ret;
1583 if (png_ptr->buffer_size < 4)
1585 png_push_save_buffer(png_ptr);
1586 return;
1589 png_push_crc_finish(png_ptr);
1591 #if defined(PNG_MAX_MALLOC_64K)
1592 if (png_ptr->skip_length)
1593 return;
1594 #endif
1596 key = png_ptr->current_text;
1598 for (lang = key; *lang; lang++)
1599 /* empty loop */ ;
1601 if (lang < key + png_ptr->current_text_size - 3)
1602 lang++;
1604 comp_flag = *lang++;
1605 lang++; /* skip comp_type, always zero */
1607 for (lang_key = lang; *lang_key; lang_key++)
1608 /* empty loop */ ;
1609 lang_key++; /* skip NUL separator */
1611 text=lang_key;
1612 if (lang_key < key + png_ptr->current_text_size - 1)
1614 for (; *text; text++)
1615 /* empty loop */ ;
1618 if (text < key + png_ptr->current_text_size)
1619 text++;
1621 text_ptr = (png_textp)png_malloc(png_ptr,
1622 (png_uint_32)png_sizeof(png_text));
1623 text_ptr->compression = comp_flag + 2;
1624 text_ptr->key = key;
1625 text_ptr->lang = lang;
1626 text_ptr->lang_key = lang_key;
1627 text_ptr->text = text;
1628 text_ptr->text_length = 0;
1629 text_ptr->itxt_length = png_strlen(text);
1631 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1633 png_ptr->current_text = NULL;
1635 png_free(png_ptr, text_ptr);
1636 if (ret)
1637 png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
1640 #endif
1642 /* This function is called when we haven't found a handler for this
1643 * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
1644 * name or a critical chunk), the chunk is (currently) silently ignored.
1646 void /* PRIVATE */
1647 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
1648 length)
1650 png_uint_32 skip = 0;
1652 if (!(png_ptr->chunk_name[0] & 0x20))
1654 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1655 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1656 PNG_HANDLE_CHUNK_ALWAYS
1657 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1658 && png_ptr->read_user_chunk_fn == NULL
1659 #endif
1661 #endif
1662 png_chunk_error(png_ptr, "unknown critical chunk");
1664 info_ptr = info_ptr; /* to quiet some compiler warnings */
1667 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1668 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
1670 #ifdef PNG_MAX_MALLOC_64K
1671 if (length > (png_uint_32)65535L)
1673 png_warning(png_ptr, "unknown chunk too large to fit in memory");
1674 skip = length - (png_uint_32)65535L;
1675 length = (png_uint_32)65535L;
1677 #endif
1678 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
1679 (png_charp)png_ptr->chunk_name,
1680 png_sizeof(png_ptr->unknown_chunk.name));
1681 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
1682 = '\0';
1684 png_ptr->unknown_chunk.size = (png_size_t)length;
1685 if (length == 0)
1686 png_ptr->unknown_chunk.data = NULL;
1687 else
1689 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
1690 (png_uint_32)length);
1691 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
1693 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1694 if (png_ptr->read_user_chunk_fn != NULL)
1696 /* callback to user unknown chunk handler */
1697 int ret;
1698 ret = (*(png_ptr->read_user_chunk_fn))
1699 (png_ptr, &png_ptr->unknown_chunk);
1700 if (ret < 0)
1701 png_chunk_error(png_ptr, "error in user chunk");
1702 if (ret == 0)
1704 if (!(png_ptr->chunk_name[0] & 0x20))
1705 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1706 PNG_HANDLE_CHUNK_ALWAYS)
1707 png_chunk_error(png_ptr, "unknown critical chunk");
1708 png_set_unknown_chunks(png_ptr, info_ptr,
1709 &png_ptr->unknown_chunk, 1);
1712 else
1713 #endif
1714 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
1715 png_free(png_ptr, png_ptr->unknown_chunk.data);
1716 png_ptr->unknown_chunk.data = NULL;
1718 else
1719 #endif
1720 skip=length;
1721 png_push_crc_skip(png_ptr, skip);
1724 void /* PRIVATE */
1725 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1727 if (png_ptr->info_fn != NULL)
1728 (*(png_ptr->info_fn))(png_ptr, info_ptr);
1731 void /* PRIVATE */
1732 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
1734 if (png_ptr->end_fn != NULL)
1735 (*(png_ptr->end_fn))(png_ptr, info_ptr);
1738 void /* PRIVATE */
1739 png_push_have_row(png_structp png_ptr, png_bytep row)
1741 if (png_ptr->row_fn != NULL)
1742 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1743 (int)png_ptr->pass);
1746 void PNGAPI
1747 png_progressive_combine_row (png_structp png_ptr,
1748 png_bytep old_row, png_bytep new_row)
1750 #ifdef PNG_USE_LOCAL_ARRAYS
1751 PNG_CONST int FARDATA png_pass_dsp_mask[7] =
1752 {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
1753 #endif
1754 if (png_ptr == NULL) return;
1755 if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
1756 png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
1759 void PNGAPI
1760 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
1761 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1762 png_progressive_end_ptr end_fn)
1764 if (png_ptr == NULL) return;
1765 png_ptr->info_fn = info_fn;
1766 png_ptr->row_fn = row_fn;
1767 png_ptr->end_fn = end_fn;
1769 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
1772 #if defined(PNG_READ_APNG_SUPPORTED)
1773 void PNGAPI
1774 png_set_progressive_frame_fn(png_structp png_ptr,
1775 png_progressive_frame_ptr frame_info_fn,
1776 png_progressive_frame_ptr frame_end_fn)
1778 png_ptr->frame_info_fn = frame_info_fn;
1779 png_ptr->frame_end_fn = frame_end_fn;
1781 #endif
1783 png_voidp PNGAPI
1784 png_get_progressive_ptr(png_structp png_ptr)
1786 if (png_ptr == NULL) return (NULL);
1787 return png_ptr->io_ptr;
1789 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */