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