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