1 :
2 : /* pngpread.c - read a png file in push mode
3 : *
4 : * Last changed in libpng 1.5.9 [February 18, 2012]
5 : * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6 : * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 : * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 : *
9 : * This code is released under the libpng license.
10 : * For conditions of distribution and use, see the disclaimer
11 : * and license in png.h
12 : */
13 :
14 : #include "pngpriv.h"
15 :
16 : #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
17 :
18 : /* Push model modes */
19 : #define PNG_READ_SIG_MODE 0
20 : #define PNG_READ_CHUNK_MODE 1
21 : #define PNG_READ_IDAT_MODE 2
22 : #define PNG_SKIP_MODE 3
23 : #define PNG_READ_tEXt_MODE 4
24 : #define PNG_READ_zTXt_MODE 5
25 : #define PNG_READ_DONE_MODE 6
26 : #define PNG_READ_iTXt_MODE 7
27 : #define PNG_ERROR_MODE 8
28 :
29 : void PNGAPI
30 20 : png_process_data(png_structp png_ptr, png_infop info_ptr,
31 : png_bytep buffer, png_size_t buffer_size)
32 : {
33 20 : if (png_ptr == NULL || info_ptr == NULL)
34 0 : return;
35 :
36 20 : png_push_restore_buffer(png_ptr, buffer, buffer_size);
37 :
38 85 : while (png_ptr->buffer_size)
39 : {
40 45 : png_process_some_data(png_ptr, info_ptr);
41 : }
42 : }
43 :
44 : png_size_t PNGAPI
45 0 : png_process_data_pause(png_structp png_ptr, int save)
46 : {
47 0 : if (png_ptr != NULL)
48 : {
49 : /* It's easiest for the caller if we do the save, then the caller doesn't
50 : * have to supply the same data again:
51 : */
52 0 : if (save)
53 0 : png_push_save_buffer(png_ptr);
54 : else
55 : {
56 : /* This includes any pending saved bytes: */
57 0 : png_size_t remaining = png_ptr->buffer_size;
58 0 : png_ptr->buffer_size = 0;
59 :
60 : /* So subtract the saved buffer size, unless all the data
61 : * is actually 'saved', in which case we just return 0
62 : */
63 0 : if (png_ptr->save_buffer_size < remaining)
64 0 : return remaining - png_ptr->save_buffer_size;
65 : }
66 : }
67 :
68 0 : return 0;
69 : }
70 :
71 : png_uint_32 PNGAPI
72 0 : png_process_data_skip(png_structp png_ptr)
73 : {
74 0 : png_uint_32 remaining = 0;
75 :
76 0 : if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
77 0 : png_ptr->skip_length > 0)
78 : {
79 : /* At the end of png_process_data the buffer size must be 0 (see the loop
80 : * above) so we can detect a broken call here:
81 : */
82 0 : if (png_ptr->buffer_size != 0)
83 0 : png_error(png_ptr,
84 : "png_process_data_skip called inside png_process_data");
85 :
86 : /* If is impossible for there to be a saved buffer at this point -
87 : * otherwise we could not be in SKIP mode. This will also happen if
88 : * png_process_skip is called inside png_process_data (but only very
89 : * rarely.)
90 : */
91 0 : if (png_ptr->save_buffer_size != 0)
92 0 : png_error(png_ptr, "png_process_data_skip called with saved data");
93 :
94 0 : remaining = png_ptr->skip_length;
95 0 : png_ptr->skip_length = 0;
96 0 : png_ptr->process_mode = PNG_READ_CHUNK_MODE;
97 : }
98 :
99 0 : return remaining;
100 : }
101 :
102 : /* What we do with the incoming data depends on what we were previously
103 : * doing before we ran out of data...
104 : */
105 : void /* PRIVATE */
106 45 : png_process_some_data(png_structp png_ptr, png_infop info_ptr)
107 : {
108 45 : if (png_ptr == NULL)
109 0 : return;
110 :
111 45 : switch (png_ptr->process_mode)
112 : {
113 : case PNG_READ_SIG_MODE:
114 : {
115 4 : png_push_read_sig(png_ptr, info_ptr);
116 4 : break;
117 : }
118 :
119 : case PNG_READ_CHUNK_MODE:
120 : {
121 14 : png_push_read_chunk(png_ptr, info_ptr);
122 14 : break;
123 : }
124 :
125 : case PNG_READ_IDAT_MODE:
126 : {
127 26 : png_push_read_IDAT(png_ptr);
128 26 : break;
129 : }
130 :
131 : #ifdef PNG_READ_tEXt_SUPPORTED
132 : case PNG_READ_tEXt_MODE:
133 : {
134 : png_push_read_tEXt(png_ptr, info_ptr);
135 : break;
136 : }
137 :
138 : #endif
139 : #ifdef PNG_READ_zTXt_SUPPORTED
140 : case PNG_READ_zTXt_MODE:
141 : {
142 : png_push_read_zTXt(png_ptr, info_ptr);
143 : break;
144 : }
145 :
146 : #endif
147 : #ifdef PNG_READ_iTXt_SUPPORTED
148 : case PNG_READ_iTXt_MODE:
149 : {
150 : png_push_read_iTXt(png_ptr, info_ptr);
151 : break;
152 : }
153 :
154 : #endif
155 : case PNG_SKIP_MODE:
156 : {
157 1 : png_push_crc_finish(png_ptr);
158 1 : break;
159 : }
160 :
161 : default:
162 : {
163 0 : png_ptr->buffer_size = 0;
164 0 : break;
165 : }
166 : }
167 : }
168 :
169 : /* Read any remaining signature bytes from the stream and compare them with
170 : * the correct PNG signature. It is possible that this routine is called
171 : * with bytes already read from the signature, either because they have been
172 : * checked by the calling application, or because of multiple calls to this
173 : * routine.
174 : */
175 : void /* PRIVATE */
176 4 : png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
177 : {
178 4 : png_size_t num_checked = png_ptr->sig_bytes,
179 4 : num_to_check = 8 - num_checked;
180 :
181 4 : if (png_ptr->buffer_size < num_to_check)
182 : {
183 0 : num_to_check = png_ptr->buffer_size;
184 : }
185 :
186 4 : png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
187 : num_to_check);
188 4 : png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
189 :
190 4 : if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
191 : {
192 0 : if (num_checked < 4 &&
193 0 : png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
194 0 : png_error(png_ptr, "Not a PNG file");
195 :
196 : else
197 0 : png_error(png_ptr, "PNG file corrupted by ASCII conversion");
198 : }
199 : else
200 : {
201 4 : if (png_ptr->sig_bytes >= 8)
202 : {
203 4 : png_ptr->process_mode = PNG_READ_CHUNK_MODE;
204 : }
205 : }
206 4 : }
207 :
208 : void /* PRIVATE */
209 14 : png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
210 : {
211 : png_uint_32 chunk_name;
212 :
213 : /* First we make sure we have enough data for the 4 byte chunk name
214 : * and the 4 byte chunk length before proceeding with decoding the
215 : * chunk data. To fully decode each of these chunks, we also make
216 : * sure we have enough data in the buffer for the 4 byte CRC at the
217 : * end of every chunk (except IDAT, which is handled separately).
218 : */
219 14 : if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
220 : {
221 : png_byte chunk_length[4];
222 : png_byte chunk_tag[4];
223 :
224 10 : if (png_ptr->buffer_size < 8)
225 : {
226 0 : png_push_save_buffer(png_ptr);
227 0 : return;
228 : }
229 :
230 10 : png_push_fill_buffer(png_ptr, chunk_length, 4);
231 10 : png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
232 10 : png_reset_crc(png_ptr);
233 10 : png_crc_read(png_ptr, chunk_tag, 4);
234 10 : png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
235 10 : png_check_chunk_name(png_ptr, png_ptr->chunk_name);
236 10 : png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
237 : }
238 :
239 14 : chunk_name = png_ptr->chunk_name;
240 :
241 : #ifdef PNG_READ_APNG_SUPPORTED
242 18 : if (png_ptr->num_frames_read > 0 &&
243 4 : png_ptr->num_frames_read < info_ptr->num_frames)
244 : {
245 0 : if (chunk_name == png_IDAT)
246 : {
247 : /* Discard trailing IDATs for the first frame */
248 0 : if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
249 0 : png_error(png_ptr, "out of place IDAT");
250 :
251 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
252 : {
253 0 : png_push_save_buffer(png_ptr);
254 0 : return;
255 : }
256 :
257 0 : png_push_crc_skip(png_ptr, png_ptr->push_length);
258 0 : png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
259 0 : return;
260 : }
261 0 : else if (chunk_name == png_fdAT)
262 : {
263 0 : if (png_ptr->buffer_size < 4)
264 : {
265 0 : png_push_save_buffer(png_ptr);
266 0 : return;
267 : }
268 :
269 0 : png_ensure_sequence_number(png_ptr, 4);
270 :
271 0 : if (!(png_ptr->mode & PNG_HAVE_fcTL))
272 : {
273 : /* Discard trailing fdATs for frames other than the first */
274 0 : if (png_ptr->num_frames_read < 2)
275 0 : png_error(png_ptr, "out of place fdAT");
276 :
277 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
278 : {
279 0 : png_push_save_buffer(png_ptr);
280 0 : return;
281 : }
282 :
283 0 : png_push_crc_skip(png_ptr, png_ptr->push_length);
284 0 : png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
285 0 : return;
286 : }
287 :
288 : else
289 : {
290 : /* frame data follows */
291 0 : png_ptr->idat_size = png_ptr->push_length - 4;
292 0 : png_ptr->mode |= PNG_HAVE_IDAT;
293 0 : png_ptr->process_mode = PNG_READ_IDAT_MODE;
294 :
295 0 : return;
296 : }
297 : }
298 :
299 0 : else if (chunk_name == png_fcTL)
300 : {
301 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
302 : {
303 0 : png_push_save_buffer(png_ptr);
304 0 : return;
305 : }
306 :
307 0 : png_read_reset(png_ptr);
308 0 : png_ptr->mode &= ~PNG_HAVE_fcTL;
309 :
310 0 : png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
311 :
312 0 : if (!(png_ptr->mode & PNG_HAVE_fcTL))
313 0 : png_error(png_ptr, "missing required fcTL chunk");
314 :
315 0 : png_read_reinit(png_ptr, info_ptr);
316 0 : png_progressive_read_reset(png_ptr);
317 :
318 0 : if (png_ptr->frame_info_fn != NULL)
319 0 : (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
320 :
321 0 : png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
322 :
323 0 : return;
324 : }
325 :
326 : else
327 : {
328 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
329 : {
330 0 : png_push_save_buffer(png_ptr);
331 0 : return;
332 : }
333 : png_warning(png_ptr, "Skipped (ignored) a chunk "
334 : "between APNG chunks");
335 0 : png_push_crc_skip(png_ptr, png_ptr->push_length);
336 0 : png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
337 0 : return;
338 : }
339 :
340 : return;
341 : }
342 : #endif /* PNG_READ_APNG_SUPPORTED */
343 :
344 14 : if (chunk_name == png_IDAT)
345 : {
346 : /* This is here above the if/else case statement below because if the
347 : * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
348 : * completely skipped.
349 : *
350 : * TODO: there must be a better way of doing this.
351 : */
352 4 : if (png_ptr->mode & PNG_AFTER_IDAT)
353 0 : png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
354 : }
355 :
356 14 : if (chunk_name == png_IHDR)
357 : {
358 4 : if (png_ptr->push_length != 13)
359 0 : png_error(png_ptr, "Invalid IHDR length");
360 :
361 4 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
362 : {
363 0 : png_push_save_buffer(png_ptr);
364 0 : return;
365 : }
366 :
367 4 : png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
368 : }
369 :
370 10 : else if (chunk_name == png_IEND)
371 : {
372 4 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
373 : {
374 0 : png_push_save_buffer(png_ptr);
375 0 : return;
376 : }
377 :
378 4 : png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
379 :
380 4 : png_ptr->process_mode = PNG_READ_DONE_MODE;
381 4 : png_push_have_end(png_ptr, info_ptr);
382 : }
383 :
384 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
385 : else if (png_chunk_unknown_handling(png_ptr, chunk_name))
386 : {
387 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
388 : {
389 : png_push_save_buffer(png_ptr);
390 : return;
391 : }
392 :
393 : if (chunk_name == png_IDAT)
394 : png_ptr->mode |= PNG_HAVE_IDAT;
395 :
396 : png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
397 :
398 : if (chunk_name == png_PLTE)
399 : png_ptr->mode |= PNG_HAVE_PLTE;
400 :
401 : else if (chunk_name == png_IDAT)
402 : {
403 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
404 : png_error(png_ptr, "Missing IHDR before IDAT");
405 :
406 : else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
407 : !(png_ptr->mode & PNG_HAVE_PLTE))
408 : png_error(png_ptr, "Missing PLTE before IDAT");
409 : }
410 : }
411 :
412 : #endif
413 6 : else if (chunk_name == png_PLTE)
414 : {
415 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
416 : {
417 0 : png_push_save_buffer(png_ptr);
418 0 : return;
419 : }
420 0 : png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
421 : }
422 :
423 6 : else if (chunk_name == png_IDAT)
424 : {
425 : /* If we reach an IDAT chunk, this means we have read all of the
426 : * header chunks, and we can start reading the image (or if this
427 : * is called after the image has been read - we have an error).
428 : */
429 :
430 4 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
431 0 : png_error(png_ptr, "Missing IHDR before IDAT");
432 :
433 4 : else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
434 0 : !(png_ptr->mode & PNG_HAVE_PLTE))
435 0 : png_error(png_ptr, "Missing PLTE before IDAT");
436 :
437 4 : if (png_ptr->mode & PNG_HAVE_IDAT)
438 : {
439 0 : if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
440 0 : if (png_ptr->push_length == 0)
441 0 : return;
442 :
443 0 : if (png_ptr->mode & PNG_AFTER_IDAT)
444 0 : png_benign_error(png_ptr, "Too many IDATs found");
445 : }
446 :
447 : #ifdef PNG_READ_APNG_SUPPORTED
448 4 : png_have_info(png_ptr, info_ptr);
449 : #endif
450 :
451 4 : png_ptr->idat_size = png_ptr->push_length;
452 4 : png_ptr->mode |= PNG_HAVE_IDAT;
453 4 : png_ptr->process_mode = PNG_READ_IDAT_MODE;
454 4 : png_push_have_info(png_ptr, info_ptr);
455 4 : png_ptr->zstream.avail_out =
456 8 : (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
457 8 : png_ptr->iwidth) + 1;
458 4 : png_ptr->zstream.next_out = png_ptr->row_buf;
459 4 : return;
460 : }
461 :
462 : #ifdef PNG_READ_gAMA_SUPPORTED
463 2 : else if (png_ptr->chunk_name == png_gAMA)
464 : {
465 1 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
466 : {
467 0 : png_push_save_buffer(png_ptr);
468 0 : return;
469 : }
470 :
471 1 : png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
472 : }
473 :
474 : #endif
475 : #ifdef PNG_READ_sBIT_SUPPORTED
476 : else if (png_ptr->chunk_name == png_sBIT)
477 : {
478 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
479 : {
480 : png_push_save_buffer(png_ptr);
481 : return;
482 : }
483 :
484 : png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
485 : }
486 :
487 : #endif
488 : #ifdef PNG_READ_cHRM_SUPPORTED
489 1 : else if (png_ptr->chunk_name == png_cHRM)
490 : {
491 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
492 : {
493 0 : png_push_save_buffer(png_ptr);
494 0 : return;
495 : }
496 :
497 0 : png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
498 : }
499 :
500 : #endif
501 : #ifdef PNG_READ_sRGB_SUPPORTED
502 1 : else if (chunk_name == png_sRGB)
503 : {
504 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
505 : {
506 0 : png_push_save_buffer(png_ptr);
507 0 : return;
508 : }
509 :
510 0 : png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
511 : }
512 :
513 : #endif
514 : #ifdef PNG_READ_iCCP_SUPPORTED
515 1 : else if (png_ptr->chunk_name == png_iCCP)
516 : {
517 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
518 : {
519 0 : png_push_save_buffer(png_ptr);
520 0 : return;
521 : }
522 :
523 0 : png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
524 : }
525 :
526 : #endif
527 : #ifdef PNG_READ_sPLT_SUPPORTED
528 : else if (chunk_name == png_sPLT)
529 : {
530 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
531 : {
532 : png_push_save_buffer(png_ptr);
533 : return;
534 : }
535 :
536 : png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
537 : }
538 :
539 : #endif
540 : #ifdef PNG_READ_tRNS_SUPPORTED
541 1 : else if (chunk_name == png_tRNS)
542 : {
543 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
544 : {
545 0 : png_push_save_buffer(png_ptr);
546 0 : return;
547 : }
548 :
549 0 : png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
550 : }
551 :
552 : #endif
553 : #ifdef PNG_READ_bKGD_SUPPORTED
554 : else if (chunk_name == png_bKGD)
555 : {
556 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
557 : {
558 : png_push_save_buffer(png_ptr);
559 : return;
560 : }
561 :
562 : png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
563 : }
564 :
565 : #endif
566 : #ifdef PNG_READ_hIST_SUPPORTED
567 : else if (chunk_name == png_hIST)
568 : {
569 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
570 : {
571 : png_push_save_buffer(png_ptr);
572 : return;
573 : }
574 :
575 : png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
576 : }
577 :
578 : #endif
579 : #ifdef PNG_READ_pHYs_SUPPORTED
580 : else if (chunk_name == png_pHYs)
581 : {
582 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
583 : {
584 : png_push_save_buffer(png_ptr);
585 : return;
586 : }
587 :
588 : png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
589 : }
590 :
591 : #endif
592 : #ifdef PNG_READ_oFFs_SUPPORTED
593 : else if (chunk_name == png_oFFs)
594 : {
595 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
596 : {
597 : png_push_save_buffer(png_ptr);
598 : return;
599 : }
600 :
601 : png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
602 : }
603 : #endif
604 :
605 : #ifdef PNG_READ_pCAL_SUPPORTED
606 : else if (chunk_name == png_pCAL)
607 : {
608 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
609 : {
610 : png_push_save_buffer(png_ptr);
611 : return;
612 : }
613 :
614 : png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
615 : }
616 :
617 : #endif
618 : #ifdef PNG_READ_sCAL_SUPPORTED
619 : else if (chunk_name == png_sCAL)
620 : {
621 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
622 : {
623 : png_push_save_buffer(png_ptr);
624 : return;
625 : }
626 :
627 : png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
628 : }
629 :
630 : #endif
631 : #ifdef PNG_READ_tIME_SUPPORTED
632 : else if (chunk_name == png_tIME)
633 : {
634 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
635 : {
636 : png_push_save_buffer(png_ptr);
637 : return;
638 : }
639 :
640 : png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
641 : }
642 :
643 : #endif
644 : #ifdef PNG_READ_tEXt_SUPPORTED
645 : else if (chunk_name == png_tEXt)
646 : {
647 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
648 : {
649 : png_push_save_buffer(png_ptr);
650 : return;
651 : }
652 :
653 : png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
654 : }
655 :
656 : #endif
657 : #ifdef PNG_READ_zTXt_SUPPORTED
658 : else if (chunk_name == png_zTXt)
659 : {
660 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
661 : {
662 : png_push_save_buffer(png_ptr);
663 : return;
664 : }
665 :
666 : png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
667 : }
668 :
669 : #endif
670 : #ifdef PNG_READ_iTXt_SUPPORTED
671 : else if (chunk_name == png_iTXt)
672 : {
673 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
674 : {
675 : png_push_save_buffer(png_ptr);
676 : return;
677 : }
678 :
679 : png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
680 : }
681 :
682 : #endif
683 :
684 : #ifdef PNG_READ_APNG_SUPPORTED
685 1 : else if (chunk_name == png_acTL)
686 : {
687 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
688 : {
689 0 : png_push_save_buffer(png_ptr);
690 0 : return;
691 : }
692 0 : png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
693 : }
694 :
695 1 : else if (chunk_name == png_fcTL)
696 : {
697 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
698 : {
699 0 : png_push_save_buffer(png_ptr);
700 0 : return;
701 : }
702 0 : png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
703 : }
704 : #endif /* PNG_READ_APNG_SUPPORTED */
705 :
706 : else
707 : {
708 1 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
709 : {
710 0 : png_push_save_buffer(png_ptr);
711 0 : return;
712 : }
713 1 : png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
714 : }
715 :
716 10 : png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
717 : }
718 :
719 : void /* PRIVATE */
720 1 : png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
721 : {
722 1 : png_ptr->process_mode = PNG_SKIP_MODE;
723 1 : png_ptr->skip_length = skip;
724 1 : }
725 :
726 : void /* PRIVATE */
727 1 : png_push_crc_finish(png_structp png_ptr)
728 : {
729 1 : if (png_ptr->skip_length && png_ptr->save_buffer_size)
730 : {
731 0 : png_size_t save_size = png_ptr->save_buffer_size;
732 0 : png_uint_32 skip_length = png_ptr->skip_length;
733 :
734 : /* We want the smaller of 'skip_length' and 'save_buffer_size', but
735 : * they are of different types and we don't know which variable has the
736 : * fewest bits. Carefully select the smaller and cast it to the type of
737 : * the larger - this cannot overflow. Do not cast in the following test
738 : * - it will break on either 16 or 64 bit platforms.
739 : */
740 0 : if (skip_length < save_size)
741 0 : save_size = (png_size_t)skip_length;
742 :
743 : else
744 0 : skip_length = (png_uint_32)save_size;
745 :
746 0 : png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
747 :
748 0 : png_ptr->skip_length -= skip_length;
749 0 : png_ptr->buffer_size -= save_size;
750 0 : png_ptr->save_buffer_size -= save_size;
751 0 : png_ptr->save_buffer_ptr += save_size;
752 : }
753 1 : if (png_ptr->skip_length && png_ptr->current_buffer_size)
754 : {
755 1 : png_size_t save_size = png_ptr->current_buffer_size;
756 1 : png_uint_32 skip_length = png_ptr->skip_length;
757 :
758 : /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
759 : * the same problem exists as above and the same solution.
760 : */
761 1 : if (skip_length < save_size)
762 1 : save_size = (png_size_t)skip_length;
763 :
764 : else
765 0 : skip_length = (png_uint_32)save_size;
766 :
767 1 : png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
768 :
769 1 : png_ptr->skip_length -= skip_length;
770 1 : png_ptr->buffer_size -= save_size;
771 1 : png_ptr->current_buffer_size -= save_size;
772 1 : png_ptr->current_buffer_ptr += save_size;
773 : }
774 1 : if (!png_ptr->skip_length)
775 : {
776 1 : if (png_ptr->buffer_size < 4)
777 : {
778 0 : png_push_save_buffer(png_ptr);
779 0 : return;
780 : }
781 :
782 1 : png_crc_finish(png_ptr, 0);
783 1 : png_ptr->process_mode = PNG_READ_CHUNK_MODE;
784 : }
785 : }
786 :
787 : void PNGCBAPI
788 57 : png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
789 : {
790 : png_bytep ptr;
791 :
792 57 : if (png_ptr == NULL)
793 0 : return;
794 :
795 57 : ptr = buffer;
796 57 : if (png_ptr->save_buffer_size)
797 : {
798 : png_size_t save_size;
799 :
800 0 : if (length < png_ptr->save_buffer_size)
801 0 : save_size = length;
802 :
803 : else
804 0 : save_size = png_ptr->save_buffer_size;
805 :
806 0 : png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
807 0 : length -= save_size;
808 0 : ptr += save_size;
809 0 : png_ptr->buffer_size -= save_size;
810 0 : png_ptr->save_buffer_size -= save_size;
811 0 : png_ptr->save_buffer_ptr += save_size;
812 : }
813 57 : if (length && png_ptr->current_buffer_size)
814 : {
815 : png_size_t save_size;
816 :
817 57 : if (length < png_ptr->current_buffer_size)
818 53 : save_size = length;
819 :
820 : else
821 4 : save_size = png_ptr->current_buffer_size;
822 :
823 57 : png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
824 57 : png_ptr->buffer_size -= save_size;
825 57 : png_ptr->current_buffer_size -= save_size;
826 57 : png_ptr->current_buffer_ptr += save_size;
827 : }
828 : }
829 :
830 : void /* PRIVATE */
831 0 : png_push_save_buffer(png_structp png_ptr)
832 : {
833 0 : if (png_ptr->save_buffer_size)
834 : {
835 0 : if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
836 : {
837 : png_size_t i, istop;
838 : png_bytep sp;
839 : png_bytep dp;
840 :
841 0 : istop = png_ptr->save_buffer_size;
842 0 : for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
843 0 : i < istop; i++, sp++, dp++)
844 : {
845 0 : *dp = *sp;
846 : }
847 : }
848 : }
849 0 : if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
850 0 : png_ptr->save_buffer_max)
851 : {
852 : png_size_t new_max;
853 : png_bytep old_buffer;
854 :
855 0 : if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
856 0 : (png_ptr->current_buffer_size + 256))
857 : {
858 0 : png_error(png_ptr, "Potential overflow of save_buffer");
859 : }
860 :
861 0 : new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
862 0 : old_buffer = png_ptr->save_buffer;
863 0 : png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, new_max);
864 :
865 0 : if (png_ptr->save_buffer == NULL)
866 : {
867 0 : png_free(png_ptr, old_buffer);
868 0 : png_error(png_ptr, "Insufficient memory for save_buffer");
869 : }
870 :
871 0 : png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
872 0 : png_free(png_ptr, old_buffer);
873 0 : png_ptr->save_buffer_max = new_max;
874 : }
875 0 : if (png_ptr->current_buffer_size)
876 : {
877 0 : png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
878 0 : png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
879 0 : png_ptr->save_buffer_size += png_ptr->current_buffer_size;
880 0 : png_ptr->current_buffer_size = 0;
881 : }
882 0 : png_ptr->save_buffer_ptr = png_ptr->save_buffer;
883 0 : png_ptr->buffer_size = 0;
884 0 : }
885 :
886 : void /* PRIVATE */
887 20 : png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
888 : png_size_t buffer_length)
889 : {
890 20 : png_ptr->current_buffer = buffer;
891 20 : png_ptr->current_buffer_size = buffer_length;
892 20 : png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
893 20 : png_ptr->current_buffer_ptr = png_ptr->current_buffer;
894 20 : }
895 :
896 : void /* PRIVATE */
897 26 : png_push_read_IDAT(png_structp png_ptr)
898 : {
899 26 : if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
900 : {
901 : png_byte chunk_length[4];
902 : png_byte chunk_tag[4];
903 :
904 : /* TODO: this code can be commoned up with the same code in push_read */
905 : #ifdef PNG_READ_APNG_SUPPORTED
906 6 : if (png_ptr->buffer_size < 12)
907 : #else
908 : if (png_ptr->buffer_size < 8)
909 : #endif
910 : {
911 0 : png_push_save_buffer(png_ptr);
912 0 : return;
913 : }
914 :
915 6 : png_push_fill_buffer(png_ptr, chunk_length, 4);
916 6 : png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
917 6 : png_reset_crc(png_ptr);
918 6 : png_crc_read(png_ptr, chunk_tag, 4);
919 6 : png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
920 6 : png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
921 :
922 : #ifdef PNG_READ_APNG_SUPPORTED
923 6 : if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
924 : {
925 0 : if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)
926 : {
927 0 : png_ptr->process_mode = PNG_READ_CHUNK_MODE;
928 0 : if (png_ptr->frame_end_fn != NULL)
929 0 : (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
930 0 : png_ptr->num_frames_read++;
931 0 : return;
932 : }
933 : else
934 : {
935 0 : if (png_ptr->chunk_name == png_IEND)
936 0 : png_error(png_ptr, "Not enough image data");
937 0 : if (png_ptr->push_length + 4 > png_ptr->buffer_size)
938 : {
939 0 : png_push_save_buffer(png_ptr);
940 0 : return;
941 : }
942 : png_warning(png_ptr, "Skipping (ignoring) a chunk between "
943 : "APNG chunks");
944 0 : png_crc_finish(png_ptr, png_ptr->push_length);
945 0 : png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
946 0 : return;
947 : }
948 : }
949 : else
950 : #endif
951 : #ifdef PNG_READ_APNG_SUPPORTED
952 6 : if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0)
953 : #else
954 : if (png_ptr->chunk_name != png_IDAT)
955 : #endif
956 : {
957 4 : png_ptr->process_mode = PNG_READ_CHUNK_MODE;
958 :
959 4 : if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
960 0 : png_error(png_ptr, "Not enough compressed data");
961 :
962 : #ifdef PNG_READ_APNG_SUPPORTED
963 4 : if (png_ptr->frame_end_fn != NULL)
964 0 : (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
965 4 : png_ptr->num_frames_read++;
966 : #endif
967 :
968 4 : return;
969 : }
970 :
971 2 : png_ptr->idat_size = png_ptr->push_length;
972 :
973 : #ifdef PNG_READ_APNG_SUPPORTED
974 2 : if (png_ptr->num_frames_read > 0)
975 : {
976 0 : png_ensure_sequence_number(png_ptr, 4);
977 0 : png_ptr->idat_size -= 4;
978 : }
979 : #endif
980 : }
981 :
982 22 : if (png_ptr->idat_size && png_ptr->save_buffer_size)
983 : {
984 0 : png_size_t save_size = png_ptr->save_buffer_size;
985 0 : png_uint_32 idat_size = png_ptr->idat_size;
986 :
987 : /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
988 : * are of different types and we don't know which variable has the fewest
989 : * bits. Carefully select the smaller and cast it to the type of the
990 : * larger - this cannot overflow. Do not cast in the following test - it
991 : * will break on either 16 or 64 bit platforms.
992 : */
993 0 : if (idat_size < save_size)
994 0 : save_size = (png_size_t)idat_size;
995 :
996 : else
997 0 : idat_size = (png_uint_32)save_size;
998 :
999 0 : png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
1000 :
1001 0 : png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
1002 :
1003 0 : png_ptr->idat_size -= idat_size;
1004 0 : png_ptr->buffer_size -= save_size;
1005 0 : png_ptr->save_buffer_size -= save_size;
1006 0 : png_ptr->save_buffer_ptr += save_size;
1007 : }
1008 :
1009 22 : if (png_ptr->idat_size && png_ptr->current_buffer_size)
1010 : {
1011 22 : png_size_t save_size = png_ptr->current_buffer_size;
1012 22 : png_uint_32 idat_size = png_ptr->idat_size;
1013 :
1014 : /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
1015 : * are of different types and we don't know which variable has the fewest
1016 : * bits. Carefully select the smaller and cast it to the type of the
1017 : * larger - this cannot overflow.
1018 : */
1019 22 : if (idat_size < save_size)
1020 6 : save_size = (png_size_t)idat_size;
1021 :
1022 : else
1023 16 : idat_size = (png_uint_32)save_size;
1024 :
1025 22 : png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
1026 :
1027 22 : png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
1028 :
1029 22 : png_ptr->idat_size -= idat_size;
1030 22 : png_ptr->buffer_size -= save_size;
1031 22 : png_ptr->current_buffer_size -= save_size;
1032 22 : png_ptr->current_buffer_ptr += save_size;
1033 : }
1034 22 : if (!png_ptr->idat_size)
1035 : {
1036 6 : if (png_ptr->buffer_size < 4)
1037 : {
1038 0 : png_push_save_buffer(png_ptr);
1039 0 : return;
1040 : }
1041 :
1042 6 : png_crc_finish(png_ptr, 0);
1043 6 : png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
1044 6 : png_ptr->mode |= PNG_AFTER_IDAT;
1045 : }
1046 : }
1047 :
1048 : void /* PRIVATE */
1049 22 : png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
1050 : png_size_t buffer_length)
1051 : {
1052 : /* The caller checks for a non-zero buffer length. */
1053 22 : if (!(buffer_length > 0) || buffer == NULL)
1054 0 : png_error(png_ptr, "No IDAT data (internal error)");
1055 :
1056 : /* This routine must process all the data it has been given
1057 : * before returning, calling the row callback as required to
1058 : * handle the uncompressed results.
1059 : */
1060 22 : png_ptr->zstream.next_in = buffer;
1061 22 : png_ptr->zstream.avail_in = (uInt)buffer_length;
1062 :
1063 : /* Keep going until the decompressed data is all processed
1064 : * or the stream marked as finished.
1065 : */
1066 470 : while (png_ptr->zstream.avail_in > 0 &&
1067 213 : !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
1068 : {
1069 : int ret;
1070 :
1071 : /* We have data for zlib, but we must check that zlib
1072 : * has someplace to put the results. It doesn't matter
1073 : * if we don't expect any results -- it may be the input
1074 : * data is just the LZ end code.
1075 : */
1076 213 : if (!(png_ptr->zstream.avail_out > 0))
1077 : {
1078 191 : png_ptr->zstream.avail_out =
1079 382 : (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
1080 382 : png_ptr->iwidth) + 1;
1081 :
1082 191 : png_ptr->zstream.next_out = png_ptr->row_buf;
1083 : }
1084 :
1085 : /* Using Z_SYNC_FLUSH here means that an unterminated
1086 : * LZ stream (a stream with a missing end code) can still
1087 : * be handled, otherwise (Z_NO_FLUSH) a future zlib
1088 : * implementation might defer output and therefore
1089 : * change the current behavior (see comments in inflate.c
1090 : * for why this doesn't happen at present with zlib 1.2.5).
1091 : */
1092 213 : ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
1093 :
1094 : /* Check for any failure before proceeding. */
1095 213 : if (ret != Z_OK && ret != Z_STREAM_END)
1096 : {
1097 : /* Terminate the decompression. */
1098 0 : png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
1099 :
1100 : /* This may be a truncated stream (missing or
1101 : * damaged end code). Treat that as a warning.
1102 : */
1103 0 : if (png_ptr->row_number >= png_ptr->num_rows ||
1104 0 : png_ptr->pass > 6)
1105 : png_warning(png_ptr, "Truncated compressed data in IDAT");
1106 :
1107 : else
1108 0 : png_error(png_ptr, "Decompression error in IDAT");
1109 :
1110 : /* Skip the check on unprocessed input */
1111 0 : return;
1112 : }
1113 :
1114 : /* Did inflate output any data? */
1115 213 : if (png_ptr->zstream.next_out != png_ptr->row_buf)
1116 : {
1117 : /* Is this unexpected data after the last row?
1118 : * If it is, artificially terminate the LZ output
1119 : * here.
1120 : */
1121 426 : if (png_ptr->row_number >= png_ptr->num_rows ||
1122 213 : png_ptr->pass > 6)
1123 : {
1124 : /* Extra data. */
1125 : png_warning(png_ptr, "Extra compressed data in IDAT");
1126 0 : png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
1127 :
1128 : /* Do no more processing; skip the unprocessed
1129 : * input check below.
1130 : */
1131 0 : return;
1132 : }
1133 :
1134 : /* Do we have a complete row? */
1135 213 : if (png_ptr->zstream.avail_out == 0)
1136 195 : png_push_process_row(png_ptr);
1137 : }
1138 :
1139 : /* And check for the end of the stream. */
1140 213 : if (ret == Z_STREAM_END)
1141 4 : png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
1142 : }
1143 :
1144 : /* All the data should have been processed, if anything
1145 : * is left at this point we have bytes of IDAT data
1146 : * after the zlib end code.
1147 : */
1148 22 : if (png_ptr->zstream.avail_in > 0)
1149 : png_warning(png_ptr, "Extra compression data in IDAT");
1150 : }
1151 :
1152 : void /* PRIVATE */
1153 195 : png_push_process_row(png_structp png_ptr)
1154 : {
1155 : /* 1.5.6: row_info moved out of png_struct to a local here. */
1156 : png_row_info row_info;
1157 :
1158 195 : row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
1159 195 : row_info.color_type = png_ptr->color_type;
1160 195 : row_info.bit_depth = png_ptr->bit_depth;
1161 195 : row_info.channels = png_ptr->channels;
1162 195 : row_info.pixel_depth = png_ptr->pixel_depth;
1163 195 : row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
1164 :
1165 195 : if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
1166 : {
1167 192 : if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
1168 384 : png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
1169 384 : png_ptr->prev_row + 1, png_ptr->row_buf[0]);
1170 : else
1171 0 : png_error(png_ptr, "bad adaptive filter value");
1172 : }
1173 :
1174 : /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
1175 : * 1.5.6, while the buffer really is this big in current versions of libpng
1176 : * it may not be in the future, so this was changed just to copy the
1177 : * interlaced row count:
1178 : */
1179 195 : png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
1180 :
1181 : #ifdef PNG_READ_TRANSFORMS_SUPPORTED
1182 195 : if (png_ptr->transformations)
1183 195 : png_do_read_transformations(png_ptr, &row_info);
1184 : #endif
1185 :
1186 : /* The transformed pixel depth should match the depth now in row_info. */
1187 195 : if (png_ptr->transformed_pixel_depth == 0)
1188 : {
1189 4 : png_ptr->transformed_pixel_depth = row_info.pixel_depth;
1190 4 : if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
1191 0 : png_error(png_ptr, "progressive row overflow");
1192 : }
1193 :
1194 191 : else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
1195 0 : png_error(png_ptr, "internal progressive row size calculation error");
1196 :
1197 :
1198 : #ifdef PNG_READ_INTERLACING_SUPPORTED
1199 : /* Blow up interlaced rows to full size */
1200 195 : if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
1201 : {
1202 0 : if (png_ptr->pass < 6)
1203 0 : png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
1204 : png_ptr->transformations);
1205 :
1206 0 : switch (png_ptr->pass)
1207 : {
1208 : case 0:
1209 : {
1210 : int i;
1211 0 : for (i = 0; i < 8 && png_ptr->pass == 0; i++)
1212 : {
1213 0 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1214 0 : png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
1215 : }
1216 :
1217 0 : if (png_ptr->pass == 2) /* Pass 1 might be empty */
1218 : {
1219 0 : for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1220 : {
1221 0 : png_push_have_row(png_ptr, NULL);
1222 0 : png_read_push_finish_row(png_ptr);
1223 : }
1224 : }
1225 :
1226 0 : if (png_ptr->pass == 4 && png_ptr->height <= 4)
1227 : {
1228 0 : for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1229 : {
1230 0 : png_push_have_row(png_ptr, NULL);
1231 0 : png_read_push_finish_row(png_ptr);
1232 : }
1233 : }
1234 :
1235 0 : if (png_ptr->pass == 6 && png_ptr->height <= 4)
1236 : {
1237 0 : png_push_have_row(png_ptr, NULL);
1238 0 : png_read_push_finish_row(png_ptr);
1239 : }
1240 :
1241 0 : break;
1242 : }
1243 :
1244 : case 1:
1245 : {
1246 : int i;
1247 0 : for (i = 0; i < 8 && png_ptr->pass == 1; i++)
1248 : {
1249 0 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1250 0 : png_read_push_finish_row(png_ptr);
1251 : }
1252 :
1253 0 : if (png_ptr->pass == 2) /* Skip top 4 generated rows */
1254 : {
1255 0 : for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1256 : {
1257 0 : png_push_have_row(png_ptr, NULL);
1258 0 : png_read_push_finish_row(png_ptr);
1259 : }
1260 : }
1261 :
1262 0 : break;
1263 : }
1264 :
1265 : case 2:
1266 : {
1267 : int i;
1268 :
1269 0 : for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1270 : {
1271 0 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1272 0 : png_read_push_finish_row(png_ptr);
1273 : }
1274 :
1275 0 : for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1276 : {
1277 0 : png_push_have_row(png_ptr, NULL);
1278 0 : png_read_push_finish_row(png_ptr);
1279 : }
1280 :
1281 0 : if (png_ptr->pass == 4) /* Pass 3 might be empty */
1282 : {
1283 0 : for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1284 : {
1285 0 : png_push_have_row(png_ptr, NULL);
1286 0 : png_read_push_finish_row(png_ptr);
1287 : }
1288 : }
1289 :
1290 0 : break;
1291 : }
1292 :
1293 : case 3:
1294 : {
1295 : int i;
1296 :
1297 0 : for (i = 0; i < 4 && png_ptr->pass == 3; i++)
1298 : {
1299 0 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1300 0 : png_read_push_finish_row(png_ptr);
1301 : }
1302 :
1303 0 : if (png_ptr->pass == 4) /* Skip top two generated rows */
1304 : {
1305 0 : for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1306 : {
1307 0 : png_push_have_row(png_ptr, NULL);
1308 0 : png_read_push_finish_row(png_ptr);
1309 : }
1310 : }
1311 :
1312 0 : break;
1313 : }
1314 :
1315 : case 4:
1316 : {
1317 : int i;
1318 :
1319 0 : for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1320 : {
1321 0 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1322 0 : png_read_push_finish_row(png_ptr);
1323 : }
1324 :
1325 0 : for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1326 : {
1327 0 : png_push_have_row(png_ptr, NULL);
1328 0 : png_read_push_finish_row(png_ptr);
1329 : }
1330 :
1331 0 : if (png_ptr->pass == 6) /* Pass 5 might be empty */
1332 : {
1333 0 : png_push_have_row(png_ptr, NULL);
1334 0 : png_read_push_finish_row(png_ptr);
1335 : }
1336 :
1337 0 : break;
1338 : }
1339 :
1340 : case 5:
1341 : {
1342 : int i;
1343 :
1344 0 : for (i = 0; i < 2 && png_ptr->pass == 5; i++)
1345 : {
1346 0 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1347 0 : png_read_push_finish_row(png_ptr);
1348 : }
1349 :
1350 0 : if (png_ptr->pass == 6) /* Skip top generated row */
1351 : {
1352 0 : png_push_have_row(png_ptr, NULL);
1353 0 : png_read_push_finish_row(png_ptr);
1354 : }
1355 :
1356 0 : break;
1357 : }
1358 :
1359 : default:
1360 : case 6:
1361 : {
1362 0 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1363 0 : png_read_push_finish_row(png_ptr);
1364 :
1365 0 : if (png_ptr->pass != 6)
1366 0 : break;
1367 :
1368 0 : png_push_have_row(png_ptr, NULL);
1369 0 : png_read_push_finish_row(png_ptr);
1370 : }
1371 : }
1372 0 : }
1373 : else
1374 : #endif
1375 : {
1376 195 : png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1377 195 : png_read_push_finish_row(png_ptr);
1378 : }
1379 195 : }
1380 :
1381 : void /* PRIVATE */
1382 195 : png_read_push_finish_row(png_structp png_ptr)
1383 : {
1384 : #ifdef PNG_READ_INTERLACING_SUPPORTED
1385 : /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1386 :
1387 : /* Start of interlace block */
1388 : static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1389 :
1390 : /* Offset to next interlace block */
1391 : static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1392 :
1393 : /* Start of interlace block in the y direction */
1394 : static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1395 :
1396 : /* Offset to next interlace block in the y direction */
1397 : static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1398 :
1399 : /* Height of interlace block. This is not currently used - if you need
1400 : * it, uncomment it here and in png.h
1401 : static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
1402 : */
1403 : #endif
1404 :
1405 195 : png_ptr->row_number++;
1406 195 : if (png_ptr->row_number < png_ptr->num_rows)
1407 191 : return;
1408 :
1409 : #ifdef PNG_READ_INTERLACING_SUPPORTED
1410 4 : if (png_ptr->interlaced)
1411 : {
1412 0 : png_ptr->row_number = 0;
1413 0 : png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
1414 :
1415 : do
1416 : {
1417 0 : png_ptr->pass++;
1418 0 : if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1419 0 : (png_ptr->pass == 3 && png_ptr->width < 3) ||
1420 0 : (png_ptr->pass == 5 && png_ptr->width < 2))
1421 0 : png_ptr->pass++;
1422 :
1423 0 : if (png_ptr->pass > 7)
1424 0 : png_ptr->pass--;
1425 :
1426 0 : if (png_ptr->pass >= 7)
1427 0 : break;
1428 :
1429 0 : png_ptr->iwidth = (png_ptr->width +
1430 0 : png_pass_inc[png_ptr->pass] - 1 -
1431 0 : png_pass_start[png_ptr->pass]) /
1432 0 : png_pass_inc[png_ptr->pass];
1433 :
1434 0 : if (png_ptr->transformations & PNG_INTERLACE)
1435 0 : break;
1436 :
1437 0 : png_ptr->num_rows = (png_ptr->height +
1438 0 : png_pass_yinc[png_ptr->pass] - 1 -
1439 0 : png_pass_ystart[png_ptr->pass]) /
1440 0 : png_pass_yinc[png_ptr->pass];
1441 :
1442 0 : } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
1443 : }
1444 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
1445 : }
1446 :
1447 : #ifdef PNG_READ_tEXt_SUPPORTED
1448 : void /* PRIVATE */
1449 : png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1450 : length)
1451 : {
1452 : if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1453 : {
1454 : PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
1455 : png_error(png_ptr, "Out of place tEXt");
1456 : /* NOT REACHED */
1457 : }
1458 :
1459 : #ifdef PNG_MAX_MALLOC_64K
1460 : png_ptr->skip_length = 0; /* This may not be necessary */
1461 :
1462 : if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1463 : {
1464 : png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1465 : png_ptr->skip_length = length - (png_uint_32)65535L;
1466 : length = (png_uint_32)65535L;
1467 : }
1468 : #endif
1469 :
1470 : png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
1471 : png_ptr->current_text[length] = '\0';
1472 : png_ptr->current_text_ptr = png_ptr->current_text;
1473 : png_ptr->current_text_size = (png_size_t)length;
1474 : png_ptr->current_text_left = (png_size_t)length;
1475 : png_ptr->process_mode = PNG_READ_tEXt_MODE;
1476 : }
1477 :
1478 : void /* PRIVATE */
1479 : png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
1480 : {
1481 : if (png_ptr->buffer_size && png_ptr->current_text_left)
1482 : {
1483 : png_size_t text_size;
1484 :
1485 : if (png_ptr->buffer_size < png_ptr->current_text_left)
1486 : text_size = png_ptr->buffer_size;
1487 :
1488 : else
1489 : text_size = png_ptr->current_text_left;
1490 :
1491 : png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1492 : png_ptr->current_text_left -= text_size;
1493 : png_ptr->current_text_ptr += text_size;
1494 : }
1495 : if (!(png_ptr->current_text_left))
1496 : {
1497 : png_textp text_ptr;
1498 : png_charp text;
1499 : png_charp key;
1500 : int ret;
1501 :
1502 : if (png_ptr->buffer_size < 4)
1503 : {
1504 : png_push_save_buffer(png_ptr);
1505 : return;
1506 : }
1507 :
1508 : png_push_crc_finish(png_ptr);
1509 :
1510 : #ifdef PNG_MAX_MALLOC_64K
1511 : if (png_ptr->skip_length)
1512 : return;
1513 : #endif
1514 :
1515 : key = png_ptr->current_text;
1516 :
1517 : for (text = key; *text; text++)
1518 : /* Empty loop */ ;
1519 :
1520 : if (text < key + png_ptr->current_text_size)
1521 : text++;
1522 :
1523 : text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
1524 : text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1525 : text_ptr->key = key;
1526 : text_ptr->itxt_length = 0;
1527 : text_ptr->lang = NULL;
1528 : text_ptr->lang_key = NULL;
1529 : text_ptr->text = text;
1530 :
1531 : ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1532 :
1533 : png_free(png_ptr, key);
1534 : png_free(png_ptr, text_ptr);
1535 : png_ptr->current_text = NULL;
1536 :
1537 : if (ret)
1538 : png_warning(png_ptr, "Insufficient memory to store text chunk");
1539 : }
1540 : }
1541 : #endif
1542 :
1543 : #ifdef PNG_READ_zTXt_SUPPORTED
1544 : void /* PRIVATE */
1545 : png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1546 : length)
1547 : {
1548 : if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1549 : {
1550 : PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
1551 : png_error(png_ptr, "Out of place zTXt");
1552 : /* NOT REACHED */
1553 : }
1554 :
1555 : #ifdef PNG_MAX_MALLOC_64K
1556 : /* We can't handle zTXt chunks > 64K, since we don't have enough space
1557 : * to be able to store the uncompressed data. Actually, the threshold
1558 : * is probably around 32K, but it isn't as definite as 64K is.
1559 : */
1560 : if (length > (png_uint_32)65535L)
1561 : {
1562 : png_warning(png_ptr, "zTXt chunk too large to fit in memory");
1563 : png_push_crc_skip(png_ptr, length);
1564 : return;
1565 : }
1566 : #endif
1567 :
1568 : png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
1569 : png_ptr->current_text[length] = '\0';
1570 : png_ptr->current_text_ptr = png_ptr->current_text;
1571 : png_ptr->current_text_size = (png_size_t)length;
1572 : png_ptr->current_text_left = (png_size_t)length;
1573 : png_ptr->process_mode = PNG_READ_zTXt_MODE;
1574 : }
1575 :
1576 : void /* PRIVATE */
1577 : png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
1578 : {
1579 : if (png_ptr->buffer_size && png_ptr->current_text_left)
1580 : {
1581 : png_size_t text_size;
1582 :
1583 : if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
1584 : text_size = png_ptr->buffer_size;
1585 :
1586 : else
1587 : text_size = png_ptr->current_text_left;
1588 :
1589 : png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1590 : png_ptr->current_text_left -= text_size;
1591 : png_ptr->current_text_ptr += text_size;
1592 : }
1593 : if (!(png_ptr->current_text_left))
1594 : {
1595 : png_textp text_ptr;
1596 : png_charp text;
1597 : png_charp key;
1598 : int ret;
1599 : png_size_t text_size, key_size;
1600 :
1601 : if (png_ptr->buffer_size < 4)
1602 : {
1603 : png_push_save_buffer(png_ptr);
1604 : return;
1605 : }
1606 :
1607 : png_push_crc_finish(png_ptr);
1608 :
1609 : key = png_ptr->current_text;
1610 :
1611 : for (text = key; *text; text++)
1612 : /* Empty loop */ ;
1613 :
1614 : /* zTXt can't have zero text */
1615 : if (text >= key + png_ptr->current_text_size)
1616 : {
1617 : png_ptr->current_text = NULL;
1618 : png_free(png_ptr, key);
1619 : return;
1620 : }
1621 :
1622 : text++;
1623 :
1624 : if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
1625 : {
1626 : png_ptr->current_text = NULL;
1627 : png_free(png_ptr, key);
1628 : return;
1629 : }
1630 :
1631 : text++;
1632 :
1633 : png_ptr->zstream.next_in = (png_bytep)text;
1634 : png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
1635 : (text - key));
1636 : png_ptr->zstream.next_out = png_ptr->zbuf;
1637 : png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1638 :
1639 : key_size = text - key;
1640 : text_size = 0;
1641 : text = NULL;
1642 : ret = Z_STREAM_END;
1643 :
1644 : while (png_ptr->zstream.avail_in)
1645 : {
1646 : ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
1647 : if (ret != Z_OK && ret != Z_STREAM_END)
1648 : {
1649 : inflateReset(&png_ptr->zstream);
1650 : png_ptr->zstream.avail_in = 0;
1651 : png_ptr->current_text = NULL;
1652 : png_free(png_ptr, key);
1653 : png_free(png_ptr, text);
1654 : return;
1655 : }
1656 :
1657 : if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
1658 : {
1659 : if (text == NULL)
1660 : {
1661 : text = (png_charp)png_malloc(png_ptr,
1662 : (png_ptr->zbuf_size
1663 : - png_ptr->zstream.avail_out + key_size + 1));
1664 :
1665 : png_memcpy(text + key_size, png_ptr->zbuf,
1666 : png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1667 :
1668 : png_memcpy(text, key, key_size);
1669 :
1670 : text_size = key_size + png_ptr->zbuf_size -
1671 : png_ptr->zstream.avail_out;
1672 :
1673 : *(text + text_size) = '\0';
1674 : }
1675 :
1676 : else
1677 : {
1678 : png_charp tmp;
1679 :
1680 : tmp = text;
1681 : text = (png_charp)png_malloc(png_ptr, text_size +
1682 : (png_ptr->zbuf_size
1683 : - png_ptr->zstream.avail_out + 1));
1684 :
1685 : png_memcpy(text, tmp, text_size);
1686 : png_free(png_ptr, tmp);
1687 :
1688 : png_memcpy(text + text_size, png_ptr->zbuf,
1689 : png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1690 :
1691 : text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1692 : *(text + text_size) = '\0';
1693 : }
1694 :
1695 : if (ret != Z_STREAM_END)
1696 : {
1697 : png_ptr->zstream.next_out = png_ptr->zbuf;
1698 : png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1699 : }
1700 : }
1701 : else
1702 : {
1703 : break;
1704 : }
1705 :
1706 : if (ret == Z_STREAM_END)
1707 : break;
1708 : }
1709 :
1710 : inflateReset(&png_ptr->zstream);
1711 : png_ptr->zstream.avail_in = 0;
1712 :
1713 : if (ret != Z_STREAM_END)
1714 : {
1715 : png_ptr->current_text = NULL;
1716 : png_free(png_ptr, key);
1717 : png_free(png_ptr, text);
1718 : return;
1719 : }
1720 :
1721 : png_ptr->current_text = NULL;
1722 : png_free(png_ptr, key);
1723 : key = text;
1724 : text += key_size;
1725 :
1726 : text_ptr = (png_textp)png_malloc(png_ptr,
1727 : png_sizeof(png_text));
1728 : text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
1729 : text_ptr->key = key;
1730 : text_ptr->itxt_length = 0;
1731 : text_ptr->lang = NULL;
1732 : text_ptr->lang_key = NULL;
1733 : text_ptr->text = text;
1734 :
1735 : ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1736 :
1737 : png_free(png_ptr, key);
1738 : png_free(png_ptr, text_ptr);
1739 :
1740 : if (ret)
1741 : png_warning(png_ptr, "Insufficient memory to store text chunk");
1742 : }
1743 : }
1744 : #endif
1745 :
1746 : #ifdef PNG_READ_iTXt_SUPPORTED
1747 : void /* PRIVATE */
1748 : png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1749 : length)
1750 : {
1751 : if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1752 : {
1753 : PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
1754 : png_error(png_ptr, "Out of place iTXt");
1755 : /* NOT REACHED */
1756 : }
1757 :
1758 : #ifdef PNG_MAX_MALLOC_64K
1759 : png_ptr->skip_length = 0; /* This may not be necessary */
1760 :
1761 : if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1762 : {
1763 : png_warning(png_ptr, "iTXt chunk too large to fit in memory");
1764 : png_ptr->skip_length = length - (png_uint_32)65535L;
1765 : length = (png_uint_32)65535L;
1766 : }
1767 : #endif
1768 :
1769 : png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
1770 : png_ptr->current_text[length] = '\0';
1771 : png_ptr->current_text_ptr = png_ptr->current_text;
1772 : png_ptr->current_text_size = (png_size_t)length;
1773 : png_ptr->current_text_left = (png_size_t)length;
1774 : png_ptr->process_mode = PNG_READ_iTXt_MODE;
1775 : }
1776 :
1777 : void /* PRIVATE */
1778 : png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
1779 : {
1780 :
1781 : if (png_ptr->buffer_size && png_ptr->current_text_left)
1782 : {
1783 : png_size_t text_size;
1784 :
1785 : if (png_ptr->buffer_size < png_ptr->current_text_left)
1786 : text_size = png_ptr->buffer_size;
1787 :
1788 : else
1789 : text_size = png_ptr->current_text_left;
1790 :
1791 : png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1792 : png_ptr->current_text_left -= text_size;
1793 : png_ptr->current_text_ptr += text_size;
1794 : }
1795 :
1796 : if (!(png_ptr->current_text_left))
1797 : {
1798 : png_textp text_ptr;
1799 : png_charp key;
1800 : int comp_flag;
1801 : png_charp lang;
1802 : png_charp lang_key;
1803 : png_charp text;
1804 : int ret;
1805 :
1806 : if (png_ptr->buffer_size < 4)
1807 : {
1808 : png_push_save_buffer(png_ptr);
1809 : return;
1810 : }
1811 :
1812 : png_push_crc_finish(png_ptr);
1813 :
1814 : #ifdef PNG_MAX_MALLOC_64K
1815 : if (png_ptr->skip_length)
1816 : return;
1817 : #endif
1818 :
1819 : key = png_ptr->current_text;
1820 :
1821 : for (lang = key; *lang; lang++)
1822 : /* Empty loop */ ;
1823 :
1824 : if (lang < key + png_ptr->current_text_size - 3)
1825 : lang++;
1826 :
1827 : comp_flag = *lang++;
1828 : lang++; /* Skip comp_type, always zero */
1829 :
1830 : for (lang_key = lang; *lang_key; lang_key++)
1831 : /* Empty loop */ ;
1832 :
1833 : lang_key++; /* Skip NUL separator */
1834 :
1835 : text=lang_key;
1836 :
1837 : if (lang_key < key + png_ptr->current_text_size - 1)
1838 : {
1839 : for (; *text; text++)
1840 : /* Empty loop */ ;
1841 : }
1842 :
1843 : if (text < key + png_ptr->current_text_size)
1844 : text++;
1845 :
1846 : text_ptr = (png_textp)png_malloc(png_ptr,
1847 : png_sizeof(png_text));
1848 :
1849 : text_ptr->compression = comp_flag + 2;
1850 : text_ptr->key = key;
1851 : text_ptr->lang = lang;
1852 : text_ptr->lang_key = lang_key;
1853 : text_ptr->text = text;
1854 : text_ptr->text_length = 0;
1855 : text_ptr->itxt_length = png_strlen(text);
1856 :
1857 : ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1858 :
1859 : png_ptr->current_text = NULL;
1860 :
1861 : png_free(png_ptr, text_ptr);
1862 : if (ret)
1863 : png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
1864 : }
1865 : }
1866 : #endif
1867 :
1868 : /* This function is called when we haven't found a handler for this
1869 : * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
1870 : * name or a critical chunk), the chunk is (currently) silently ignored.
1871 : */
1872 : void /* PRIVATE */
1873 1 : png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
1874 : length)
1875 : {
1876 1 : png_uint_32 skip = 0;
1877 1 : png_uint_32 chunk_name = png_ptr->chunk_name;
1878 :
1879 1 : if (PNG_CHUNK_CRITICAL(chunk_name))
1880 : {
1881 : #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1882 : if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
1883 : PNG_HANDLE_CHUNK_ALWAYS
1884 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1885 : && png_ptr->read_user_chunk_fn == NULL
1886 : #endif
1887 : )
1888 : #endif
1889 0 : png_chunk_error(png_ptr, "unknown critical chunk");
1890 :
1891 : PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
1892 : }
1893 :
1894 : #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1895 : /* TODO: the code below is apparently just using the
1896 : * png_struct::unknown_chunk member as a temporarily variable, it should be
1897 : * possible to eliminate both it and the temporary buffer.
1898 : */
1899 : if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
1900 : {
1901 : #ifdef PNG_MAX_MALLOC_64K
1902 : if (length > 65535)
1903 : {
1904 : png_warning(png_ptr, "unknown chunk too large to fit in memory");
1905 : skip = length - 65535;
1906 : length = 65535;
1907 : }
1908 : #endif
1909 : /* This is just a record for the user; libpng doesn't use the character
1910 : * form of the name.
1911 : */
1912 : PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
1913 :
1914 : png_ptr->unknown_chunk.size = length;
1915 :
1916 : if (length == 0)
1917 : png_ptr->unknown_chunk.data = NULL;
1918 :
1919 : else
1920 : {
1921 : png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
1922 : png_ptr->unknown_chunk.size);
1923 : png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data,
1924 : png_ptr->unknown_chunk.size);
1925 : }
1926 :
1927 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1928 : if (png_ptr->read_user_chunk_fn != NULL)
1929 : {
1930 : /* Callback to user unknown chunk handler */
1931 : int ret;
1932 : ret = (*(png_ptr->read_user_chunk_fn))
1933 : (png_ptr, &png_ptr->unknown_chunk);
1934 :
1935 : if (ret < 0)
1936 : png_chunk_error(png_ptr, "error in user chunk");
1937 :
1938 : if (ret == 0)
1939 : {
1940 : if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
1941 : if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
1942 : PNG_HANDLE_CHUNK_ALWAYS)
1943 : png_chunk_error(png_ptr, "unknown critical chunk");
1944 : png_set_unknown_chunks(png_ptr, info_ptr,
1945 : &png_ptr->unknown_chunk, 1);
1946 : }
1947 : }
1948 :
1949 : else
1950 : #endif
1951 : png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
1952 : png_free(png_ptr, png_ptr->unknown_chunk.data);
1953 : png_ptr->unknown_chunk.data = NULL;
1954 : }
1955 :
1956 : else
1957 : #endif
1958 1 : skip=length;
1959 1 : png_push_crc_skip(png_ptr, skip);
1960 1 : }
1961 :
1962 : void /* PRIVATE */
1963 4 : png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1964 : {
1965 4 : if (png_ptr->info_fn != NULL)
1966 4 : (*(png_ptr->info_fn))(png_ptr, info_ptr);
1967 4 : }
1968 :
1969 : void /* PRIVATE */
1970 4 : png_push_have_end(png_structp png_ptr, png_infop info_ptr)
1971 : {
1972 4 : if (png_ptr->end_fn != NULL)
1973 4 : (*(png_ptr->end_fn))(png_ptr, info_ptr);
1974 4 : }
1975 :
1976 : void /* PRIVATE */
1977 195 : png_push_have_row(png_structp png_ptr, png_bytep row)
1978 : {
1979 195 : if (png_ptr->row_fn != NULL)
1980 390 : (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1981 195 : (int)png_ptr->pass);
1982 195 : }
1983 :
1984 : #ifdef PNG_READ_INTERLACING_SUPPORTED
1985 : void PNGAPI
1986 0 : png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
1987 : png_const_bytep new_row)
1988 : {
1989 0 : if (png_ptr == NULL)
1990 0 : return;
1991 :
1992 : /* new_row is a flag here - if it is NULL then the app callback was called
1993 : * from an empty row (see the calls to png_struct::row_fn below), otherwise
1994 : * it must be png_ptr->row_buf+1
1995 : */
1996 0 : if (new_row != NULL)
1997 0 : png_combine_row(png_ptr, old_row, 1/*display*/);
1998 : }
1999 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
2000 :
2001 : void PNGAPI
2002 4 : png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
2003 : png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
2004 : png_progressive_end_ptr end_fn)
2005 : {
2006 4 : if (png_ptr == NULL)
2007 0 : return;
2008 :
2009 4 : png_ptr->info_fn = info_fn;
2010 4 : png_ptr->row_fn = row_fn;
2011 4 : png_ptr->end_fn = end_fn;
2012 :
2013 4 : png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
2014 : }
2015 :
2016 : #ifdef PNG_READ_APNG_SUPPORTED
2017 : void PNGAPI
2018 0 : png_set_progressive_frame_fn(png_structp png_ptr,
2019 : png_progressive_frame_ptr frame_info_fn,
2020 : png_progressive_frame_ptr frame_end_fn)
2021 : {
2022 0 : png_ptr->frame_info_fn = frame_info_fn;
2023 0 : png_ptr->frame_end_fn = frame_end_fn;
2024 0 : }
2025 : #endif
2026 :
2027 : png_voidp PNGAPI
2028 203 : png_get_progressive_ptr(png_const_structp png_ptr)
2029 : {
2030 203 : if (png_ptr == NULL)
2031 0 : return (NULL);
2032 :
2033 203 : return png_ptr->io_ptr;
2034 : }
2035 : #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
|