source: rtems-graphics-toolkit/libpng-1.5.12/pngpread.c @ 1cb4ff2

Last change on this file since 1cb4ff2 was 1cb4ff2, checked in by Alexandru-Sever Horin <alex.sever.h@…>, on 08/06/12 at 11:43:44

Added libpng-1.5.12 update.

  • Property mode set to 100644
File size: 35.8 KB
Line 
1
2/* pngpread.c - read a png file in push mode
3 *
4 * Last changed in libpng 1.5.11 [June 14, 2012]
5 * Copyright (c) 1998-2012 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#include "pngpriv.h"
15
16#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
17
18/* Push model modes */
19#define PNG_READ_SIG_MODE   0
20#define PNG_READ_CHUNK_MODE 1
21#define PNG_READ_IDAT_MODE  2
22#define PNG_SKIP_MODE       3
23#define PNG_READ_tEXt_MODE  4
24#define PNG_READ_zTXt_MODE  5
25#define PNG_READ_DONE_MODE  6
26#define PNG_READ_iTXt_MODE  7
27#define PNG_ERROR_MODE      8
28
29void PNGAPI
30png_process_data(png_structp png_ptr, png_infop info_ptr,
31    png_bytep buffer, png_size_t buffer_size)
32{
33   if (png_ptr == NULL || info_ptr == NULL)
34      return;
35
36   png_push_restore_buffer(png_ptr, buffer, buffer_size);
37
38   while (png_ptr->buffer_size)
39   {
40      png_process_some_data(png_ptr, info_ptr);
41   }
42}
43
44png_size_t PNGAPI
45png_process_data_pause(png_structp png_ptr, int save)
46{
47   if (png_ptr != NULL)
48   {
49      /* It's easiest for the caller if we do the save, then the caller doesn't
50       * have to supply the same data again:
51       */
52      if (save)
53         png_push_save_buffer(png_ptr);
54      else
55      {
56         /* This includes any pending saved bytes: */
57         png_size_t remaining = png_ptr->buffer_size;
58         png_ptr->buffer_size = 0;
59
60         /* So subtract the saved buffer size, unless all the data
61          * is actually 'saved', in which case we just return 0
62          */
63         if (png_ptr->save_buffer_size < remaining)
64            return remaining - png_ptr->save_buffer_size;
65      }
66   }
67
68   return 0;
69}
70
71png_uint_32 PNGAPI
72png_process_data_skip(png_structp png_ptr)
73{
74   png_uint_32 remaining = 0;
75
76   if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
77      png_ptr->skip_length > 0)
78   {
79      /* At the end of png_process_data the buffer size must be 0 (see the loop
80       * above) so we can detect a broken call here:
81       */
82      if (png_ptr->buffer_size != 0)
83         png_error(png_ptr,
84            "png_process_data_skip called inside png_process_data");
85
86      /* If is impossible for there to be a saved buffer at this point -
87       * otherwise we could not be in SKIP mode.  This will also happen if
88       * png_process_skip is called inside png_process_data (but only very
89       * rarely.)
90       */
91      if (png_ptr->save_buffer_size != 0)
92         png_error(png_ptr, "png_process_data_skip called with saved data");
93
94      remaining = png_ptr->skip_length;
95      png_ptr->skip_length = 0;
96      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
97   }
98
99   return remaining;
100}
101
102/* What we do with the incoming data depends on what we were previously
103 * doing before we ran out of data...
104 */
105void /* PRIVATE */
106png_process_some_data(png_structp png_ptr, png_infop info_ptr)
107{
108   if (png_ptr == NULL)
109      return;
110
111   switch (png_ptr->process_mode)
112   {
113      case PNG_READ_SIG_MODE:
114      {
115         png_push_read_sig(png_ptr, info_ptr);
116         break;
117      }
118
119      case PNG_READ_CHUNK_MODE:
120      {
121         png_push_read_chunk(png_ptr, info_ptr);
122         break;
123      }
124
125      case PNG_READ_IDAT_MODE:
126      {
127         png_push_read_IDAT(png_ptr);
128         break;
129      }
130
131      case PNG_SKIP_MODE:
132      {
133         png_push_crc_finish(png_ptr);
134         break;
135      }
136
137      default:
138      {
139         png_ptr->buffer_size = 0;
140         break;
141      }
142   }
143}
144
145/* Read any remaining signature bytes from the stream and compare them with
146 * the correct PNG signature.  It is possible that this routine is called
147 * with bytes already read from the signature, either because they have been
148 * checked by the calling application, or because of multiple calls to this
149 * routine.
150 */
151void /* PRIVATE */
152png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
153{
154   png_size_t num_checked = png_ptr->sig_bytes,
155       num_to_check = 8 - num_checked;
156
157   if (png_ptr->buffer_size < num_to_check)
158   {
159      num_to_check = png_ptr->buffer_size;
160   }
161
162   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
163       num_to_check);
164   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
165
166   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
167   {
168      if (num_checked < 4 &&
169          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
170         png_error(png_ptr, "Not a PNG file");
171
172      else
173         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
174   }
175
176   else
177   {
178      if (png_ptr->sig_bytes >= 8)
179      {
180         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
181      }
182   }
183}
184
185void /* PRIVATE */
186png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
187{
188   png_uint_32 chunk_name;
189
190   /* First we make sure we have enough data for the 4 byte chunk name
191    * and the 4 byte chunk length before proceeding with decoding the
192    * chunk data.  To fully decode each of these chunks, we also make
193    * sure we have enough data in the buffer for the 4 byte CRC at the
194    * end of every chunk (except IDAT, which is handled separately).
195    */
196   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
197   {
198      png_byte chunk_length[4];
199      png_byte chunk_tag[4];
200
201      if (png_ptr->buffer_size < 8)
202      {
203         png_push_save_buffer(png_ptr);
204         return;
205      }
206
207      png_push_fill_buffer(png_ptr, chunk_length, 4);
208      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
209      png_reset_crc(png_ptr);
210      png_crc_read(png_ptr, chunk_tag, 4);
211      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
212      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
213      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
214   }
215
216   chunk_name = png_ptr->chunk_name;
217
218   if (chunk_name == png_IDAT)
219   {
220      /* This is here above the if/else case statement below because if the
221       * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
222       * completely skipped.
223       *
224       * TODO: there must be a better way of doing this.
225       */
226      if (png_ptr->mode & PNG_AFTER_IDAT)
227         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
228   }
229
230   if (chunk_name == png_IHDR)
231   {
232      if (png_ptr->push_length != 13)
233         png_error(png_ptr, "Invalid IHDR length");
234
235      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
236      {
237         png_push_save_buffer(png_ptr);
238         return;
239      }
240
241      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
242   }
243
244   else if (chunk_name == png_IEND)
245   {
246      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
247      {
248         png_push_save_buffer(png_ptr);
249         return;
250      }
251
252      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
253
254      png_ptr->process_mode = PNG_READ_DONE_MODE;
255      png_push_have_end(png_ptr, info_ptr);
256   }
257
258#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
259   else if (png_chunk_unknown_handling(png_ptr, chunk_name))
260   {
261      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
262      {
263         png_push_save_buffer(png_ptr);
264         return;
265      }
266
267      if (chunk_name == png_IDAT)
268         png_ptr->mode |= PNG_HAVE_IDAT;
269
270      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
271
272      if (chunk_name == png_PLTE)
273         png_ptr->mode |= PNG_HAVE_PLTE;
274
275      else if (chunk_name == png_IDAT)
276      {
277         if (!(png_ptr->mode & PNG_HAVE_IHDR))
278            png_error(png_ptr, "Missing IHDR before IDAT");
279
280         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
281             !(png_ptr->mode & PNG_HAVE_PLTE))
282            png_error(png_ptr, "Missing PLTE before IDAT");
283      }
284   }
285#endif
286
287   else if (chunk_name == png_PLTE)
288   {
289      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
290      {
291         png_push_save_buffer(png_ptr);
292         return;
293      }
294      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
295   }
296
297   else if (chunk_name == png_IDAT)
298   {
299      /* If we reach an IDAT chunk, this means we have read all of the
300       * header chunks, and we can start reading the image (or if this
301       * is called after the image has been read - we have an error).
302       */
303
304      if (!(png_ptr->mode & PNG_HAVE_IHDR))
305         png_error(png_ptr, "Missing IHDR before IDAT");
306
307      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
308          !(png_ptr->mode & PNG_HAVE_PLTE))
309         png_error(png_ptr, "Missing PLTE before IDAT");
310
311      if (png_ptr->mode & PNG_HAVE_IDAT)
312      {
313         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
314            if (png_ptr->push_length == 0)
315               return;
316
317         if (png_ptr->mode & PNG_AFTER_IDAT)
318            png_benign_error(png_ptr, "Too many IDATs found");
319      }
320
321      png_ptr->idat_size = png_ptr->push_length;
322      png_ptr->mode |= PNG_HAVE_IDAT;
323      png_ptr->process_mode = PNG_READ_IDAT_MODE;
324      png_push_have_info(png_ptr, info_ptr);
325      png_ptr->zstream.avail_out =
326          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
327          png_ptr->iwidth) + 1;
328      png_ptr->zstream.next_out = png_ptr->row_buf;
329      return;
330   }
331
332#ifdef PNG_READ_gAMA_SUPPORTED
333   else if (png_ptr->chunk_name == png_gAMA)
334   {
335      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
336      {
337         png_push_save_buffer(png_ptr);
338         return;
339      }
340
341      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
342   }
343
344#endif
345#ifdef PNG_READ_sBIT_SUPPORTED
346   else if (png_ptr->chunk_name == png_sBIT)
347   {
348      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
349      {
350         png_push_save_buffer(png_ptr);
351         return;
352      }
353
354      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
355   }
356
357#endif
358#ifdef PNG_READ_cHRM_SUPPORTED
359   else if (png_ptr->chunk_name == png_cHRM)
360   {
361      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
362      {
363         png_push_save_buffer(png_ptr);
364         return;
365      }
366
367      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
368   }
369
370#endif
371#ifdef PNG_READ_sRGB_SUPPORTED
372   else if (chunk_name == png_sRGB)
373   {
374      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
375      {
376         png_push_save_buffer(png_ptr);
377         return;
378      }
379
380      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
381   }
382
383#endif
384#ifdef PNG_READ_iCCP_SUPPORTED
385   else if (png_ptr->chunk_name == png_iCCP)
386   {
387      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
388      {
389         png_push_save_buffer(png_ptr);
390         return;
391      }
392
393      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
394   }
395
396#endif
397#ifdef PNG_READ_sPLT_SUPPORTED
398   else if (chunk_name == png_sPLT)
399   {
400      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
401      {
402         png_push_save_buffer(png_ptr);
403         return;
404      }
405
406      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
407   }
408
409#endif
410#ifdef PNG_READ_tRNS_SUPPORTED
411   else if (chunk_name == png_tRNS)
412   {
413      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
414      {
415         png_push_save_buffer(png_ptr);
416         return;
417      }
418
419      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
420   }
421
422#endif
423#ifdef PNG_READ_bKGD_SUPPORTED
424   else if (chunk_name == png_bKGD)
425   {
426      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
427      {
428         png_push_save_buffer(png_ptr);
429         return;
430      }
431
432      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
433   }
434
435#endif
436#ifdef PNG_READ_hIST_SUPPORTED
437   else if (chunk_name == png_hIST)
438   {
439      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
440      {
441         png_push_save_buffer(png_ptr);
442         return;
443      }
444
445      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
446   }
447
448#endif
449#ifdef PNG_READ_pHYs_SUPPORTED
450   else if (chunk_name == png_pHYs)
451   {
452      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
453      {
454         png_push_save_buffer(png_ptr);
455         return;
456      }
457
458      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
459   }
460
461#endif
462#ifdef PNG_READ_oFFs_SUPPORTED
463   else if (chunk_name == png_oFFs)
464   {
465      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
466      {
467         png_push_save_buffer(png_ptr);
468         return;
469      }
470
471      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
472   }
473#endif
474
475#ifdef PNG_READ_pCAL_SUPPORTED
476   else if (chunk_name == png_pCAL)
477   {
478      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
479      {
480         png_push_save_buffer(png_ptr);
481         return;
482      }
483
484      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
485   }
486
487#endif
488#ifdef PNG_READ_sCAL_SUPPORTED
489   else if (chunk_name == png_sCAL)
490   {
491      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
492      {
493         png_push_save_buffer(png_ptr);
494         return;
495      }
496
497      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
498   }
499
500#endif
501#ifdef PNG_READ_tIME_SUPPORTED
502   else if (chunk_name == png_tIME)
503   {
504      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
505      {
506         png_push_save_buffer(png_ptr);
507         return;
508      }
509
510      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
511   }
512
513#endif
514#ifdef PNG_READ_tEXt_SUPPORTED
515   else if (chunk_name == png_tEXt)
516   {
517      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
518      {
519         png_push_save_buffer(png_ptr);
520         return;
521      }
522
523      png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
524   }
525
526#endif
527#ifdef PNG_READ_zTXt_SUPPORTED
528   else if (chunk_name == png_zTXt)
529   {
530      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
531      {
532         png_push_save_buffer(png_ptr);
533         return;
534      }
535
536      png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
537   }
538
539#endif
540#ifdef PNG_READ_iTXt_SUPPORTED
541   else if (chunk_name == png_iTXt)
542   {
543      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
544      {
545         png_push_save_buffer(png_ptr);
546         return;
547      }
548
549      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
550   }
551
552#endif
553
554   else
555   {
556      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
557      {
558         png_push_save_buffer(png_ptr);
559         return;
560      }
561      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
562   }
563
564   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
565}
566
567void /* PRIVATE */
568png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
569{
570   png_ptr->process_mode = PNG_SKIP_MODE;
571   png_ptr->skip_length = skip;
572}
573
574void /* PRIVATE */
575png_push_crc_finish(png_structp png_ptr)
576{
577   if (png_ptr->skip_length && png_ptr->save_buffer_size)
578   {
579      png_size_t save_size = png_ptr->save_buffer_size;
580      png_uint_32 skip_length = png_ptr->skip_length;
581
582      /* We want the smaller of 'skip_length' and 'save_buffer_size', but
583       * they are of different types and we don't know which variable has the
584       * fewest bits.  Carefully select the smaller and cast it to the type of
585       * the larger - this cannot overflow.  Do not cast in the following test
586       * - it will break on either 16 or 64 bit platforms.
587       */
588      if (skip_length < save_size)
589         save_size = (png_size_t)skip_length;
590
591      else
592         skip_length = (png_uint_32)save_size;
593
594      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
595
596      png_ptr->skip_length -= skip_length;
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
602   if (png_ptr->skip_length && png_ptr->current_buffer_size)
603   {
604      png_size_t save_size = png_ptr->current_buffer_size;
605      png_uint_32 skip_length = png_ptr->skip_length;
606
607      /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
608       * the same problem exists as above and the same solution.
609       */
610      if (skip_length < save_size)
611         save_size = (png_size_t)skip_length;
612
613      else
614         skip_length = (png_uint_32)save_size;
615
616      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
617
618      png_ptr->skip_length -= skip_length;
619      png_ptr->buffer_size -= save_size;
620      png_ptr->current_buffer_size -= save_size;
621      png_ptr->current_buffer_ptr += save_size;
622   }
623
624   if (!png_ptr->skip_length)
625   {
626      if (png_ptr->buffer_size < 4)
627      {
628         png_push_save_buffer(png_ptr);
629         return;
630      }
631
632      png_crc_finish(png_ptr, 0);
633      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
634   }
635}
636
637void PNGCBAPI
638png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
639{
640   png_bytep ptr;
641
642   if (png_ptr == NULL)
643      return;
644
645   ptr = buffer;
646
647   if (png_ptr->save_buffer_size)
648   {
649      png_size_t save_size;
650
651      if (length < png_ptr->save_buffer_size)
652         save_size = length;
653
654      else
655         save_size = png_ptr->save_buffer_size;
656
657      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
658      length -= save_size;
659      ptr += save_size;
660      png_ptr->buffer_size -= save_size;
661      png_ptr->save_buffer_size -= save_size;
662      png_ptr->save_buffer_ptr += save_size;
663   }
664
665   if (length && png_ptr->current_buffer_size)
666   {
667      png_size_t save_size;
668
669      if (length < png_ptr->current_buffer_size)
670         save_size = length;
671
672      else
673         save_size = png_ptr->current_buffer_size;
674
675      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
676      png_ptr->buffer_size -= save_size;
677      png_ptr->current_buffer_size -= save_size;
678      png_ptr->current_buffer_ptr += save_size;
679   }
680}
681
682void /* PRIVATE */
683png_push_save_buffer(png_structp png_ptr)
684{
685   if (png_ptr->save_buffer_size)
686   {
687      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
688      {
689         png_size_t i, istop;
690         png_bytep sp;
691         png_bytep dp;
692
693         istop = png_ptr->save_buffer_size;
694
695         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
696             i < istop; i++, sp++, dp++)
697         {
698            *dp = *sp;
699         }
700      }
701   }
702
703   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
704       png_ptr->save_buffer_max)
705   {
706      png_size_t new_max;
707      png_bytep old_buffer;
708
709      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
710          (png_ptr->current_buffer_size + 256))
711      {
712         png_error(png_ptr, "Potential overflow of save_buffer");
713      }
714
715      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
716      old_buffer = png_ptr->save_buffer;
717      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, new_max);
718
719      if (png_ptr->save_buffer == NULL)
720      {
721         png_free(png_ptr, old_buffer);
722         png_error(png_ptr, "Insufficient memory for save_buffer");
723      }
724
725      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
726      png_free(png_ptr, old_buffer);
727      png_ptr->save_buffer_max = new_max;
728   }
729
730   if (png_ptr->current_buffer_size)
731   {
732      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
733         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
734      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
735      png_ptr->current_buffer_size = 0;
736   }
737
738   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
739   png_ptr->buffer_size = 0;
740}
741
742void /* PRIVATE */
743png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
744   png_size_t buffer_length)
745{
746   png_ptr->current_buffer = buffer;
747   png_ptr->current_buffer_size = buffer_length;
748   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
749   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
750}
751
752void /* PRIVATE */
753png_push_read_IDAT(png_structp png_ptr)
754{
755   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
756   {
757      png_byte chunk_length[4];
758      png_byte chunk_tag[4];
759
760      /* TODO: this code can be commoned up with the same code in push_read */
761      if (png_ptr->buffer_size < 8)
762      {
763         png_push_save_buffer(png_ptr);
764         return;
765      }
766
767      png_push_fill_buffer(png_ptr, chunk_length, 4);
768      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
769      png_reset_crc(png_ptr);
770      png_crc_read(png_ptr, chunk_tag, 4);
771      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
772      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
773
774      if (png_ptr->chunk_name != png_IDAT)
775      {
776         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
777
778         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
779            png_error(png_ptr, "Not enough compressed data");
780
781         return;
782      }
783
784      png_ptr->idat_size = png_ptr->push_length;
785   }
786
787   if (png_ptr->idat_size && png_ptr->save_buffer_size)
788   {
789      png_size_t save_size = png_ptr->save_buffer_size;
790      png_uint_32 idat_size = png_ptr->idat_size;
791
792      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
793       * are of different types and we don't know which variable has the fewest
794       * bits.  Carefully select the smaller and cast it to the type of the
795       * larger - this cannot overflow.  Do not cast in the following test - it
796       * will break on either 16 or 64 bit platforms.
797       */
798      if (idat_size < save_size)
799         save_size = (png_size_t)idat_size;
800
801      else
802         idat_size = (png_uint_32)save_size;
803
804      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
805
806      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
807
808      png_ptr->idat_size -= idat_size;
809      png_ptr->buffer_size -= save_size;
810      png_ptr->save_buffer_size -= save_size;
811      png_ptr->save_buffer_ptr += save_size;
812   }
813
814   if (png_ptr->idat_size && png_ptr->current_buffer_size)
815   {
816      png_size_t save_size = png_ptr->current_buffer_size;
817      png_uint_32 idat_size = png_ptr->idat_size;
818
819      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
820       * are of different types and we don't know which variable has the fewest
821       * bits.  Carefully select the smaller and cast it to the type of the
822       * larger - this cannot overflow.
823       */
824      if (idat_size < save_size)
825         save_size = (png_size_t)idat_size;
826
827      else
828         idat_size = (png_uint_32)save_size;
829
830      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
831
832      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
833
834      png_ptr->idat_size -= idat_size;
835      png_ptr->buffer_size -= save_size;
836      png_ptr->current_buffer_size -= save_size;
837      png_ptr->current_buffer_ptr += save_size;
838   }
839
840   if (!png_ptr->idat_size)
841   {
842      if (png_ptr->buffer_size < 4)
843      {
844         png_push_save_buffer(png_ptr);
845         return;
846      }
847
848      png_crc_finish(png_ptr, 0);
849      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
850      png_ptr->mode |= PNG_AFTER_IDAT;
851   }
852}
853
854void /* PRIVATE */
855png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
856   png_size_t buffer_length)
857{
858   /* The caller checks for a non-zero buffer length. */
859   if (!(buffer_length > 0) || buffer == NULL)
860      png_error(png_ptr, "No IDAT data (internal error)");
861
862   /* This routine must process all the data it has been given
863    * before returning, calling the row callback as required to
864    * handle the uncompressed results.
865    */
866   png_ptr->zstream.next_in = buffer;
867   png_ptr->zstream.avail_in = (uInt)buffer_length;
868
869   /* Keep going until the decompressed data is all processed
870    * or the stream marked as finished.
871    */
872   while (png_ptr->zstream.avail_in > 0 &&
873          !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
874   {
875      int ret;
876
877      /* We have data for zlib, but we must check that zlib
878       * has someplace to put the results.  It doesn't matter
879       * if we don't expect any results -- it may be the input
880       * data is just the LZ end code.
881       */
882      if (!(png_ptr->zstream.avail_out > 0))
883      {
884         png_ptr->zstream.avail_out =
885             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
886             png_ptr->iwidth) + 1;
887
888         png_ptr->zstream.next_out = png_ptr->row_buf;
889      }
890
891      /* Using Z_SYNC_FLUSH here means that an unterminated
892       * LZ stream (a stream with a missing end code) can still
893       * be handled, otherwise (Z_NO_FLUSH) a future zlib
894       * implementation might defer output and therefore
895       * change the current behavior (see comments in inflate.c
896       * for why this doesn't happen at present with zlib 1.2.5).
897       */
898      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
899
900      /* Check for any failure before proceeding. */
901      if (ret != Z_OK && ret != Z_STREAM_END)
902      {
903         /* Terminate the decompression. */
904         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
905
906         /* This may be a truncated stream (missing or
907          * damaged end code).  Treat that as a warning.
908          */
909         if (png_ptr->row_number >= png_ptr->num_rows ||
910             png_ptr->pass > 6)
911            png_warning(png_ptr, "Truncated compressed data in IDAT");
912
913         else
914            png_error(png_ptr, "Decompression error in IDAT");
915
916         /* Skip the check on unprocessed input */
917         return;
918      }
919
920      /* Did inflate output any data? */
921      if (png_ptr->zstream.next_out != png_ptr->row_buf)
922      {
923         /* Is this unexpected data after the last row?
924          * If it is, artificially terminate the LZ output
925          * here.
926          */
927         if (png_ptr->row_number >= png_ptr->num_rows ||
928             png_ptr->pass > 6)
929         {
930            /* Extra data. */
931            png_warning(png_ptr, "Extra compressed data in IDAT");
932            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
933
934            /* Do no more processing; skip the unprocessed
935             * input check below.
936             */
937            return;
938         }
939
940         /* Do we have a complete row? */
941         if (png_ptr->zstream.avail_out == 0)
942            png_push_process_row(png_ptr);
943      }
944
945      /* And check for the end of the stream. */
946      if (ret == Z_STREAM_END)
947         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
948   }
949
950   /* All the data should have been processed, if anything
951    * is left at this point we have bytes of IDAT data
952    * after the zlib end code.
953    */
954   if (png_ptr->zstream.avail_in > 0)
955      png_warning(png_ptr, "Extra compression data in IDAT");
956}
957
958void /* PRIVATE */
959png_push_process_row(png_structp png_ptr)
960{
961   /* 1.5.6: row_info moved out of png_struct to a local here. */
962   png_row_info row_info;
963
964   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
965   row_info.color_type = png_ptr->color_type;
966   row_info.bit_depth = png_ptr->bit_depth;
967   row_info.channels = png_ptr->channels;
968   row_info.pixel_depth = png_ptr->pixel_depth;
969   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
970
971   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
972   {
973      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
974         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
975            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
976      else
977         png_error(png_ptr, "bad adaptive filter value");
978   }
979
980   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
981    * 1.5.6, while the buffer really is this big in current versions of libpng
982    * it may not be in the future, so this was changed just to copy the
983    * interlaced row count:
984    */
985   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
986
987#ifdef PNG_READ_TRANSFORMS_SUPPORTED
988   if (png_ptr->transformations)
989      png_do_read_transformations(png_ptr, &row_info);
990#endif
991
992   /* The transformed pixel depth should match the depth now in row_info. */
993   if (png_ptr->transformed_pixel_depth == 0)
994   {
995      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
996      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
997         png_error(png_ptr, "progressive row overflow");
998   }
999
1000   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
1001      png_error(png_ptr, "internal progressive row size calculation error");
1002
1003
1004#ifdef PNG_READ_INTERLACING_SUPPORTED
1005   /* Blow up interlaced rows to full size */
1006   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
1007   {
1008      if (png_ptr->pass < 6)
1009         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
1010            png_ptr->transformations);
1011
1012    switch (png_ptr->pass)
1013    {
1014         case 0:
1015         {
1016            int i;
1017            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
1018            {
1019               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1020               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
1021            }
1022
1023            if (png_ptr->pass == 2) /* Pass 1 might be empty */
1024            {
1025               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1026               {
1027                  png_push_have_row(png_ptr, NULL);
1028                  png_read_push_finish_row(png_ptr);
1029               }
1030            }
1031
1032            if (png_ptr->pass == 4 && png_ptr->height <= 4)
1033            {
1034               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1035               {
1036                  png_push_have_row(png_ptr, NULL);
1037                  png_read_push_finish_row(png_ptr);
1038               }
1039            }
1040
1041            if (png_ptr->pass == 6 && png_ptr->height <= 4)
1042            {
1043                png_push_have_row(png_ptr, NULL);
1044                png_read_push_finish_row(png_ptr);
1045            }
1046
1047            break;
1048         }
1049
1050         case 1:
1051         {
1052            int i;
1053            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
1054            {
1055               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1056               png_read_push_finish_row(png_ptr);
1057            }
1058
1059            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
1060            {
1061               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1062               {
1063                  png_push_have_row(png_ptr, NULL);
1064                  png_read_push_finish_row(png_ptr);
1065               }
1066            }
1067
1068            break;
1069         }
1070
1071         case 2:
1072         {
1073            int i;
1074
1075            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1076            {
1077               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1078               png_read_push_finish_row(png_ptr);
1079            }
1080
1081            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1082            {
1083               png_push_have_row(png_ptr, NULL);
1084               png_read_push_finish_row(png_ptr);
1085            }
1086
1087            if (png_ptr->pass == 4) /* Pass 3 might be empty */
1088            {
1089               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1090               {
1091                  png_push_have_row(png_ptr, NULL);
1092                  png_read_push_finish_row(png_ptr);
1093               }
1094            }
1095
1096            break;
1097         }
1098
1099         case 3:
1100         {
1101            int i;
1102
1103            for (i = 0; i < 4 && png_ptr->pass == 3; 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 == 4) /* Skip top two generated rows */
1110            {
1111               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1112               {
1113                  png_push_have_row(png_ptr, NULL);
1114                  png_read_push_finish_row(png_ptr);
1115               }
1116            }
1117
1118            break;
1119         }
1120
1121         case 4:
1122         {
1123            int i;
1124
1125            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1126            {
1127               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1128               png_read_push_finish_row(png_ptr);
1129            }
1130
1131            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1132            {
1133               png_push_have_row(png_ptr, NULL);
1134               png_read_push_finish_row(png_ptr);
1135            }
1136
1137            if (png_ptr->pass == 6) /* Pass 5 might be empty */
1138            {
1139               png_push_have_row(png_ptr, NULL);
1140               png_read_push_finish_row(png_ptr);
1141            }
1142
1143            break;
1144         }
1145
1146         case 5:
1147         {
1148            int i;
1149
1150            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
1151            {
1152               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1153               png_read_push_finish_row(png_ptr);
1154            }
1155
1156            if (png_ptr->pass == 6) /* Skip top generated row */
1157            {
1158               png_push_have_row(png_ptr, NULL);
1159               png_read_push_finish_row(png_ptr);
1160            }
1161
1162            break;
1163         }
1164
1165         default:
1166         case 6:
1167         {
1168            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1169            png_read_push_finish_row(png_ptr);
1170
1171            if (png_ptr->pass != 6)
1172               break;
1173
1174            png_push_have_row(png_ptr, NULL);
1175            png_read_push_finish_row(png_ptr);
1176         }
1177      }
1178   }
1179   else
1180#endif
1181   {
1182      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1183      png_read_push_finish_row(png_ptr);
1184   }
1185}
1186
1187void /* PRIVATE */
1188png_read_push_finish_row(png_structp png_ptr)
1189{
1190#ifdef PNG_READ_INTERLACING_SUPPORTED
1191   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1192
1193   /* Start of interlace block */
1194   static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1195
1196   /* Offset to next interlace block */
1197   static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1198
1199   /* Start of interlace block in the y direction */
1200   static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1201
1202   /* Offset to next interlace block in the y direction */
1203   static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1204
1205   /* Height of interlace block.  This is not currently used - if you need
1206    * it, uncomment it here and in png.h
1207   static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
1208   */
1209#endif
1210
1211   png_ptr->row_number++;
1212   if (png_ptr->row_number < png_ptr->num_rows)
1213      return;
1214
1215#ifdef PNG_READ_INTERLACING_SUPPORTED
1216   if (png_ptr->interlaced)
1217   {
1218      png_ptr->row_number = 0;
1219      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
1220
1221      do
1222      {
1223         png_ptr->pass++;
1224         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1225             (png_ptr->pass == 3 && png_ptr->width < 3) ||
1226             (png_ptr->pass == 5 && png_ptr->width < 2))
1227            png_ptr->pass++;
1228
1229         if (png_ptr->pass > 7)
1230            png_ptr->pass--;
1231
1232         if (png_ptr->pass >= 7)
1233            break;
1234
1235         png_ptr->iwidth = (png_ptr->width +
1236             png_pass_inc[png_ptr->pass] - 1 -
1237             png_pass_start[png_ptr->pass]) /
1238             png_pass_inc[png_ptr->pass];
1239
1240         if (png_ptr->transformations & PNG_INTERLACE)
1241            break;
1242
1243         png_ptr->num_rows = (png_ptr->height +
1244             png_pass_yinc[png_ptr->pass] - 1 -
1245             png_pass_ystart[png_ptr->pass]) /
1246             png_pass_yinc[png_ptr->pass];
1247
1248      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
1249   }
1250#endif /* PNG_READ_INTERLACING_SUPPORTED */
1251}
1252
1253void /* PRIVATE */
1254png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1255{
1256   if (png_ptr->info_fn != NULL)
1257      (*(png_ptr->info_fn))(png_ptr, info_ptr);
1258}
1259
1260void /* PRIVATE */
1261png_push_have_end(png_structp png_ptr, png_infop info_ptr)
1262{
1263   if (png_ptr->end_fn != NULL)
1264      (*(png_ptr->end_fn))(png_ptr, info_ptr);
1265}
1266
1267void /* PRIVATE */
1268png_push_have_row(png_structp png_ptr, png_bytep row)
1269{
1270   if (png_ptr->row_fn != NULL)
1271      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1272         (int)png_ptr->pass);
1273}
1274
1275#ifdef PNG_READ_INTERLACING_SUPPORTED
1276void PNGAPI
1277png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
1278    png_const_bytep new_row)
1279{
1280   if (png_ptr == NULL)
1281      return;
1282
1283   /* new_row is a flag here - if it is NULL then the app callback was called
1284    * from an empty row (see the calls to png_struct::row_fn below), otherwise
1285    * it must be png_ptr->row_buf+1
1286    */
1287   if (new_row != NULL)
1288      png_combine_row(png_ptr, old_row, 1/*display*/);
1289}
1290#endif /* PNG_READ_INTERLACING_SUPPORTED */
1291
1292void PNGAPI
1293png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
1294    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1295    png_progressive_end_ptr end_fn)
1296{
1297   if (png_ptr == NULL)
1298      return;
1299
1300   png_ptr->info_fn = info_fn;
1301   png_ptr->row_fn = row_fn;
1302   png_ptr->end_fn = end_fn;
1303
1304   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
1305}
1306
1307png_voidp PNGAPI
1308png_get_progressive_ptr(png_const_structp png_ptr)
1309{
1310   if (png_ptr == NULL)
1311      return (NULL);
1312
1313   return png_ptr->io_ptr;
1314}
1315#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
Note: See TracBrowser for help on using the repository browser.