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