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