added a bunch of libraries
[vrlugburz] / libs / imago / libpng / pngpread.c
1
2 /* pngpread.c - read a png file in push mode
3  *
4  * Last changed in libpng 1.2.32 [September 18, 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 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
14
15 /* push model modes */
16 #define PNG_READ_SIG_MODE   0
17 #define PNG_READ_CHUNK_MODE 1
18 #define PNG_READ_IDAT_MODE  2
19 #define PNG_SKIP_MODE       3
20 #define PNG_READ_tEXt_MODE  4
21 #define PNG_READ_zTXt_MODE  5
22 #define PNG_READ_DONE_MODE  6
23 #define PNG_READ_iTXt_MODE  7
24 #define PNG_ERROR_MODE      8
25
26 void PNGAPI
27 png_process_data(png_structp png_ptr, png_infop info_ptr,
28    png_bytep buffer, png_size_t buffer_size)
29 {
30    if (png_ptr == NULL || info_ptr == NULL) return;
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  */
42 void /* PRIVATE */
43 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
44 {
45    if (png_ptr == NULL) return;
46    switch (png_ptr->process_mode)
47    {
48       case PNG_READ_SIG_MODE:
49       {
50          png_push_read_sig(png_ptr, info_ptr);
51          break;
52       }
53       case PNG_READ_CHUNK_MODE:
54       {
55          png_push_read_chunk(png_ptr, info_ptr);
56          break;
57       }
58       case PNG_READ_IDAT_MODE:
59       {
60          png_push_read_IDAT(png_ptr);
61          break;
62       }
63 #if defined(PNG_READ_tEXt_SUPPORTED)
64       case PNG_READ_tEXt_MODE:
65       {
66          png_push_read_tEXt(png_ptr, info_ptr);
67          break;
68       }
69 #endif
70 #if defined(PNG_READ_zTXt_SUPPORTED)
71       case PNG_READ_zTXt_MODE:
72       {
73          png_push_read_zTXt(png_ptr, info_ptr);
74          break;
75       }
76 #endif
77 #if defined(PNG_READ_iTXt_SUPPORTED)
78       case PNG_READ_iTXt_MODE:
79       {
80          png_push_read_iTXt(png_ptr, info_ptr);
81          break;
82       }
83 #endif
84       case PNG_SKIP_MODE:
85       {
86          png_push_crc_finish(png_ptr);
87          break;
88       }
89       default:
90       {
91          png_ptr->buffer_size = 0;
92          break;
93       }
94    }
95 }
96
97 /* Read any remaining signature bytes from the stream and compare them with
98  * the correct PNG signature.  It is possible that this routine is called
99  * with bytes already read from the signature, either because they have been
100  * checked by the calling application, or because of multiple calls to this
101  * routine.
102  */
103 void /* PRIVATE */
104 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
105 {
106    png_size_t num_checked = png_ptr->sig_bytes,
107              num_to_check = 8 - num_checked;
108
109    if (png_ptr->buffer_size < num_to_check)
110    {
111       num_to_check = png_ptr->buffer_size;
112    }
113
114    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
115       num_to_check);
116    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
117
118    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
119    {
120       if (num_checked < 4 &&
121           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
122          png_error(png_ptr, "Not a PNG file");
123       else
124          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
125    }
126    else
127    {
128       if (png_ptr->sig_bytes >= 8)
129       {
130          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
131       }
132    }
133 }
134
135 void /* PRIVATE */
136 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
137 {
138 #ifdef PNG_USE_LOCAL_ARRAYS
139       PNG_CONST PNG_IHDR;
140       PNG_CONST PNG_IDAT;
141       PNG_CONST PNG_IEND;
142       PNG_CONST PNG_PLTE;
143 #if defined(PNG_READ_bKGD_SUPPORTED)
144       PNG_CONST PNG_bKGD;
145 #endif
146 #if defined(PNG_READ_cHRM_SUPPORTED)
147       PNG_CONST PNG_cHRM;
148 #endif
149 #if defined(PNG_READ_gAMA_SUPPORTED)
150       PNG_CONST PNG_gAMA;
151 #endif
152 #if defined(PNG_READ_hIST_SUPPORTED)
153       PNG_CONST PNG_hIST;
154 #endif
155 #if defined(PNG_READ_iCCP_SUPPORTED)
156       PNG_CONST PNG_iCCP;
157 #endif
158 #if defined(PNG_READ_iTXt_SUPPORTED)
159       PNG_CONST PNG_iTXt;
160 #endif
161 #if defined(PNG_READ_oFFs_SUPPORTED)
162       PNG_CONST PNG_oFFs;
163 #endif
164 #if defined(PNG_READ_pCAL_SUPPORTED)
165       PNG_CONST PNG_pCAL;
166 #endif
167 #if defined(PNG_READ_pHYs_SUPPORTED)
168       PNG_CONST PNG_pHYs;
169 #endif
170 #if defined(PNG_READ_sBIT_SUPPORTED)
171       PNG_CONST PNG_sBIT;
172 #endif
173 #if defined(PNG_READ_sCAL_SUPPORTED)
174       PNG_CONST PNG_sCAL;
175 #endif
176 #if defined(PNG_READ_sRGB_SUPPORTED)
177       PNG_CONST PNG_sRGB;
178 #endif
179 #if defined(PNG_READ_sPLT_SUPPORTED)
180       PNG_CONST PNG_sPLT;
181 #endif
182 #if defined(PNG_READ_tEXt_SUPPORTED)
183       PNG_CONST PNG_tEXt;
184 #endif
185 #if defined(PNG_READ_tIME_SUPPORTED)
186       PNG_CONST PNG_tIME;
187 #endif
188 #if defined(PNG_READ_tRNS_SUPPORTED)
189       PNG_CONST PNG_tRNS;
190 #endif
191 #if defined(PNG_READ_zTXt_SUPPORTED)
192       PNG_CONST PNG_zTXt;
193 #endif
194 #endif /* PNG_USE_LOCAL_ARRAYS */
195    /* First we make sure we have enough data for the 4 byte chunk name
196     * and the 4 byte chunk length before proceeding with decoding the
197     * chunk data.  To fully decode each of these chunks, we also make
198     * sure we have enough data in the buffer for the 4 byte CRC at the
199     * end of every chunk (except IDAT, which is handled separately).
200     */
201    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
202    {
203       png_byte chunk_length[4];
204
205       if (png_ptr->buffer_size < 8)
206       {
207          png_push_save_buffer(png_ptr);
208          return;
209       }
210
211       png_push_fill_buffer(png_ptr, chunk_length, 4);
212       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
213       png_reset_crc(png_ptr);
214       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
215       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
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 != 13)
226          png_error(png_ptr, "Invalid IHDR length");
227       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
228       {
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          png_ptr->pass++;
1024          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1025              (png_ptr->pass == 3 && png_ptr->width < 3) ||
1026              (png_ptr->pass == 5 && png_ptr->width < 2))
1027            png_ptr->pass++;
1028
1029          if (png_ptr->pass > 7)
1030             png_ptr->pass--;
1031          if (png_ptr->pass >= 7)
1032             break;
1033
1034          png_ptr->iwidth = (png_ptr->width +
1035             png_pass_inc[png_ptr->pass] - 1 -
1036             png_pass_start[png_ptr->pass]) /
1037             png_pass_inc[png_ptr->pass];
1038
1039          png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
1040             png_ptr->iwidth) + 1;
1041
1042          if (png_ptr->transformations & PNG_INTERLACE)
1043             break;
1044
1045          png_ptr->num_rows = (png_ptr->height +
1046             png_pass_yinc[png_ptr->pass] - 1 -
1047             png_pass_ystart[png_ptr->pass]) /
1048             png_pass_yinc[png_ptr->pass];
1049
1050       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
1051    }
1052 }
1053
1054 #if defined(PNG_READ_tEXt_SUPPORTED)
1055 void /* PRIVATE */
1056 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1057    length)
1058 {
1059    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1060       {
1061          png_error(png_ptr, "Out of place tEXt");
1062          info_ptr = info_ptr; /* to quiet some compiler warnings */
1063       }
1064
1065 #ifdef PNG_MAX_MALLOC_64K
1066    png_ptr->skip_length = 0;  /* This may not be necessary */
1067
1068    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1069    {
1070       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1071       png_ptr->skip_length = length - (png_uint_32)65535L;
1072       length = (png_uint_32)65535L;
1073    }
1074 #endif
1075
1076    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1077       (png_uint_32)(length + 1));
1078    png_ptr->current_text[length] = '\0';
1079    png_ptr->current_text_ptr = png_ptr->current_text;
1080    png_ptr->current_text_size = (png_size_t)length;
1081    png_ptr->current_text_left = (png_size_t)length;
1082    png_ptr->process_mode = PNG_READ_tEXt_MODE;
1083 }
1084
1085 void /* PRIVATE */
1086 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
1087 {
1088    if (png_ptr->buffer_size && png_ptr->current_text_left)
1089    {
1090       png_size_t text_size;
1091
1092       if (png_ptr->buffer_size < png_ptr->current_text_left)
1093          text_size = png_ptr->buffer_size;
1094       else
1095          text_size = png_ptr->current_text_left;
1096       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1097       png_ptr->current_text_left -= text_size;
1098       png_ptr->current_text_ptr += text_size;
1099    }
1100    if (!(png_ptr->current_text_left))
1101    {
1102       png_textp text_ptr;
1103       png_charp text;
1104       png_charp key;
1105       int ret;
1106
1107       if (png_ptr->buffer_size < 4)
1108       {
1109          png_push_save_buffer(png_ptr);
1110          return;
1111       }
1112
1113       png_push_crc_finish(png_ptr);
1114
1115 #if defined(PNG_MAX_MALLOC_64K)
1116       if (png_ptr->skip_length)
1117          return;
1118 #endif
1119
1120       key = png_ptr->current_text;
1121
1122       for (text = key; *text; text++)
1123          /* empty loop */ ;
1124
1125       if (text < key + png_ptr->current_text_size)
1126          text++;
1127
1128       text_ptr = (png_textp)png_malloc(png_ptr,
1129          (png_uint_32)png_sizeof(png_text));
1130       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1131       text_ptr->key = key;
1132 #ifdef PNG_iTXt_SUPPORTED
1133       text_ptr->lang = NULL;
1134       text_ptr->lang_key = NULL;
1135 #endif
1136       text_ptr->text = text;
1137
1138       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1139
1140       png_free(png_ptr, key);
1141       png_free(png_ptr, text_ptr);
1142       png_ptr->current_text = NULL;
1143
1144       if (ret)
1145         png_warning(png_ptr, "Insufficient memory to store text chunk.");
1146    }
1147 }
1148 #endif
1149
1150 #if defined(PNG_READ_zTXt_SUPPORTED)
1151 void /* PRIVATE */
1152 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1153    length)
1154 {
1155    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1156       {
1157          png_error(png_ptr, "Out of place zTXt");
1158          info_ptr = info_ptr; /* to quiet some compiler warnings */
1159       }
1160
1161 #ifdef PNG_MAX_MALLOC_64K
1162    /* We can't handle zTXt chunks > 64K, since we don't have enough space
1163     * to be able to store the uncompressed data.  Actually, the threshold
1164     * is probably around 32K, but it isn't as definite as 64K is.
1165     */
1166    if (length > (png_uint_32)65535L)
1167    {
1168       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
1169       png_push_crc_skip(png_ptr, length);
1170       return;
1171    }
1172 #endif
1173
1174    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1175       (png_uint_32)(length + 1));
1176    png_ptr->current_text[length] = '\0';
1177    png_ptr->current_text_ptr = png_ptr->current_text;
1178    png_ptr->current_text_size = (png_size_t)length;
1179    png_ptr->current_text_left = (png_size_t)length;
1180    png_ptr->process_mode = PNG_READ_zTXt_MODE;
1181 }
1182
1183 void /* PRIVATE */
1184 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
1185 {
1186    if (png_ptr->buffer_size && png_ptr->current_text_left)
1187    {
1188       png_size_t text_size;
1189
1190       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
1191          text_size = png_ptr->buffer_size;
1192       else
1193          text_size = png_ptr->current_text_left;
1194       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1195       png_ptr->current_text_left -= text_size;
1196       png_ptr->current_text_ptr += text_size;
1197    }
1198    if (!(png_ptr->current_text_left))
1199    {
1200       png_textp text_ptr;
1201       png_charp text;
1202       png_charp key;
1203       int ret;
1204       png_size_t text_size, key_size;
1205
1206       if (png_ptr->buffer_size < 4)
1207       {
1208          png_push_save_buffer(png_ptr);
1209          return;
1210       }
1211
1212       png_push_crc_finish(png_ptr);
1213
1214       key = png_ptr->current_text;
1215
1216       for (text = key; *text; text++)
1217          /* empty loop */ ;
1218
1219       /* zTXt can't have zero text */
1220       if (text >= key + png_ptr->current_text_size)
1221       {
1222          png_ptr->current_text = NULL;
1223          png_free(png_ptr, key);
1224          return;
1225       }
1226
1227       text++;
1228
1229       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
1230       {
1231          png_ptr->current_text = NULL;
1232          png_free(png_ptr, key);
1233          return;
1234       }
1235
1236       text++;
1237
1238       png_ptr->zstream.next_in = (png_bytep )text;
1239       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
1240          (text - key));
1241       png_ptr->zstream.next_out = png_ptr->zbuf;
1242       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1243
1244       key_size = text - key;
1245       text_size = 0;
1246       text = NULL;
1247       ret = Z_STREAM_END;
1248
1249       while (png_ptr->zstream.avail_in)
1250       {
1251          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
1252          if (ret != Z_OK && ret != Z_STREAM_END)
1253          {
1254             inflateReset(&png_ptr->zstream);
1255             png_ptr->zstream.avail_in = 0;
1256             png_ptr->current_text = NULL;
1257             png_free(png_ptr, key);
1258             png_free(png_ptr, text);
1259             return;
1260          }
1261          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
1262          {
1263             if (text == NULL)
1264             {
1265                text = (png_charp)png_malloc(png_ptr,
1266                      (png_uint_32)(png_ptr->zbuf_size
1267                      - png_ptr->zstream.avail_out + key_size + 1));
1268                png_memcpy(text + key_size, png_ptr->zbuf,
1269                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1270                png_memcpy(text, key, key_size);
1271                text_size = key_size + png_ptr->zbuf_size -
1272                   png_ptr->zstream.avail_out;
1273                *(text + text_size) = '\0';
1274             }
1275             else
1276             {
1277                png_charp tmp;
1278
1279                tmp = text;
1280                text = (png_charp)png_malloc(png_ptr, text_size +
1281                   (png_uint_32)(png_ptr->zbuf_size 
1282                   - png_ptr->zstream.avail_out + 1));
1283                png_memcpy(text, tmp, text_size);
1284                png_free(png_ptr, tmp);
1285                png_memcpy(text + text_size, png_ptr->zbuf,
1286                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1287                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1288                *(text + text_size) = '\0';
1289             }
1290             if (ret != Z_STREAM_END)
1291             {
1292                png_ptr->zstream.next_out = png_ptr->zbuf;
1293                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1294             }
1295          }
1296          else
1297          {
1298             break;
1299          }
1300
1301          if (ret == Z_STREAM_END)
1302             break;
1303       }
1304
1305       inflateReset(&png_ptr->zstream);
1306       png_ptr->zstream.avail_in = 0;
1307
1308       if (ret != Z_STREAM_END)
1309       {
1310          png_ptr->current_text = NULL;
1311          png_free(png_ptr, key);
1312          png_free(png_ptr, text);
1313          return;
1314       }
1315
1316       png_ptr->current_text = NULL;
1317       png_free(png_ptr, key);
1318       key = text;
1319       text += key_size;
1320
1321       text_ptr = (png_textp)png_malloc(png_ptr,
1322           (png_uint_32)png_sizeof(png_text));
1323       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
1324       text_ptr->key = key;
1325 #ifdef PNG_iTXt_SUPPORTED
1326       text_ptr->lang = NULL;
1327       text_ptr->lang_key = NULL;
1328 #endif
1329       text_ptr->text = text;
1330
1331       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1332
1333       png_free(png_ptr, key);
1334       png_free(png_ptr, text_ptr);
1335
1336       if (ret)
1337         png_warning(png_ptr, "Insufficient memory to store text chunk.");
1338    }
1339 }
1340 #endif
1341
1342 #if defined(PNG_READ_iTXt_SUPPORTED)
1343 void /* PRIVATE */
1344 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1345    length)
1346 {
1347    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1348       {
1349          png_error(png_ptr, "Out of place iTXt");
1350          info_ptr = info_ptr; /* to quiet some compiler warnings */
1351       }
1352
1353 #ifdef PNG_MAX_MALLOC_64K
1354    png_ptr->skip_length = 0;  /* This may not be necessary */
1355
1356    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1357    {
1358       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
1359       png_ptr->skip_length = length - (png_uint_32)65535L;
1360       length = (png_uint_32)65535L;
1361    }
1362 #endif
1363
1364    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1365       (png_uint_32)(length + 1));
1366    png_ptr->current_text[length] = '\0';
1367    png_ptr->current_text_ptr = png_ptr->current_text;
1368    png_ptr->current_text_size = (png_size_t)length;
1369    png_ptr->current_text_left = (png_size_t)length;
1370    png_ptr->process_mode = PNG_READ_iTXt_MODE;
1371 }
1372
1373 void /* PRIVATE */
1374 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
1375 {
1376
1377    if (png_ptr->buffer_size && png_ptr->current_text_left)
1378    {
1379       png_size_t text_size;
1380
1381       if (png_ptr->buffer_size < png_ptr->current_text_left)
1382          text_size = png_ptr->buffer_size;
1383       else
1384          text_size = png_ptr->current_text_left;
1385       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1386       png_ptr->current_text_left -= text_size;
1387       png_ptr->current_text_ptr += text_size;
1388    }
1389    if (!(png_ptr->current_text_left))
1390    {
1391       png_textp text_ptr;
1392       png_charp key;
1393       int comp_flag;
1394       png_charp lang;
1395       png_charp lang_key;
1396       png_charp text;
1397       int ret;
1398
1399       if (png_ptr->buffer_size < 4)
1400       {
1401          png_push_save_buffer(png_ptr);
1402          return;
1403       }
1404
1405       png_push_crc_finish(png_ptr);
1406
1407 #if defined(PNG_MAX_MALLOC_64K)
1408       if (png_ptr->skip_length)
1409          return;
1410 #endif
1411
1412       key = png_ptr->current_text;
1413
1414       for (lang = key; *lang; lang++)
1415          /* empty loop */ ;
1416
1417       if (lang < key + png_ptr->current_text_size - 3)
1418          lang++;
1419
1420       comp_flag = *lang++;
1421       lang++;     /* skip comp_type, always zero */
1422
1423       for (lang_key = lang; *lang_key; lang_key++)
1424          /* empty loop */ ;
1425       lang_key++;        /* skip NUL separator */
1426
1427       text=lang_key;
1428       if (lang_key < key + png_ptr->current_text_size - 1)
1429       {
1430         for (; *text; text++)
1431            /* empty loop */ ;
1432       }
1433
1434       if (text < key + png_ptr->current_text_size)
1435          text++;
1436
1437       text_ptr = (png_textp)png_malloc(png_ptr,
1438          (png_uint_32)png_sizeof(png_text));
1439       text_ptr->compression = comp_flag + 2;
1440       text_ptr->key = key;
1441       text_ptr->lang = lang;
1442       text_ptr->lang_key = lang_key;
1443       text_ptr->text = text;
1444       text_ptr->text_length = 0;
1445       text_ptr->itxt_length = png_strlen(text);
1446
1447       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1448
1449       png_ptr->current_text = NULL;
1450
1451       png_free(png_ptr, text_ptr);
1452       if (ret)
1453         png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
1454    }
1455 }
1456 #endif
1457
1458 /* This function is called when we haven't found a handler for this
1459  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
1460  * name or a critical chunk), the chunk is (currently) silently ignored.
1461  */
1462 void /* PRIVATE */
1463 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
1464    length)
1465 {
1466    png_uint_32 skip = 0;
1467
1468    if (!(png_ptr->chunk_name[0] & 0x20))
1469    {
1470 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1471       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1472          PNG_HANDLE_CHUNK_ALWAYS
1473 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1474          && png_ptr->read_user_chunk_fn == NULL
1475 #endif
1476          )
1477 #endif
1478          png_chunk_error(png_ptr, "unknown critical chunk");
1479
1480       info_ptr = info_ptr; /* to quiet some compiler warnings */
1481    }
1482
1483 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1484    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
1485    {
1486 #ifdef PNG_MAX_MALLOC_64K
1487       if (length > (png_uint_32)65535L)
1488       {
1489           png_warning(png_ptr, "unknown chunk too large to fit in memory");
1490           skip = length - (png_uint_32)65535L;
1491           length = (png_uint_32)65535L;
1492       }
1493 #endif
1494       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
1495                  (png_charp)png_ptr->chunk_name, 
1496                  png_sizeof(png_ptr->unknown_chunk.name));
1497       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
1498         = '\0';
1499
1500       png_ptr->unknown_chunk.size = (png_size_t)length;
1501       if (length == 0)
1502          png_ptr->unknown_chunk.data = NULL;
1503       else
1504       {
1505          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
1506        (png_uint_32)length);
1507          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
1508       }
1509 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1510       if (png_ptr->read_user_chunk_fn != NULL)
1511       {
1512          /* callback to user unknown chunk handler */
1513          int ret;
1514          ret = (*(png_ptr->read_user_chunk_fn))
1515            (png_ptr, &png_ptr->unknown_chunk);
1516          if (ret < 0)
1517             png_chunk_error(png_ptr, "error in user chunk");
1518          if (ret == 0)
1519          {
1520             if (!(png_ptr->chunk_name[0] & 0x20))
1521                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1522                     PNG_HANDLE_CHUNK_ALWAYS)
1523                   png_chunk_error(png_ptr, "unknown critical chunk");
1524             png_set_unknown_chunks(png_ptr, info_ptr,
1525                &png_ptr->unknown_chunk, 1);
1526          }
1527       }
1528       else
1529 #endif
1530         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
1531       png_free(png_ptr, png_ptr->unknown_chunk.data);
1532       png_ptr->unknown_chunk.data = NULL;
1533    }
1534    else
1535 #endif
1536       skip=length;
1537    png_push_crc_skip(png_ptr, skip);
1538 }
1539
1540 void /* PRIVATE */
1541 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1542 {
1543    if (png_ptr->info_fn != NULL)
1544       (*(png_ptr->info_fn))(png_ptr, info_ptr);
1545 }
1546
1547 void /* PRIVATE */
1548 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
1549 {
1550    if (png_ptr->end_fn != NULL)
1551       (*(png_ptr->end_fn))(png_ptr, info_ptr);
1552 }
1553
1554 void /* PRIVATE */
1555 png_push_have_row(png_structp png_ptr, png_bytep row)
1556 {
1557    if (png_ptr->row_fn != NULL)
1558       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1559          (int)png_ptr->pass);
1560 }
1561
1562 void PNGAPI
1563 png_progressive_combine_row (png_structp png_ptr,
1564    png_bytep old_row, png_bytep new_row)
1565 {
1566 #ifdef PNG_USE_LOCAL_ARRAYS
1567    PNG_CONST int FARDATA png_pass_dsp_mask[7] =
1568       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
1569 #endif
1570    if (png_ptr == NULL) return;
1571    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
1572       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
1573 }
1574
1575 void PNGAPI
1576 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
1577    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1578    png_progressive_end_ptr end_fn)
1579 {
1580    if (png_ptr == NULL) return;
1581    png_ptr->info_fn = info_fn;
1582    png_ptr->row_fn = row_fn;
1583    png_ptr->end_fn = end_fn;
1584
1585    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
1586 }
1587
1588 png_voidp PNGAPI
1589 png_get_progressive_ptr(png_structp png_ptr)
1590 {
1591    if (png_ptr == NULL) return (NULL);
1592    return png_ptr->io_ptr;
1593 }
1594 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */