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