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