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