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