• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* pngrutil.c - utilities to read a PNG file
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  * This file contains routines that are only called from within
14  * libpng itself during the course of reading an image.
15  */
16 
17 #define PNG_INTERNAL
18 #define PNG_NO_PEDANTIC_WARNINGS
19 #include "png.h"
20 #ifdef PNG_READ_SUPPORTED
21 
22 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
23 #  define WIN32_WCE_OLD
24 #endif
25 
26 #ifdef PNG_FLOATING_POINT_SUPPORTED
27 #  ifdef WIN32_WCE_OLD
28 /* The strtod() function is not supported on WindowsCE */
png_strtod(png_structp png_ptr,PNG_CONST char * nptr,char ** endptr)29 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
30     char **endptr)
31 {
32    double result = 0;
33    int len;
34    wchar_t *str, *end;
35 
36    len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
37    str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
38    if ( NULL != str )
39    {
40       MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
41       result = wcstod(str, &end);
42       len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
43       *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
44       png_free(png_ptr, str);
45    }
46    return result;
47 }
48 #  else
49 #    define png_strtod(p,a,b) strtod(a,b)
50 #  endif
51 #endif
52 
53 png_uint_32 PNGAPI
png_get_uint_31(png_structp png_ptr,png_bytep buf)54 png_get_uint_31(png_structp png_ptr, png_bytep buf)
55 {
56 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
57    png_uint_32 i = png_get_uint_32(buf);
58 #else
59    /* Avoid an extra function call by inlining the result. */
60    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
61       ((png_uint_32)(*(buf + 1)) << 16) +
62       ((png_uint_32)(*(buf + 2)) << 8) +
63       (png_uint_32)(*(buf + 3));
64 #endif
65    if (i > PNG_UINT_31_MAX)
66      png_error(png_ptr, "PNG unsigned integer out of range.");
67    return (i);
68 }
69 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
70 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
71 png_uint_32 PNGAPI
png_get_uint_32(png_bytep buf)72 png_get_uint_32(png_bytep buf)
73 {
74    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
75       ((png_uint_32)(*(buf + 1)) << 16) +
76       ((png_uint_32)(*(buf + 2)) << 8) +
77       (png_uint_32)(*(buf + 3));
78 
79    return (i);
80 }
81 
82 /* Grab a signed 32-bit integer from a buffer in big-endian format.  The
83  * data is stored in the PNG file in two's complement format, and it is
84  * assumed that the machine format for signed integers is the same.
85  */
86 png_int_32 PNGAPI
png_get_int_32(png_bytep buf)87 png_get_int_32(png_bytep buf)
88 {
89    png_int_32 i = ((png_int_32)(*buf) << 24) +
90       ((png_int_32)(*(buf + 1)) << 16) +
91       ((png_int_32)(*(buf + 2)) << 8) +
92       (png_int_32)(*(buf + 3));
93 
94    return (i);
95 }
96 
97 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
98 png_uint_16 PNGAPI
png_get_uint_16(png_bytep buf)99 png_get_uint_16(png_bytep buf)
100 {
101    png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
102       (png_uint_16)(*(buf + 1)));
103 
104    return (i);
105 }
106 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
107 
108 /* Read the chunk header (length + type name).
109  * Put the type name into png_ptr->chunk_name, and return the length.
110  */
111 png_uint_32 /* PRIVATE */
png_read_chunk_header(png_structp png_ptr)112 png_read_chunk_header(png_structp png_ptr)
113 {
114    png_byte buf[8];
115    png_uint_32 length;
116 
117    /* Read the length and the chunk name */
118    png_read_data(png_ptr, buf, 8);
119    length = png_get_uint_31(png_ptr, buf);
120 
121    /* Put the chunk name into png_ptr->chunk_name */
122    png_memcpy(png_ptr->chunk_name, buf + 4, 4);
123 
124    png_debug2(0, "Reading %s chunk, length = %lu",
125       png_ptr->chunk_name, length);
126 
127    /* Reset the crc and run it over the chunk name */
128    png_reset_crc(png_ptr);
129    png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
130 
131    /* Check to see if chunk name is valid */
132    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
133 
134    return length;
135 }
136 
137 /* Read data, and (optionally) run it through the CRC. */
138 void /* PRIVATE */
png_crc_read(png_structp png_ptr,png_bytep buf,png_size_t length)139 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
140 {
141    if (png_ptr == NULL)
142       return;
143    png_read_data(png_ptr, buf, length);
144    png_calculate_crc(png_ptr, buf, length);
145 }
146 
147 /* Optionally skip data and then check the CRC.  Depending on whether we
148  * are reading a ancillary or critical chunk, and how the program has set
149  * things up, we may calculate the CRC on the data and print a message.
150  * Returns '1' if there was a CRC error, '0' otherwise.
151  */
152 int /* PRIVATE */
png_crc_finish(png_structp png_ptr,png_uint_32 skip)153 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
154 {
155    png_size_t i;
156    png_size_t istop = png_ptr->zbuf_size;
157 
158    for (i = (png_size_t)skip; i > istop; i -= istop)
159    {
160       png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
161    }
162    if (i)
163    {
164       png_crc_read(png_ptr, png_ptr->zbuf, i);
165    }
166 
167    if (png_crc_error(png_ptr))
168    {
169       if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
170           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
171           (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
172           (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
173       {
174          png_chunk_warning(png_ptr, "CRC error");
175       }
176       else
177       {
178          png_chunk_error(png_ptr, "CRC error");
179       }
180       return (1);
181    }
182 
183    return (0);
184 }
185 
186 /* Compare the CRC stored in the PNG file with that calculated by libpng from
187  * the data it has read thus far.
188  */
189 int /* PRIVATE */
png_crc_error(png_structp png_ptr)190 png_crc_error(png_structp png_ptr)
191 {
192    png_byte crc_bytes[4];
193    png_uint_32 crc;
194    int need_crc = 1;
195 
196    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
197    {
198       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
199           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
200          need_crc = 0;
201    }
202    else                                                    /* critical */
203    {
204       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
205          need_crc = 0;
206    }
207 
208    png_read_data(png_ptr, crc_bytes, 4);
209 
210    if (need_crc)
211    {
212       crc = png_get_uint_32(crc_bytes);
213       return ((int)(crc != png_ptr->crc));
214    }
215    else
216       return (0);
217 }
218 
219 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
220     defined(PNG_READ_iCCP_SUPPORTED)
221 static png_size_t
png_inflate(png_structp png_ptr,const png_byte * data,png_size_t size,png_bytep output,png_size_t output_size)222 png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
223         png_bytep output, png_size_t output_size)
224 {
225    png_size_t count = 0;
226 
227    png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
228    png_ptr->zstream.avail_in = size;
229 
230    while (1)
231    {
232       int ret, avail;
233 
234       /* Reset the output buffer each time round - we empty it
235        * after every inflate call.
236        */
237       png_ptr->zstream.next_out = png_ptr->zbuf;
238       png_ptr->zstream.avail_out = png_ptr->zbuf_size;
239 
240       ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
241       avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
242 
243       /* First copy/count any new output - but only if we didn't
244        * get an error code.
245        */
246       if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
247       {
248          if (output != 0 && output_size > count)
249          {
250             int copy = output_size - count;
251             if (avail < copy) copy = avail;
252             png_memcpy(output + count, png_ptr->zbuf, copy);
253          }
254          count += avail;
255       }
256 
257       if (ret == Z_OK)
258          continue;
259 
260       /* Termination conditions - always reset the zstream, it
261        * must be left in inflateInit state.
262        */
263       png_ptr->zstream.avail_in = 0;
264       inflateReset(&png_ptr->zstream);
265 
266       if (ret == Z_STREAM_END)
267          return count; /* NOTE: may be zero. */
268 
269       /* Now handle the error codes - the API always returns 0
270        * and the error message is dumped into the uncompressed
271        * buffer if available.
272        */
273       {
274          PNG_CONST char *msg;
275          if (png_ptr->zstream.msg != 0)
276             msg = png_ptr->zstream.msg;
277          else
278          {
279 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
280             char umsg[52];
281 
282             switch (ret)
283             {
284                case Z_BUF_ERROR:
285                   msg = "Buffer error in compressed datastream in %s chunk";
286                   break;
287                case Z_DATA_ERROR:
288                   msg = "Data error in compressed datastream in %s chunk";
289                   break;
290                default:
291                   msg = "Incomplete compressed datastream in %s chunk";
292                   break;
293             }
294 
295             png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
296             msg = umsg;
297 #else
298             msg = "Damaged compressed datastream in chunk other than IDAT";
299 #endif
300          }
301 
302          png_warning(png_ptr, msg);
303       }
304 
305       /* 0 means an error - notice that this code simple ignores
306        * zero length compressed chunks as a result.
307        */
308       return 0;
309    }
310 }
311 
312 /*
313  * Decompress trailing data in a chunk.  The assumption is that chunkdata
314  * points at an allocated area holding the contents of a chunk with a
315  * trailing compressed part.  What we get back is an allocated area
316  * holding the original prefix part and an uncompressed version of the
317  * trailing part (the malloc area passed in is freed).
318  */
319 void /* PRIVATE */
png_decompress_chunk(png_structp png_ptr,int comp_type,png_size_t chunklength,png_size_t prefix_size,png_size_t * newlength)320 png_decompress_chunk(png_structp png_ptr, int comp_type,
321     png_size_t chunklength,
322     png_size_t prefix_size, png_size_t *newlength)
323 {
324    /* The caller should guarantee this */
325    if (prefix_size > chunklength)
326    {
327       /* The recovery is to delete the chunk. */
328       png_warning(png_ptr, "invalid chunklength");
329       prefix_size = 0; /* To delete everything */
330    }
331 
332    else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
333    {
334       png_size_t expanded_size = png_inflate(png_ptr,
335                 (png_bytep)(png_ptr->chunkdata + prefix_size),
336                 chunklength - prefix_size,
337                 0/*output*/, 0/*output size*/);
338 
339       /* Now check the limits on this chunk - if the limit fails the
340        * compressed data will be removed, the prefix will remain.
341        */
342 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
343       if (png_ptr->user_chunk_malloc_max &&
344           (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
345 #else
346 #  ifdef PNG_USER_CHUNK_MALLOC_MAX
347       if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
348           prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
349 #  endif
350 #endif
351          png_warning(png_ptr, "Exceeded size limit while expanding chunk");
352 
353       /* If the size is zero either there was an error and a message
354        * has already been output (warning) or the size really is zero
355        * and we have nothing to do - the code will exit through the
356        * error case below.
357        */
358 #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
359     defined(PNG_USER_CHUNK_MALLOC_MAX)
360       else
361 #endif
362       if (expanded_size > 0)
363       {
364          /* Success (maybe) - really uncompress the chunk. */
365          png_size_t new_size = 0;
366          png_charp text = png_malloc_warn(png_ptr,
367                         prefix_size + expanded_size + 1);
368 
369          if (text != NULL)
370          {
371             png_memcpy(text, png_ptr->chunkdata, prefix_size);
372             new_size = png_inflate(png_ptr,
373                 (png_bytep)(png_ptr->chunkdata + prefix_size),
374                 chunklength - prefix_size,
375                 (png_bytep)(text + prefix_size), expanded_size);
376             text[prefix_size + expanded_size] = 0; /* just in case */
377 
378             if (new_size == expanded_size)
379             {
380                png_free(png_ptr, png_ptr->chunkdata);
381                png_ptr->chunkdata = text;
382                *newlength = prefix_size + expanded_size;
383                return; /* The success return! */
384             }
385 
386             png_warning(png_ptr, "png_inflate logic error");
387             png_free(png_ptr, text);
388          }
389          else
390           png_warning(png_ptr, "Not enough memory to decompress chunk.");
391       }
392    }
393 
394    else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
395    {
396 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
397       char umsg[50];
398 
399       png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
400           comp_type);
401       png_warning(png_ptr, umsg);
402 #else
403       png_warning(png_ptr, "Unknown zTXt compression type");
404 #endif
405 
406       /* The recovery is to simply drop the data. */
407    }
408 
409    /* Generic error return - leave the prefix, delete the compressed
410     * data, reallocate the chunkdata to remove the potentially large
411     * amount of compressed data.
412     */
413    {
414       png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
415       if (text != NULL)
416       {
417          if (prefix_size > 0)
418             png_memcpy(text, png_ptr->chunkdata, prefix_size);
419          png_free(png_ptr, png_ptr->chunkdata);
420          png_ptr->chunkdata = text;
421 
422          /* This is an extra zero in the 'uncompressed' part. */
423          *(png_ptr->chunkdata + prefix_size) = 0x00;
424       }
425       /* Ignore a malloc error here - it is safe. */
426    }
427 
428    *newlength = prefix_size;
429 }
430 #endif
431 
432 /* Read and check the IDHR chunk */
433 void /* PRIVATE */
png_handle_IHDR(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)434 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
435 {
436    png_byte buf[13];
437    png_uint_32 width, height;
438    int bit_depth, color_type, compression_type, filter_type;
439    int interlace_type;
440 
441    png_debug(1, "in png_handle_IHDR");
442 
443    if (png_ptr->mode & PNG_HAVE_IHDR)
444       png_error(png_ptr, "Out of place IHDR");
445 
446    /* Check the length */
447    if (length != 13)
448       png_error(png_ptr, "Invalid IHDR chunk");
449 
450    png_ptr->mode |= PNG_HAVE_IHDR;
451 
452    png_crc_read(png_ptr, buf, 13);
453    png_crc_finish(png_ptr, 0);
454 
455    width = png_get_uint_31(png_ptr, buf);
456    height = png_get_uint_31(png_ptr, buf + 4);
457    bit_depth = buf[8];
458    color_type = buf[9];
459    compression_type = buf[10];
460    filter_type = buf[11];
461    interlace_type = buf[12];
462 
463    /* Set internal variables */
464    png_ptr->width = width;
465    png_ptr->height = height;
466    png_ptr->bit_depth = (png_byte)bit_depth;
467    png_ptr->interlaced = (png_byte)interlace_type;
468    png_ptr->color_type = (png_byte)color_type;
469 #ifdef PNG_MNG_FEATURES_SUPPORTED
470    png_ptr->filter_type = (png_byte)filter_type;
471 #endif
472    png_ptr->compression_type = (png_byte)compression_type;
473 
474    /* Find number of channels */
475    switch (png_ptr->color_type)
476    {
477       case PNG_COLOR_TYPE_GRAY:
478       case PNG_COLOR_TYPE_PALETTE:
479          png_ptr->channels = 1;
480          break;
481 
482       case PNG_COLOR_TYPE_RGB:
483          png_ptr->channels = 3;
484          break;
485 
486       case PNG_COLOR_TYPE_GRAY_ALPHA:
487          png_ptr->channels = 2;
488          break;
489 
490       case PNG_COLOR_TYPE_RGB_ALPHA:
491          png_ptr->channels = 4;
492          break;
493    }
494 
495    /* Set up other useful info */
496    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
497    png_ptr->channels);
498    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
499    png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
500    png_debug1(3, "channels = %d", png_ptr->channels);
501    png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
502    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
503       color_type, interlace_type, compression_type, filter_type);
504 }
505 
506 /* Read and check the palette */
507 void /* PRIVATE */
png_handle_PLTE(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)508 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
509 {
510    png_color palette[PNG_MAX_PALETTE_LENGTH];
511    int num, i;
512 #ifdef PNG_POINTER_INDEXING_SUPPORTED
513    png_colorp pal_ptr;
514 #endif
515 
516    png_debug(1, "in png_handle_PLTE");
517 
518    if (!(png_ptr->mode & PNG_HAVE_IHDR))
519       png_error(png_ptr, "Missing IHDR before PLTE");
520 
521    else if (png_ptr->mode & PNG_HAVE_IDAT)
522    {
523       png_warning(png_ptr, "Invalid PLTE after IDAT");
524       png_crc_finish(png_ptr, length);
525       return;
526    }
527 
528    else if (png_ptr->mode & PNG_HAVE_PLTE)
529       png_error(png_ptr, "Duplicate PLTE chunk");
530 
531    png_ptr->mode |= PNG_HAVE_PLTE;
532 
533    if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
534    {
535       png_warning(png_ptr,
536         "Ignoring PLTE chunk in grayscale PNG");
537       png_crc_finish(png_ptr, length);
538       return;
539    }
540 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
541    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
542    {
543       png_crc_finish(png_ptr, length);
544       return;
545    }
546 #endif
547 
548    if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
549    {
550       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
551       {
552          png_warning(png_ptr, "Invalid palette chunk");
553          png_crc_finish(png_ptr, length);
554          return;
555       }
556 
557       else
558       {
559          png_error(png_ptr, "Invalid palette chunk");
560       }
561    }
562 
563    num = (int)length / 3;
564 
565 #ifdef PNG_POINTER_INDEXING_SUPPORTED
566    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
567    {
568       png_byte buf[3];
569 
570       png_crc_read(png_ptr, buf, 3);
571       pal_ptr->red = buf[0];
572       pal_ptr->green = buf[1];
573       pal_ptr->blue = buf[2];
574    }
575 #else
576    for (i = 0; i < num; i++)
577    {
578       png_byte buf[3];
579 
580       png_crc_read(png_ptr, buf, 3);
581       /* Don't depend upon png_color being any order */
582       palette[i].red = buf[0];
583       palette[i].green = buf[1];
584       palette[i].blue = buf[2];
585    }
586 #endif
587 
588    /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
589     * whatever the normal CRC configuration tells us.  However, if we
590     * have an RGB image, the PLTE can be considered ancillary, so
591     * we will act as though it is.
592     */
593 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
594    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
595 #endif
596    {
597       png_crc_finish(png_ptr, 0);
598    }
599 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
600    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
601    {
602       /* If we don't want to use the data from an ancillary chunk,
603          we have two options: an error abort, or a warning and we
604          ignore the data in this chunk (which should be OK, since
605          it's considered ancillary for a RGB or RGBA image). */
606       if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
607       {
608          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
609          {
610             png_chunk_error(png_ptr, "CRC error");
611          }
612          else
613          {
614             png_chunk_warning(png_ptr, "CRC error");
615             return;
616          }
617       }
618       /* Otherwise, we (optionally) emit a warning and use the chunk. */
619       else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
620       {
621          png_chunk_warning(png_ptr, "CRC error");
622       }
623    }
624 #endif
625 
626    png_set_PLTE(png_ptr, info_ptr, palette, num);
627 
628 #ifdef PNG_READ_tRNS_SUPPORTED
629    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
630    {
631       if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
632       {
633          if (png_ptr->num_trans > (png_uint_16)num)
634          {
635             png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
636             png_ptr->num_trans = (png_uint_16)num;
637          }
638          if (info_ptr->num_trans > (png_uint_16)num)
639          {
640             png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
641             info_ptr->num_trans = (png_uint_16)num;
642          }
643       }
644    }
645 #endif
646 
647 }
648 
649 void /* PRIVATE */
png_handle_IEND(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)650 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
651 {
652    png_debug(1, "in png_handle_IEND");
653 
654    if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
655    {
656       png_error(png_ptr, "No image in file");
657    }
658 
659    png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
660 
661    if (length != 0)
662    {
663       png_warning(png_ptr, "Incorrect IEND chunk length");
664    }
665    png_crc_finish(png_ptr, length);
666 
667    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
668 }
669 
670 #ifdef PNG_READ_gAMA_SUPPORTED
671 void /* PRIVATE */
png_handle_gAMA(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)672 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
673 {
674    png_fixed_point igamma;
675 #ifdef PNG_FLOATING_POINT_SUPPORTED
676    float file_gamma;
677 #endif
678    png_byte buf[4];
679 
680    png_debug(1, "in png_handle_gAMA");
681 
682    if (!(png_ptr->mode & PNG_HAVE_IHDR))
683       png_error(png_ptr, "Missing IHDR before gAMA");
684    else if (png_ptr->mode & PNG_HAVE_IDAT)
685    {
686       png_warning(png_ptr, "Invalid gAMA after IDAT");
687       png_crc_finish(png_ptr, length);
688       return;
689    }
690    else if (png_ptr->mode & PNG_HAVE_PLTE)
691       /* Should be an error, but we can cope with it */
692       png_warning(png_ptr, "Out of place gAMA chunk");
693 
694    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
695 #ifdef PNG_READ_sRGB_SUPPORTED
696       && !(info_ptr->valid & PNG_INFO_sRGB)
697 #endif
698       )
699    {
700       png_warning(png_ptr, "Duplicate gAMA chunk");
701       png_crc_finish(png_ptr, length);
702       return;
703    }
704 
705    if (length != 4)
706    {
707       png_warning(png_ptr, "Incorrect gAMA chunk length");
708       png_crc_finish(png_ptr, length);
709       return;
710    }
711 
712    png_crc_read(png_ptr, buf, 4);
713    if (png_crc_finish(png_ptr, 0))
714       return;
715 
716    igamma = (png_fixed_point)png_get_uint_32(buf);
717    /* Check for zero gamma */
718    if (igamma == 0)
719       {
720          png_warning(png_ptr,
721            "Ignoring gAMA chunk with gamma=0");
722          return;
723       }
724 
725 #ifdef PNG_READ_sRGB_SUPPORTED
726    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
727       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
728       {
729          png_warning(png_ptr,
730            "Ignoring incorrect gAMA value when sRGB is also present");
731 #ifdef PNG_CONSOLE_IO_SUPPORTED
732          fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
733 #endif
734          return;
735       }
736 #endif /* PNG_READ_sRGB_SUPPORTED */
737 
738 #ifdef PNG_FLOATING_POINT_SUPPORTED
739    file_gamma = (float)igamma / (float)100000.0;
740 #  ifdef PNG_READ_GAMMA_SUPPORTED
741      png_ptr->gamma = file_gamma;
742 #  endif
743      png_set_gAMA(png_ptr, info_ptr, file_gamma);
744 #endif
745 #ifdef PNG_FIXED_POINT_SUPPORTED
746    png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
747 #endif
748 }
749 #endif
750 
751 #ifdef PNG_READ_sBIT_SUPPORTED
752 void /* PRIVATE */
png_handle_sBIT(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)753 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
754 {
755    png_size_t truelen;
756    png_byte buf[4];
757 
758    png_debug(1, "in png_handle_sBIT");
759 
760    buf[0] = buf[1] = buf[2] = buf[3] = 0;
761 
762    if (!(png_ptr->mode & PNG_HAVE_IHDR))
763       png_error(png_ptr, "Missing IHDR before sBIT");
764    else if (png_ptr->mode & PNG_HAVE_IDAT)
765    {
766       png_warning(png_ptr, "Invalid sBIT after IDAT");
767       png_crc_finish(png_ptr, length);
768       return;
769    }
770    else if (png_ptr->mode & PNG_HAVE_PLTE)
771    {
772       /* Should be an error, but we can cope with it */
773       png_warning(png_ptr, "Out of place sBIT chunk");
774    }
775    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
776    {
777       png_warning(png_ptr, "Duplicate sBIT chunk");
778       png_crc_finish(png_ptr, length);
779       return;
780    }
781 
782    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
783       truelen = 3;
784    else
785       truelen = (png_size_t)png_ptr->channels;
786 
787    if (length != truelen || length > 4)
788    {
789       png_warning(png_ptr, "Incorrect sBIT chunk length");
790       png_crc_finish(png_ptr, length);
791       return;
792    }
793 
794    png_crc_read(png_ptr, buf, truelen);
795    if (png_crc_finish(png_ptr, 0))
796       return;
797 
798    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
799    {
800       png_ptr->sig_bit.red = buf[0];
801       png_ptr->sig_bit.green = buf[1];
802       png_ptr->sig_bit.blue = buf[2];
803       png_ptr->sig_bit.alpha = buf[3];
804    }
805    else
806    {
807       png_ptr->sig_bit.gray = buf[0];
808       png_ptr->sig_bit.red = buf[0];
809       png_ptr->sig_bit.green = buf[0];
810       png_ptr->sig_bit.blue = buf[0];
811       png_ptr->sig_bit.alpha = buf[1];
812    }
813    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
814 }
815 #endif
816 
817 #ifdef PNG_READ_cHRM_SUPPORTED
818 void /* PRIVATE */
png_handle_cHRM(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)819 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
820 {
821    png_byte buf[32];
822 #ifdef PNG_FLOATING_POINT_SUPPORTED
823    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
824 #endif
825    png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
826       int_y_green, int_x_blue, int_y_blue;
827 
828    png_uint_32 uint_x, uint_y;
829 
830    png_debug(1, "in png_handle_cHRM");
831 
832    if (!(png_ptr->mode & PNG_HAVE_IHDR))
833       png_error(png_ptr, "Missing IHDR before cHRM");
834    else if (png_ptr->mode & PNG_HAVE_IDAT)
835    {
836       png_warning(png_ptr, "Invalid cHRM after IDAT");
837       png_crc_finish(png_ptr, length);
838       return;
839    }
840    else if (png_ptr->mode & PNG_HAVE_PLTE)
841       /* Should be an error, but we can cope with it */
842       png_warning(png_ptr, "Missing PLTE before cHRM");
843 
844    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
845 #ifdef PNG_READ_sRGB_SUPPORTED
846       && !(info_ptr->valid & PNG_INFO_sRGB)
847 #endif
848       )
849    {
850       png_warning(png_ptr, "Duplicate cHRM chunk");
851       png_crc_finish(png_ptr, length);
852       return;
853    }
854 
855    if (length != 32)
856    {
857       png_warning(png_ptr, "Incorrect cHRM chunk length");
858       png_crc_finish(png_ptr, length);
859       return;
860    }
861 
862    png_crc_read(png_ptr, buf, 32);
863    if (png_crc_finish(png_ptr, 0))
864       return;
865 
866    uint_x = png_get_uint_32(buf);
867    uint_y = png_get_uint_32(buf + 4);
868    int_x_white = (png_fixed_point)uint_x;
869    int_y_white = (png_fixed_point)uint_y;
870 
871    uint_x = png_get_uint_32(buf + 8);
872    uint_y = png_get_uint_32(buf + 12);
873    int_x_red = (png_fixed_point)uint_x;
874    int_y_red = (png_fixed_point)uint_y;
875 
876    uint_x = png_get_uint_32(buf + 16);
877    uint_y = png_get_uint_32(buf + 20);
878    int_x_green = (png_fixed_point)uint_x;
879    int_y_green = (png_fixed_point)uint_y;
880 
881    uint_x = png_get_uint_32(buf + 24);
882    uint_y = png_get_uint_32(buf + 28);
883    int_x_blue = (png_fixed_point)uint_x;
884    int_y_blue = (png_fixed_point)uint_y;
885 
886 #ifdef PNG_FLOATING_POINT_SUPPORTED
887    white_x = (float)int_x_white / (float)100000.0;
888    white_y = (float)int_y_white / (float)100000.0;
889    red_x   = (float)int_x_red   / (float)100000.0;
890    red_y   = (float)int_y_red   / (float)100000.0;
891    green_x = (float)int_x_green / (float)100000.0;
892    green_y = (float)int_y_green / (float)100000.0;
893    blue_x  = (float)int_x_blue  / (float)100000.0;
894    blue_y  = (float)int_y_blue  / (float)100000.0;
895 #endif
896 
897 #ifdef PNG_READ_sRGB_SUPPORTED
898    if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
899       {
900       if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
901           PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
902           PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
903           PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
904           PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
905           PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
906           PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
907           PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
908          {
909             png_warning(png_ptr,
910               "Ignoring incorrect cHRM value when sRGB is also present");
911 #ifdef PNG_CONSOLE_IO_SUPPORTED
912 #ifdef PNG_FLOATING_POINT_SUPPORTED
913             fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
914                white_x, white_y, red_x, red_y);
915             fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
916                green_x, green_y, blue_x, blue_y);
917 #else
918             fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
919                (long)int_x_white, (long)int_y_white,
920                (long)int_x_red, (long)int_y_red);
921             fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
922                (long)int_x_green, (long)int_y_green,
923                (long)int_x_blue, (long)int_y_blue);
924 #endif
925 #endif /* PNG_CONSOLE_IO_SUPPORTED */
926          }
927          return;
928       }
929 #endif /* PNG_READ_sRGB_SUPPORTED */
930 
931 #ifdef PNG_FLOATING_POINT_SUPPORTED
932    png_set_cHRM(png_ptr, info_ptr,
933       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
934 #endif
935 #ifdef PNG_FIXED_POINT_SUPPORTED
936    png_set_cHRM_fixed(png_ptr, info_ptr,
937       int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
938       int_y_green, int_x_blue, int_y_blue);
939 #endif
940 }
941 #endif
942 
943 #ifdef PNG_READ_sRGB_SUPPORTED
944 void /* PRIVATE */
png_handle_sRGB(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)945 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
946 {
947    int intent;
948    png_byte buf[1];
949 
950    png_debug(1, "in png_handle_sRGB");
951 
952    if (!(png_ptr->mode & PNG_HAVE_IHDR))
953       png_error(png_ptr, "Missing IHDR before sRGB");
954    else if (png_ptr->mode & PNG_HAVE_IDAT)
955    {
956       png_warning(png_ptr, "Invalid sRGB after IDAT");
957       png_crc_finish(png_ptr, length);
958       return;
959    }
960    else if (png_ptr->mode & PNG_HAVE_PLTE)
961       /* Should be an error, but we can cope with it */
962       png_warning(png_ptr, "Out of place sRGB chunk");
963 
964    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
965    {
966       png_warning(png_ptr, "Duplicate sRGB chunk");
967       png_crc_finish(png_ptr, length);
968       return;
969    }
970 
971    if (length != 1)
972    {
973       png_warning(png_ptr, "Incorrect sRGB chunk length");
974       png_crc_finish(png_ptr, length);
975       return;
976    }
977 
978    png_crc_read(png_ptr, buf, 1);
979    if (png_crc_finish(png_ptr, 0))
980       return;
981 
982    intent = buf[0];
983    /* Check for bad intent */
984    if (intent >= PNG_sRGB_INTENT_LAST)
985    {
986       png_warning(png_ptr, "Unknown sRGB intent");
987       return;
988    }
989 
990 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
991    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
992    {
993    png_fixed_point igamma;
994 #ifdef PNG_FIXED_POINT_SUPPORTED
995       igamma=info_ptr->int_gamma;
996 #else
997 #  ifdef PNG_FLOATING_POINT_SUPPORTED
998       igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
999 #  endif
1000 #endif
1001       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
1002       {
1003          png_warning(png_ptr,
1004            "Ignoring incorrect gAMA value when sRGB is also present");
1005 #ifdef PNG_CONSOLE_IO_SUPPORTED
1006 #  ifdef PNG_FIXED_POINT_SUPPORTED
1007          fprintf(stderr, "incorrect gamma=(%d/100000)\n",
1008             (int)png_ptr->int_gamma);
1009 #  else
1010 #    ifdef PNG_FLOATING_POINT_SUPPORTED
1011          fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
1012 #    endif
1013 #  endif
1014 #endif
1015       }
1016    }
1017 #endif /* PNG_READ_gAMA_SUPPORTED */
1018 
1019 #ifdef PNG_READ_cHRM_SUPPORTED
1020 #ifdef PNG_FIXED_POINT_SUPPORTED
1021    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1022       if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
1023           PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
1024           PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
1025           PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
1026           PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
1027           PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
1028           PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
1029           PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
1030          {
1031             png_warning(png_ptr,
1032               "Ignoring incorrect cHRM value when sRGB is also present");
1033          }
1034 #endif /* PNG_FIXED_POINT_SUPPORTED */
1035 #endif /* PNG_READ_cHRM_SUPPORTED */
1036 
1037    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1038 }
1039 #endif /* PNG_READ_sRGB_SUPPORTED */
1040 
1041 #ifdef PNG_READ_iCCP_SUPPORTED
1042 void /* PRIVATE */
png_handle_iCCP(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1043 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1044 /* Note: this does not properly handle chunks that are > 64K under DOS */
1045 {
1046    png_byte compression_type;
1047    png_bytep pC;
1048    png_charp profile;
1049    png_uint_32 skip = 0;
1050    png_uint_32 profile_size, profile_length;
1051    png_size_t slength, prefix_length, data_length;
1052 
1053    png_debug(1, "in png_handle_iCCP");
1054 
1055    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1056       png_error(png_ptr, "Missing IHDR before iCCP");
1057    else if (png_ptr->mode & PNG_HAVE_IDAT)
1058    {
1059       png_warning(png_ptr, "Invalid iCCP after IDAT");
1060       png_crc_finish(png_ptr, length);
1061       return;
1062    }
1063    else if (png_ptr->mode & PNG_HAVE_PLTE)
1064       /* Should be an error, but we can cope with it */
1065       png_warning(png_ptr, "Out of place iCCP chunk");
1066 
1067    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1068    {
1069       png_warning(png_ptr, "Duplicate iCCP chunk");
1070       png_crc_finish(png_ptr, length);
1071       return;
1072    }
1073 
1074 #ifdef PNG_MAX_MALLOC_64K
1075    if (length > (png_uint_32)65535L)
1076    {
1077       png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1078       skip = length - (png_uint_32)65535L;
1079       length = (png_uint_32)65535L;
1080    }
1081 #endif
1082 
1083    png_free(png_ptr, png_ptr->chunkdata);
1084    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1085    slength = (png_size_t)length;
1086    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1087 
1088    if (png_crc_finish(png_ptr, skip))
1089    {
1090       png_free(png_ptr, png_ptr->chunkdata);
1091       png_ptr->chunkdata = NULL;
1092       return;
1093    }
1094 
1095    png_ptr->chunkdata[slength] = 0x00;
1096 
1097    for (profile = png_ptr->chunkdata; *profile; profile++)
1098       /* Empty loop to find end of name */ ;
1099 
1100    ++profile;
1101 
1102    /* There should be at least one zero (the compression type byte)
1103     * following the separator, and we should be on it
1104     */
1105    if ( profile >= png_ptr->chunkdata + slength - 1)
1106    {
1107       png_free(png_ptr, png_ptr->chunkdata);
1108       png_ptr->chunkdata = NULL;
1109       png_warning(png_ptr, "Malformed iCCP chunk");
1110       return;
1111    }
1112 
1113    /* Compression_type should always be zero */
1114    compression_type = *profile++;
1115    if (compression_type)
1116    {
1117       png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1118       compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
1119                                  wrote nonzero) */
1120    }
1121 
1122    prefix_length = profile - png_ptr->chunkdata;
1123    png_decompress_chunk(png_ptr, compression_type,
1124      slength, prefix_length, &data_length);
1125 
1126    profile_length = data_length - prefix_length;
1127 
1128    if ( prefix_length > data_length || profile_length < 4)
1129    {
1130       png_free(png_ptr, png_ptr->chunkdata);
1131       png_ptr->chunkdata = NULL;
1132       png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1133       return;
1134    }
1135 
1136    /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1137    pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1138    profile_size = ((*(pC    ))<<24) |
1139                   ((*(pC + 1))<<16) |
1140                   ((*(pC + 2))<< 8) |
1141                   ((*(pC + 3))    );
1142 
1143    if (profile_size < profile_length)
1144       profile_length = profile_size;
1145 
1146    if (profile_size > profile_length)
1147    {
1148       png_free(png_ptr, png_ptr->chunkdata);
1149       png_ptr->chunkdata = NULL;
1150       png_warning(png_ptr, "Ignoring truncated iCCP profile.");
1151       return;
1152    }
1153 
1154    png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1155      compression_type, png_ptr->chunkdata + prefix_length, profile_length);
1156    png_free(png_ptr, png_ptr->chunkdata);
1157    png_ptr->chunkdata = NULL;
1158 }
1159 #endif /* PNG_READ_iCCP_SUPPORTED */
1160 
1161 #ifdef PNG_READ_sPLT_SUPPORTED
1162 void /* PRIVATE */
png_handle_sPLT(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1163 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1164 /* Note: this does not properly handle chunks that are > 64K under DOS */
1165 {
1166    png_bytep entry_start;
1167    png_sPLT_t new_palette;
1168 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1169    png_sPLT_entryp pp;
1170 #endif
1171    int data_length, entry_size, i;
1172    png_uint_32 skip = 0;
1173    png_size_t slength;
1174 
1175    png_debug(1, "in png_handle_sPLT");
1176 
1177 #ifdef PNG_USER_LIMITS_SUPPORTED
1178 
1179    if (png_ptr->user_chunk_cache_max != 0)
1180    {
1181       if (png_ptr->user_chunk_cache_max == 1)
1182       {
1183          png_crc_finish(png_ptr, length);
1184          return;
1185       }
1186       if (--png_ptr->user_chunk_cache_max == 1)
1187       {
1188          png_warning(png_ptr, "No space in chunk cache for sPLT");
1189          png_crc_finish(png_ptr, length);
1190          return;
1191       }
1192    }
1193 #endif
1194 
1195    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1196       png_error(png_ptr, "Missing IHDR before sPLT");
1197    else if (png_ptr->mode & PNG_HAVE_IDAT)
1198    {
1199       png_warning(png_ptr, "Invalid sPLT after IDAT");
1200       png_crc_finish(png_ptr, length);
1201       return;
1202    }
1203 
1204 #ifdef PNG_MAX_MALLOC_64K
1205    if (length > (png_uint_32)65535L)
1206    {
1207       png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1208       skip = length - (png_uint_32)65535L;
1209       length = (png_uint_32)65535L;
1210    }
1211 #endif
1212 
1213    png_free(png_ptr, png_ptr->chunkdata);
1214    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1215    slength = (png_size_t)length;
1216    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1217 
1218    if (png_crc_finish(png_ptr, skip))
1219    {
1220       png_free(png_ptr, png_ptr->chunkdata);
1221       png_ptr->chunkdata = NULL;
1222       return;
1223    }
1224 
1225    png_ptr->chunkdata[slength] = 0x00;
1226 
1227    for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1228        entry_start++)
1229       /* Empty loop to find end of name */ ;
1230    ++entry_start;
1231 
1232    /* A sample depth should follow the separator, and we should be on it  */
1233    if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1234    {
1235       png_free(png_ptr, png_ptr->chunkdata);
1236       png_ptr->chunkdata = NULL;
1237       png_warning(png_ptr, "malformed sPLT chunk");
1238       return;
1239    }
1240 
1241    new_palette.depth = *entry_start++;
1242    entry_size = (new_palette.depth == 8 ? 6 : 10);
1243    data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
1244 
1245    /* Integrity-check the data length */
1246    if (data_length % entry_size)
1247    {
1248       png_free(png_ptr, png_ptr->chunkdata);
1249       png_ptr->chunkdata = NULL;
1250       png_warning(png_ptr, "sPLT chunk has bad length");
1251       return;
1252    }
1253 
1254    new_palette.nentries = (png_int_32) ( data_length / entry_size);
1255    if ((png_uint_32) new_palette.nentries >
1256        (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
1257    {
1258        png_warning(png_ptr, "sPLT chunk too long");
1259        return;
1260    }
1261    new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1262        png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1263    if (new_palette.entries == NULL)
1264    {
1265        png_warning(png_ptr, "sPLT chunk requires too much memory");
1266        return;
1267    }
1268 
1269 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1270    for (i = 0; i < new_palette.nentries; i++)
1271    {
1272       pp = new_palette.entries + i;
1273 
1274       if (new_palette.depth == 8)
1275       {
1276           pp->red = *entry_start++;
1277           pp->green = *entry_start++;
1278           pp->blue = *entry_start++;
1279           pp->alpha = *entry_start++;
1280       }
1281       else
1282       {
1283           pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1284           pp->green = png_get_uint_16(entry_start); entry_start += 2;
1285           pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1286           pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1287       }
1288       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1289    }
1290 #else
1291    pp = new_palette.entries;
1292    for (i = 0; i < new_palette.nentries; i++)
1293    {
1294 
1295       if (new_palette.depth == 8)
1296       {
1297           pp[i].red   = *entry_start++;
1298           pp[i].green = *entry_start++;
1299           pp[i].blue  = *entry_start++;
1300           pp[i].alpha = *entry_start++;
1301       }
1302       else
1303       {
1304           pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
1305           pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1306           pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
1307           pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1308       }
1309       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1310    }
1311 #endif
1312 
1313    /* Discard all chunk data except the name and stash that */
1314    new_palette.name = png_ptr->chunkdata;
1315 
1316    png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1317 
1318    png_free(png_ptr, png_ptr->chunkdata);
1319    png_ptr->chunkdata = NULL;
1320    png_free(png_ptr, new_palette.entries);
1321 }
1322 #endif /* PNG_READ_sPLT_SUPPORTED */
1323 
1324 #ifdef PNG_READ_tRNS_SUPPORTED
1325 void /* PRIVATE */
png_handle_tRNS(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1326 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1327 {
1328    png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1329 
1330    png_debug(1, "in png_handle_tRNS");
1331 
1332    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1333       png_error(png_ptr, "Missing IHDR before tRNS");
1334    else if (png_ptr->mode & PNG_HAVE_IDAT)
1335    {
1336       png_warning(png_ptr, "Invalid tRNS after IDAT");
1337       png_crc_finish(png_ptr, length);
1338       return;
1339    }
1340    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1341    {
1342       png_warning(png_ptr, "Duplicate tRNS chunk");
1343       png_crc_finish(png_ptr, length);
1344       return;
1345    }
1346 
1347    if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1348    {
1349       png_byte buf[2];
1350 
1351       if (length != 2)
1352       {
1353          png_warning(png_ptr, "Incorrect tRNS chunk length");
1354          png_crc_finish(png_ptr, length);
1355          return;
1356       }
1357 
1358       png_crc_read(png_ptr, buf, 2);
1359       png_ptr->num_trans = 1;
1360       png_ptr->trans_values.gray = png_get_uint_16(buf);
1361    }
1362    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1363    {
1364       png_byte buf[6];
1365 
1366       if (length != 6)
1367       {
1368          png_warning(png_ptr, "Incorrect tRNS chunk length");
1369          png_crc_finish(png_ptr, length);
1370          return;
1371       }
1372       png_crc_read(png_ptr, buf, (png_size_t)length);
1373       png_ptr->num_trans = 1;
1374       png_ptr->trans_values.red = png_get_uint_16(buf);
1375       png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1376       png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1377    }
1378    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1379    {
1380       if (!(png_ptr->mode & PNG_HAVE_PLTE))
1381       {
1382          /* Should be an error, but we can cope with it. */
1383          png_warning(png_ptr, "Missing PLTE before tRNS");
1384       }
1385       if (length > (png_uint_32)png_ptr->num_palette ||
1386           length > PNG_MAX_PALETTE_LENGTH)
1387       {
1388          png_warning(png_ptr, "Incorrect tRNS chunk length");
1389          png_crc_finish(png_ptr, length);
1390          return;
1391       }
1392       if (length == 0)
1393       {
1394          png_warning(png_ptr, "Zero length tRNS chunk");
1395          png_crc_finish(png_ptr, length);
1396          return;
1397       }
1398       png_crc_read(png_ptr, readbuf, (png_size_t)length);
1399       png_ptr->num_trans = (png_uint_16)length;
1400    }
1401    else
1402    {
1403       png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1404       png_crc_finish(png_ptr, length);
1405       return;
1406    }
1407 
1408    if (png_crc_finish(png_ptr, 0))
1409    {
1410       png_ptr->num_trans = 0;
1411       return;
1412    }
1413 
1414    png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1415       &(png_ptr->trans_values));
1416 }
1417 #endif
1418 
1419 #ifdef PNG_READ_bKGD_SUPPORTED
1420 void /* PRIVATE */
png_handle_bKGD(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1421 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1422 {
1423    png_size_t truelen;
1424    png_byte buf[6];
1425 
1426    png_debug(1, "in png_handle_bKGD");
1427 
1428    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1429       png_error(png_ptr, "Missing IHDR before bKGD");
1430    else if (png_ptr->mode & PNG_HAVE_IDAT)
1431    {
1432       png_warning(png_ptr, "Invalid bKGD after IDAT");
1433       png_crc_finish(png_ptr, length);
1434       return;
1435    }
1436    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1437             !(png_ptr->mode & PNG_HAVE_PLTE))
1438    {
1439       png_warning(png_ptr, "Missing PLTE before bKGD");
1440       png_crc_finish(png_ptr, length);
1441       return;
1442    }
1443    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1444    {
1445       png_warning(png_ptr, "Duplicate bKGD chunk");
1446       png_crc_finish(png_ptr, length);
1447       return;
1448    }
1449 
1450    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1451       truelen = 1;
1452    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1453       truelen = 6;
1454    else
1455       truelen = 2;
1456 
1457    if (length != truelen)
1458    {
1459       png_warning(png_ptr, "Incorrect bKGD chunk length");
1460       png_crc_finish(png_ptr, length);
1461       return;
1462    }
1463 
1464    png_crc_read(png_ptr, buf, truelen);
1465    if (png_crc_finish(png_ptr, 0))
1466       return;
1467 
1468    /* We convert the index value into RGB components so that we can allow
1469     * arbitrary RGB values for background when we have transparency, and
1470     * so it is easy to determine the RGB values of the background color
1471     * from the info_ptr struct. */
1472    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1473    {
1474       png_ptr->background.index = buf[0];
1475       if (info_ptr && info_ptr->num_palette)
1476       {
1477           if (buf[0] >= info_ptr->num_palette)
1478           {
1479              png_warning(png_ptr, "Incorrect bKGD chunk index value");
1480              return;
1481           }
1482           png_ptr->background.red =
1483              (png_uint_16)png_ptr->palette[buf[0]].red;
1484           png_ptr->background.green =
1485              (png_uint_16)png_ptr->palette[buf[0]].green;
1486           png_ptr->background.blue =
1487              (png_uint_16)png_ptr->palette[buf[0]].blue;
1488       }
1489    }
1490    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1491    {
1492       png_ptr->background.red =
1493       png_ptr->background.green =
1494       png_ptr->background.blue =
1495       png_ptr->background.gray = png_get_uint_16(buf);
1496    }
1497    else
1498    {
1499       png_ptr->background.red = png_get_uint_16(buf);
1500       png_ptr->background.green = png_get_uint_16(buf + 2);
1501       png_ptr->background.blue = png_get_uint_16(buf + 4);
1502    }
1503 
1504    png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1505 }
1506 #endif
1507 
1508 #ifdef PNG_READ_hIST_SUPPORTED
1509 void /* PRIVATE */
png_handle_hIST(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1510 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1511 {
1512    unsigned int num, i;
1513    png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1514 
1515    png_debug(1, "in png_handle_hIST");
1516 
1517    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1518       png_error(png_ptr, "Missing IHDR before hIST");
1519    else if (png_ptr->mode & PNG_HAVE_IDAT)
1520    {
1521       png_warning(png_ptr, "Invalid hIST after IDAT");
1522       png_crc_finish(png_ptr, length);
1523       return;
1524    }
1525    else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1526    {
1527       png_warning(png_ptr, "Missing PLTE before hIST");
1528       png_crc_finish(png_ptr, length);
1529       return;
1530    }
1531    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1532    {
1533       png_warning(png_ptr, "Duplicate hIST chunk");
1534       png_crc_finish(png_ptr, length);
1535       return;
1536    }
1537 
1538    num = length / 2 ;
1539    if (num != (unsigned int) png_ptr->num_palette || num >
1540       (unsigned int) PNG_MAX_PALETTE_LENGTH)
1541    {
1542       png_warning(png_ptr, "Incorrect hIST chunk length");
1543       png_crc_finish(png_ptr, length);
1544       return;
1545    }
1546 
1547    for (i = 0; i < num; i++)
1548    {
1549       png_byte buf[2];
1550 
1551       png_crc_read(png_ptr, buf, 2);
1552       readbuf[i] = png_get_uint_16(buf);
1553    }
1554 
1555    if (png_crc_finish(png_ptr, 0))
1556       return;
1557 
1558    png_set_hIST(png_ptr, info_ptr, readbuf);
1559 }
1560 #endif
1561 
1562 #ifdef PNG_READ_pHYs_SUPPORTED
1563 void /* PRIVATE */
png_handle_pHYs(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1564 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1565 {
1566    png_byte buf[9];
1567    png_uint_32 res_x, res_y;
1568    int unit_type;
1569 
1570    png_debug(1, "in png_handle_pHYs");
1571 
1572    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1573       png_error(png_ptr, "Missing IHDR before pHYs");
1574    else if (png_ptr->mode & PNG_HAVE_IDAT)
1575    {
1576       png_warning(png_ptr, "Invalid pHYs after IDAT");
1577       png_crc_finish(png_ptr, length);
1578       return;
1579    }
1580    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1581    {
1582       png_warning(png_ptr, "Duplicate pHYs chunk");
1583       png_crc_finish(png_ptr, length);
1584       return;
1585    }
1586 
1587    if (length != 9)
1588    {
1589       png_warning(png_ptr, "Incorrect pHYs chunk length");
1590       png_crc_finish(png_ptr, length);
1591       return;
1592    }
1593 
1594    png_crc_read(png_ptr, buf, 9);
1595    if (png_crc_finish(png_ptr, 0))
1596       return;
1597 
1598    res_x = png_get_uint_32(buf);
1599    res_y = png_get_uint_32(buf + 4);
1600    unit_type = buf[8];
1601    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1602 }
1603 #endif
1604 
1605 #ifdef PNG_READ_oFFs_SUPPORTED
1606 void /* PRIVATE */
png_handle_oFFs(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1607 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1608 {
1609    png_byte buf[9];
1610    png_int_32 offset_x, offset_y;
1611    int unit_type;
1612 
1613    png_debug(1, "in png_handle_oFFs");
1614 
1615    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1616       png_error(png_ptr, "Missing IHDR before oFFs");
1617    else if (png_ptr->mode & PNG_HAVE_IDAT)
1618    {
1619       png_warning(png_ptr, "Invalid oFFs after IDAT");
1620       png_crc_finish(png_ptr, length);
1621       return;
1622    }
1623    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1624    {
1625       png_warning(png_ptr, "Duplicate oFFs chunk");
1626       png_crc_finish(png_ptr, length);
1627       return;
1628    }
1629 
1630    if (length != 9)
1631    {
1632       png_warning(png_ptr, "Incorrect oFFs chunk length");
1633       png_crc_finish(png_ptr, length);
1634       return;
1635    }
1636 
1637    png_crc_read(png_ptr, buf, 9);
1638    if (png_crc_finish(png_ptr, 0))
1639       return;
1640 
1641    offset_x = png_get_int_32(buf);
1642    offset_y = png_get_int_32(buf + 4);
1643    unit_type = buf[8];
1644    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1645 }
1646 #endif
1647 
1648 #ifdef PNG_READ_pCAL_SUPPORTED
1649 /* Read the pCAL chunk (described in the PNG Extensions document) */
1650 void /* PRIVATE */
png_handle_pCAL(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1651 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1652 {
1653    png_int_32 X0, X1;
1654    png_byte type, nparams;
1655    png_charp buf, units, endptr;
1656    png_charpp params;
1657    png_size_t slength;
1658    int i;
1659 
1660    png_debug(1, "in png_handle_pCAL");
1661 
1662    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1663       png_error(png_ptr, "Missing IHDR before pCAL");
1664    else if (png_ptr->mode & PNG_HAVE_IDAT)
1665    {
1666       png_warning(png_ptr, "Invalid pCAL after IDAT");
1667       png_crc_finish(png_ptr, length);
1668       return;
1669    }
1670    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1671    {
1672       png_warning(png_ptr, "Duplicate pCAL chunk");
1673       png_crc_finish(png_ptr, length);
1674       return;
1675    }
1676 
1677    png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1678       length + 1);
1679    png_free(png_ptr, png_ptr->chunkdata);
1680    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1681    if (png_ptr->chunkdata == NULL)
1682      {
1683        png_warning(png_ptr, "No memory for pCAL purpose.");
1684        return;
1685      }
1686    slength = (png_size_t)length;
1687    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1688 
1689    if (png_crc_finish(png_ptr, 0))
1690    {
1691       png_free(png_ptr, png_ptr->chunkdata);
1692       png_ptr->chunkdata = NULL;
1693       return;
1694    }
1695 
1696    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1697 
1698    png_debug(3, "Finding end of pCAL purpose string");
1699    for (buf = png_ptr->chunkdata; *buf; buf++)
1700       /* Empty loop */ ;
1701 
1702    endptr = png_ptr->chunkdata + slength;
1703 
1704    /* We need to have at least 12 bytes after the purpose string
1705       in order to get the parameter information. */
1706    if (endptr <= buf + 12)
1707    {
1708       png_warning(png_ptr, "Invalid pCAL data");
1709       png_free(png_ptr, png_ptr->chunkdata);
1710       png_ptr->chunkdata = NULL;
1711       return;
1712    }
1713 
1714    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1715    X0 = png_get_int_32((png_bytep)buf+1);
1716    X1 = png_get_int_32((png_bytep)buf+5);
1717    type = buf[9];
1718    nparams = buf[10];
1719    units = buf + 11;
1720 
1721    png_debug(3, "Checking pCAL equation type and number of parameters");
1722    /* Check that we have the right number of parameters for known
1723       equation types. */
1724    if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1725        (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1726        (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1727        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1728    {
1729       png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1730       png_free(png_ptr, png_ptr->chunkdata);
1731       png_ptr->chunkdata = NULL;
1732       return;
1733    }
1734    else if (type >= PNG_EQUATION_LAST)
1735    {
1736       png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1737    }
1738 
1739    for (buf = units; *buf; buf++)
1740       /* Empty loop to move past the units string. */ ;
1741 
1742    png_debug(3, "Allocating pCAL parameters array");
1743    params = (png_charpp)png_malloc_warn(png_ptr,
1744       (png_uint_32)(nparams * png_sizeof(png_charp))) ;
1745    if (params == NULL)
1746      {
1747        png_free(png_ptr, png_ptr->chunkdata);
1748        png_ptr->chunkdata = NULL;
1749        png_warning(png_ptr, "No memory for pCAL params.");
1750        return;
1751      }
1752 
1753    /* Get pointers to the start of each parameter string. */
1754    for (i = 0; i < (int)nparams; i++)
1755    {
1756       buf++; /* Skip the null string terminator from previous parameter. */
1757 
1758       png_debug1(3, "Reading pCAL parameter %d", i);
1759       for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1760          /* Empty loop to move past each parameter string */ ;
1761 
1762       /* Make sure we haven't run out of data yet */
1763       if (buf > endptr)
1764       {
1765          png_warning(png_ptr, "Invalid pCAL data");
1766          png_free(png_ptr, png_ptr->chunkdata);
1767          png_ptr->chunkdata = NULL;
1768          png_free(png_ptr, params);
1769          return;
1770       }
1771    }
1772 
1773    png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
1774       units, params);
1775 
1776    png_free(png_ptr, png_ptr->chunkdata);
1777    png_ptr->chunkdata = NULL;
1778    png_free(png_ptr, params);
1779 }
1780 #endif
1781 
1782 #ifdef PNG_READ_sCAL_SUPPORTED
1783 /* Read the sCAL chunk */
1784 void /* PRIVATE */
png_handle_sCAL(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1785 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1786 {
1787    png_charp ep;
1788 #ifdef PNG_FLOATING_POINT_SUPPORTED
1789    double width, height;
1790    png_charp vp;
1791 #else
1792 #ifdef PNG_FIXED_POINT_SUPPORTED
1793    png_charp swidth, sheight;
1794 #endif
1795 #endif
1796    png_size_t slength;
1797 
1798    png_debug(1, "in png_handle_sCAL");
1799 
1800    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1801       png_error(png_ptr, "Missing IHDR before sCAL");
1802    else if (png_ptr->mode & PNG_HAVE_IDAT)
1803    {
1804       png_warning(png_ptr, "Invalid sCAL after IDAT");
1805       png_crc_finish(png_ptr, length);
1806       return;
1807    }
1808    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1809    {
1810       png_warning(png_ptr, "Duplicate sCAL chunk");
1811       png_crc_finish(png_ptr, length);
1812       return;
1813    }
1814 
1815    png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1816       length + 1);
1817    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1818    if (png_ptr->chunkdata == NULL)
1819    {
1820       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1821       png_crc_finish(png_ptr, length);
1822       return;
1823    }
1824    slength = (png_size_t)length;
1825    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1826 
1827    if (png_crc_finish(png_ptr, 0))
1828    {
1829       png_free(png_ptr, png_ptr->chunkdata);
1830       png_ptr->chunkdata = NULL;
1831       return;
1832    }
1833 
1834    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1835 
1836    ep = png_ptr->chunkdata + 1;        /* Skip unit byte */
1837 
1838 #ifdef PNG_FLOATING_POINT_SUPPORTED
1839    width = png_strtod(png_ptr, ep, &vp);
1840    if (*vp)
1841    {
1842       png_warning(png_ptr, "malformed width string in sCAL chunk");
1843       png_free(png_ptr, png_ptr->chunkdata);
1844       png_ptr->chunkdata = NULL;
1845       return;
1846    }
1847 #else
1848 #ifdef PNG_FIXED_POINT_SUPPORTED
1849    swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1850    if (swidth == NULL)
1851    {
1852       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1853       png_free(png_ptr, png_ptr->chunkdata);
1854       png_ptr->chunkdata = NULL;
1855       return;
1856    }
1857    png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1858 #endif
1859 #endif
1860 
1861    for (ep = png_ptr->chunkdata; *ep; ep++)
1862       /* Empty loop */ ;
1863    ep++;
1864 
1865    if (png_ptr->chunkdata + slength < ep)
1866    {
1867       png_warning(png_ptr, "Truncated sCAL chunk");
1868 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1869       png_free(png_ptr, swidth);
1870 #endif
1871       png_free(png_ptr, png_ptr->chunkdata);
1872       png_ptr->chunkdata = NULL;
1873       return;
1874    }
1875 
1876 #ifdef PNG_FLOATING_POINT_SUPPORTED
1877    height = png_strtod(png_ptr, ep, &vp);
1878    if (*vp)
1879    {
1880       png_warning(png_ptr, "malformed height string in sCAL chunk");
1881       png_free(png_ptr, png_ptr->chunkdata);
1882       png_ptr->chunkdata = NULL;
1883 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1884       png_free(png_ptr, swidth);
1885 #endif
1886       return;
1887    }
1888 #else
1889 #ifdef PNG_FIXED_POINT_SUPPORTED
1890    sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1891    if (sheight == NULL)
1892    {
1893       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1894       png_free(png_ptr, png_ptr->chunkdata);
1895       png_ptr->chunkdata = NULL;
1896 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1897       png_free(png_ptr, swidth);
1898 #endif
1899       return;
1900    }
1901    png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1902 #endif
1903 #endif
1904 
1905    if (png_ptr->chunkdata + slength < ep
1906 #ifdef PNG_FLOATING_POINT_SUPPORTED
1907       || width <= 0. || height <= 0.
1908 #endif
1909       )
1910    {
1911       png_warning(png_ptr, "Invalid sCAL data");
1912       png_free(png_ptr, png_ptr->chunkdata);
1913       png_ptr->chunkdata = NULL;
1914 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1915       png_free(png_ptr, swidth);
1916       png_free(png_ptr, sheight);
1917 #endif
1918       return;
1919    }
1920 
1921 
1922 #ifdef PNG_FLOATING_POINT_SUPPORTED
1923    png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
1924 #else
1925 #ifdef PNG_FIXED_POINT_SUPPORTED
1926    png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
1927 #endif
1928 #endif
1929 
1930    png_free(png_ptr, png_ptr->chunkdata);
1931    png_ptr->chunkdata = NULL;
1932 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1933    png_free(png_ptr, swidth);
1934    png_free(png_ptr, sheight);
1935 #endif
1936 }
1937 #endif
1938 
1939 #ifdef PNG_READ_tIME_SUPPORTED
1940 void /* PRIVATE */
png_handle_tIME(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1941 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1942 {
1943    png_byte buf[7];
1944    png_time mod_time;
1945 
1946    png_debug(1, "in png_handle_tIME");
1947 
1948    if (!(png_ptr->mode & PNG_HAVE_IHDR))
1949       png_error(png_ptr, "Out of place tIME chunk");
1950    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1951    {
1952       png_warning(png_ptr, "Duplicate tIME chunk");
1953       png_crc_finish(png_ptr, length);
1954       return;
1955    }
1956 
1957    if (png_ptr->mode & PNG_HAVE_IDAT)
1958       png_ptr->mode |= PNG_AFTER_IDAT;
1959 
1960    if (length != 7)
1961    {
1962       png_warning(png_ptr, "Incorrect tIME chunk length");
1963       png_crc_finish(png_ptr, length);
1964       return;
1965    }
1966 
1967    png_crc_read(png_ptr, buf, 7);
1968    if (png_crc_finish(png_ptr, 0))
1969       return;
1970 
1971    mod_time.second = buf[6];
1972    mod_time.minute = buf[5];
1973    mod_time.hour = buf[4];
1974    mod_time.day = buf[3];
1975    mod_time.month = buf[2];
1976    mod_time.year = png_get_uint_16(buf);
1977 
1978    png_set_tIME(png_ptr, info_ptr, &mod_time);
1979 }
1980 #endif
1981 
1982 #ifdef PNG_READ_tEXt_SUPPORTED
1983 /* Note: this does not properly handle chunks that are > 64K under DOS */
1984 void /* PRIVATE */
png_handle_tEXt(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1985 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1986 {
1987    png_textp text_ptr;
1988    png_charp key;
1989    png_charp text;
1990    png_uint_32 skip = 0;
1991    png_size_t slength;
1992    int ret;
1993 
1994    png_debug(1, "in png_handle_tEXt");
1995 
1996 #ifdef PNG_USER_LIMITS_SUPPORTED
1997    if (png_ptr->user_chunk_cache_max != 0)
1998    {
1999       if (png_ptr->user_chunk_cache_max == 1)
2000       {
2001          png_crc_finish(png_ptr, length);
2002          return;
2003       }
2004       if (--png_ptr->user_chunk_cache_max == 1)
2005       {
2006          png_warning(png_ptr, "No space in chunk cache for tEXt");
2007          png_crc_finish(png_ptr, length);
2008          return;
2009       }
2010    }
2011 #endif
2012 
2013    if (!(png_ptr->mode & PNG_HAVE_IHDR))
2014       png_error(png_ptr, "Missing IHDR before tEXt");
2015 
2016    if (png_ptr->mode & PNG_HAVE_IDAT)
2017       png_ptr->mode |= PNG_AFTER_IDAT;
2018 
2019 #ifdef PNG_MAX_MALLOC_64K
2020    if (length > (png_uint_32)65535L)
2021    {
2022       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2023       skip = length - (png_uint_32)65535L;
2024       length = (png_uint_32)65535L;
2025    }
2026 #endif
2027 
2028    png_free(png_ptr, png_ptr->chunkdata);
2029 
2030    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2031    if (png_ptr->chunkdata == NULL)
2032    {
2033      png_warning(png_ptr, "No memory to process text chunk.");
2034      return;
2035    }
2036    slength = (png_size_t)length;
2037    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2038 
2039    if (png_crc_finish(png_ptr, skip))
2040    {
2041       png_free(png_ptr, png_ptr->chunkdata);
2042       png_ptr->chunkdata = NULL;
2043       return;
2044    }
2045 
2046    key = png_ptr->chunkdata;
2047 
2048    key[slength] = 0x00;
2049 
2050    for (text = key; *text; text++)
2051       /* Empty loop to find end of key */ ;
2052 
2053    if (text != key + slength)
2054       text++;
2055 
2056    text_ptr = (png_textp)png_malloc_warn(png_ptr,
2057       (png_uint_32)png_sizeof(png_text));
2058    if (text_ptr == NULL)
2059    {
2060      png_warning(png_ptr, "Not enough memory to process text chunk.");
2061      png_free(png_ptr, png_ptr->chunkdata);
2062      png_ptr->chunkdata = NULL;
2063      return;
2064    }
2065    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2066    text_ptr->key = key;
2067 #ifdef PNG_iTXt_SUPPORTED
2068    text_ptr->lang = NULL;
2069    text_ptr->lang_key = NULL;
2070    text_ptr->itxt_length = 0;
2071 #endif
2072    text_ptr->text = text;
2073    text_ptr->text_length = png_strlen(text);
2074 
2075    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2076 
2077    png_free(png_ptr, png_ptr->chunkdata);
2078    png_ptr->chunkdata = NULL;
2079    png_free(png_ptr, text_ptr);
2080    if (ret)
2081      png_warning(png_ptr, "Insufficient memory to process text chunk.");
2082 }
2083 #endif
2084 
2085 #ifdef PNG_READ_zTXt_SUPPORTED
2086 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2087 void /* PRIVATE */
png_handle_zTXt(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)2088 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2089 {
2090    png_textp text_ptr;
2091    png_charp text;
2092    int comp_type;
2093    int ret;
2094    png_size_t slength, prefix_len, data_len;
2095 
2096    png_debug(1, "in png_handle_zTXt");
2097 
2098 #ifdef PNG_USER_LIMITS_SUPPORTED
2099    if (png_ptr->user_chunk_cache_max != 0)
2100    {
2101       if (png_ptr->user_chunk_cache_max == 1)
2102       {
2103          png_crc_finish(png_ptr, length);
2104          return;
2105       }
2106       if (--png_ptr->user_chunk_cache_max == 1)
2107       {
2108          png_warning(png_ptr, "No space in chunk cache for zTXt");
2109          png_crc_finish(png_ptr, length);
2110          return;
2111       }
2112    }
2113 #endif
2114 
2115    if (!(png_ptr->mode & PNG_HAVE_IHDR))
2116       png_error(png_ptr, "Missing IHDR before zTXt");
2117 
2118    if (png_ptr->mode & PNG_HAVE_IDAT)
2119       png_ptr->mode |= PNG_AFTER_IDAT;
2120 
2121 #ifdef PNG_MAX_MALLOC_64K
2122    /* We will no doubt have problems with chunks even half this size, but
2123       there is no hard and fast rule to tell us where to stop. */
2124    if (length > (png_uint_32)65535L)
2125    {
2126      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2127      png_crc_finish(png_ptr, length);
2128      return;
2129    }
2130 #endif
2131 
2132    png_free(png_ptr, png_ptr->chunkdata);
2133    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2134    if (png_ptr->chunkdata == NULL)
2135    {
2136      png_warning(png_ptr, "Out of memory processing zTXt chunk.");
2137      return;
2138    }
2139    slength = (png_size_t)length;
2140    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2141    if (png_crc_finish(png_ptr, 0))
2142    {
2143       png_free(png_ptr, png_ptr->chunkdata);
2144       png_ptr->chunkdata = NULL;
2145       return;
2146    }
2147 
2148    png_ptr->chunkdata[slength] = 0x00;
2149 
2150    for (text = png_ptr->chunkdata; *text; text++)
2151       /* Empty loop */ ;
2152 
2153    /* zTXt must have some text after the chunkdataword */
2154    if (text >= png_ptr->chunkdata + slength - 2)
2155    {
2156       png_warning(png_ptr, "Truncated zTXt chunk");
2157       png_free(png_ptr, png_ptr->chunkdata);
2158       png_ptr->chunkdata = NULL;
2159       return;
2160    }
2161    else
2162    {
2163        comp_type = *(++text);
2164        if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2165        {
2166           png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2167           comp_type = PNG_TEXT_COMPRESSION_zTXt;
2168        }
2169        text++;        /* Skip the compression_method byte */
2170    }
2171    prefix_len = text - png_ptr->chunkdata;
2172 
2173    png_decompress_chunk(png_ptr, comp_type,
2174      (png_size_t)length, prefix_len, &data_len);
2175 
2176    text_ptr = (png_textp)png_malloc_warn(png_ptr,
2177       (png_uint_32)png_sizeof(png_text));
2178    if (text_ptr == NULL)
2179    {
2180      png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
2181      png_free(png_ptr, png_ptr->chunkdata);
2182      png_ptr->chunkdata = NULL;
2183      return;
2184    }
2185    text_ptr->compression = comp_type;
2186    text_ptr->key = png_ptr->chunkdata;
2187 #ifdef PNG_iTXt_SUPPORTED
2188    text_ptr->lang = NULL;
2189    text_ptr->lang_key = NULL;
2190    text_ptr->itxt_length = 0;
2191 #endif
2192    text_ptr->text = png_ptr->chunkdata + prefix_len;
2193    text_ptr->text_length = data_len;
2194 
2195    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2196 
2197    png_free(png_ptr, text_ptr);
2198    png_free(png_ptr, png_ptr->chunkdata);
2199    png_ptr->chunkdata = NULL;
2200    if (ret)
2201      png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2202 }
2203 #endif
2204 
2205 #ifdef PNG_READ_iTXt_SUPPORTED
2206 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2207 void /* PRIVATE */
png_handle_iTXt(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)2208 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2209 {
2210    png_textp text_ptr;
2211    png_charp key, lang, text, lang_key;
2212    int comp_flag;
2213    int comp_type = 0;
2214    int ret;
2215    png_size_t slength, prefix_len, data_len;
2216 
2217    png_debug(1, "in png_handle_iTXt");
2218 
2219 #ifdef PNG_USER_LIMITS_SUPPORTED
2220    if (png_ptr->user_chunk_cache_max != 0)
2221    {
2222       if (png_ptr->user_chunk_cache_max == 1)
2223       {
2224          png_crc_finish(png_ptr, length);
2225          return;
2226       }
2227       if (--png_ptr->user_chunk_cache_max == 1)
2228       {
2229          png_warning(png_ptr, "No space in chunk cache for iTXt");
2230          png_crc_finish(png_ptr, length);
2231          return;
2232       }
2233    }
2234 #endif
2235 
2236    if (!(png_ptr->mode & PNG_HAVE_IHDR))
2237       png_error(png_ptr, "Missing IHDR before iTXt");
2238 
2239    if (png_ptr->mode & PNG_HAVE_IDAT)
2240       png_ptr->mode |= PNG_AFTER_IDAT;
2241 
2242 #ifdef PNG_MAX_MALLOC_64K
2243    /* We will no doubt have problems with chunks even half this size, but
2244       there is no hard and fast rule to tell us where to stop. */
2245    if (length > (png_uint_32)65535L)
2246    {
2247      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2248      png_crc_finish(png_ptr, length);
2249      return;
2250    }
2251 #endif
2252 
2253    png_free(png_ptr, png_ptr->chunkdata);
2254    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2255    if (png_ptr->chunkdata == NULL)
2256    {
2257      png_warning(png_ptr, "No memory to process iTXt chunk.");
2258      return;
2259    }
2260    slength = (png_size_t)length;
2261    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2262    if (png_crc_finish(png_ptr, 0))
2263    {
2264       png_free(png_ptr, png_ptr->chunkdata);
2265       png_ptr->chunkdata = NULL;
2266       return;
2267    }
2268 
2269    png_ptr->chunkdata[slength] = 0x00;
2270 
2271    for (lang = png_ptr->chunkdata; *lang; lang++)
2272       /* Empty loop */ ;
2273    lang++;        /* Skip NUL separator */
2274 
2275    /* iTXt must have a language tag (possibly empty), two compression bytes,
2276     * translated keyword (possibly empty), and possibly some text after the
2277     * keyword
2278     */
2279 
2280    if (lang >= png_ptr->chunkdata + slength - 3)
2281    {
2282       png_warning(png_ptr, "Truncated iTXt chunk");
2283       png_free(png_ptr, png_ptr->chunkdata);
2284       png_ptr->chunkdata = NULL;
2285       return;
2286    }
2287    else
2288    {
2289        comp_flag = *lang++;
2290        comp_type = *lang++;
2291    }
2292 
2293    for (lang_key = lang; *lang_key; lang_key++)
2294       /* Empty loop */ ;
2295    lang_key++;        /* Skip NUL separator */
2296 
2297    if (lang_key >= png_ptr->chunkdata + slength)
2298    {
2299       png_warning(png_ptr, "Truncated iTXt chunk");
2300       png_free(png_ptr, png_ptr->chunkdata);
2301       png_ptr->chunkdata = NULL;
2302       return;
2303    }
2304 
2305    for (text = lang_key; *text; text++)
2306       /* Empty loop */ ;
2307    text++;        /* Skip NUL separator */
2308    if (text >= png_ptr->chunkdata + slength)
2309    {
2310       png_warning(png_ptr, "Malformed iTXt chunk");
2311       png_free(png_ptr, png_ptr->chunkdata);
2312       png_ptr->chunkdata = NULL;
2313       return;
2314    }
2315 
2316    prefix_len = text - png_ptr->chunkdata;
2317 
2318    key=png_ptr->chunkdata;
2319    if (comp_flag)
2320        png_decompress_chunk(png_ptr, comp_type,
2321          (size_t)length, prefix_len, &data_len);
2322    else
2323        data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2324    text_ptr = (png_textp)png_malloc_warn(png_ptr,
2325       (png_uint_32)png_sizeof(png_text));
2326    if (text_ptr == NULL)
2327    {
2328      png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
2329      png_free(png_ptr, png_ptr->chunkdata);
2330      png_ptr->chunkdata = NULL;
2331      return;
2332    }
2333    text_ptr->compression = (int)comp_flag + 1;
2334    text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2335    text_ptr->lang = png_ptr->chunkdata + (lang - key);
2336    text_ptr->itxt_length = data_len;
2337    text_ptr->text_length = 0;
2338    text_ptr->key = png_ptr->chunkdata;
2339    text_ptr->text = png_ptr->chunkdata + prefix_len;
2340 
2341    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2342 
2343    png_free(png_ptr, text_ptr);
2344    png_free(png_ptr, png_ptr->chunkdata);
2345    png_ptr->chunkdata = NULL;
2346    if (ret)
2347      png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2348 }
2349 #endif
2350 
2351 /* This function is called when we haven't found a handler for a
2352    chunk.  If there isn't a problem with the chunk itself (ie bad
2353    chunk name, CRC, or a critical chunk), the chunk is silently ignored
2354    -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2355    case it will be saved away to be written out later. */
2356 void /* PRIVATE */
png_handle_unknown(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)2357 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2358 {
2359    png_uint_32 skip = 0;
2360 
2361    png_debug(1, "in png_handle_unknown");
2362 
2363 #ifdef PNG_USER_LIMITS_SUPPORTED
2364    if (png_ptr->user_chunk_cache_max != 0)
2365    {
2366       if (png_ptr->user_chunk_cache_max == 1)
2367       {
2368          png_crc_finish(png_ptr, length);
2369          return;
2370       }
2371       if (--png_ptr->user_chunk_cache_max == 1)
2372       {
2373          png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2374          png_crc_finish(png_ptr, length);
2375          return;
2376       }
2377    }
2378 #endif
2379 
2380    if (png_ptr->mode & PNG_HAVE_IDAT)
2381    {
2382 #ifdef PNG_USE_LOCAL_ARRAYS
2383       PNG_CONST PNG_IDAT;
2384 #endif
2385       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
2386          png_ptr->mode |= PNG_AFTER_IDAT;
2387    }
2388 
2389    if (!(png_ptr->chunk_name[0] & 0x20))
2390    {
2391 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2392       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2393            PNG_HANDLE_CHUNK_ALWAYS
2394 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2395            && png_ptr->read_user_chunk_fn == NULL
2396 #endif
2397         )
2398 #endif
2399           png_chunk_error(png_ptr, "unknown critical chunk");
2400    }
2401 
2402 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2403    if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2404 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2405        || (png_ptr->read_user_chunk_fn != NULL)
2406 #endif
2407         )
2408    {
2409 #ifdef PNG_MAX_MALLOC_64K
2410        if (length > (png_uint_32)65535L)
2411        {
2412            png_warning(png_ptr, "unknown chunk too large to fit in memory");
2413            skip = length - (png_uint_32)65535L;
2414            length = (png_uint_32)65535L;
2415        }
2416 #endif
2417        png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2418                   (png_charp)png_ptr->chunk_name,
2419                   png_sizeof(png_ptr->unknown_chunk.name));
2420        png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
2421            = '\0';
2422        png_ptr->unknown_chunk.size = (png_size_t)length;
2423        if (length == 0)
2424          png_ptr->unknown_chunk.data = NULL;
2425        else
2426        {
2427          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2428          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2429        }
2430 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2431        if (png_ptr->read_user_chunk_fn != NULL)
2432        {
2433           /* Callback to user unknown chunk handler */
2434           int ret;
2435           ret = (*(png_ptr->read_user_chunk_fn))
2436             (png_ptr, &png_ptr->unknown_chunk);
2437           if (ret < 0)
2438              png_chunk_error(png_ptr, "error in user chunk");
2439           if (ret == 0)
2440           {
2441              if (!(png_ptr->chunk_name[0] & 0x20))
2442 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2443                 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2444                      PNG_HANDLE_CHUNK_ALWAYS)
2445 #endif
2446                    png_chunk_error(png_ptr, "unknown critical chunk");
2447              png_set_unknown_chunks(png_ptr, info_ptr,
2448                &png_ptr->unknown_chunk, 1);
2449           }
2450        }
2451        else
2452 #endif
2453        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2454        png_free(png_ptr, png_ptr->unknown_chunk.data);
2455        png_ptr->unknown_chunk.data = NULL;
2456    }
2457    else
2458 #endif
2459       skip = length;
2460 
2461    png_crc_finish(png_ptr, skip);
2462 
2463 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2464    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
2465 #endif
2466 }
2467 
2468 /* This function is called to verify that a chunk name is valid.
2469    This function can't have the "critical chunk check" incorporated
2470    into it, since in the future we will need to be able to call user
2471    functions to handle unknown critical chunks after we check that
2472    the chunk name itself is valid. */
2473 
2474 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2475 
2476 void /* PRIVATE */
png_check_chunk_name(png_structp png_ptr,png_bytep chunk_name)2477 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2478 {
2479    png_debug(1, "in png_check_chunk_name");
2480    if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2481        isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2482    {
2483       png_chunk_error(png_ptr, "invalid chunk type");
2484    }
2485 }
2486 
2487 /* Combines the row recently read in with the existing pixels in the
2488    row.  This routine takes care of alpha and transparency if requested.
2489    This routine also handles the two methods of progressive display
2490    of interlaced images, depending on the mask value.
2491    The mask value describes which pixels are to be combined with
2492    the row.  The pattern always repeats every 8 pixels, so just 8
2493    bits are needed.  A one indicates the pixel is to be combined,
2494    a zero indicates the pixel is to be skipped.  This is in addition
2495    to any alpha or transparency value associated with the pixel.  If
2496    you want all pixels to be combined, pass 0xff (255) in mask.  */
2497 
2498 void /* PRIVATE */
png_combine_row(png_structp png_ptr,png_bytep row,int mask)2499 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2500 {
2501    png_debug(1, "in png_combine_row");
2502    if (mask == 0xff)
2503    {
2504       png_memcpy(row, png_ptr->row_buf + 1,
2505          PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2506    }
2507    else
2508    {
2509       switch (png_ptr->row_info.pixel_depth)
2510       {
2511          case 1:
2512          {
2513             png_bytep sp = png_ptr->row_buf + 1;
2514             png_bytep dp = row;
2515             int s_inc, s_start, s_end;
2516             int m = 0x80;
2517             int shift;
2518             png_uint_32 i;
2519             png_uint_32 row_width = png_ptr->width;
2520 
2521 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2522             if (png_ptr->transformations & PNG_PACKSWAP)
2523             {
2524                 s_start = 0;
2525                 s_end = 7;
2526                 s_inc = 1;
2527             }
2528             else
2529 #endif
2530             {
2531                 s_start = 7;
2532                 s_end = 0;
2533                 s_inc = -1;
2534             }
2535 
2536             shift = s_start;
2537 
2538             for (i = 0; i < row_width; i++)
2539             {
2540                if (m & mask)
2541                {
2542                   int value;
2543 
2544                   value = (*sp >> shift) & 0x01;
2545                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2546                   *dp |= (png_byte)(value << shift);
2547                }
2548 
2549                if (shift == s_end)
2550                {
2551                   shift = s_start;
2552                   sp++;
2553                   dp++;
2554                }
2555                else
2556                   shift += s_inc;
2557 
2558                if (m == 1)
2559                   m = 0x80;
2560                else
2561                   m >>= 1;
2562             }
2563             break;
2564          }
2565          case 2:
2566          {
2567             png_bytep sp = png_ptr->row_buf + 1;
2568             png_bytep dp = row;
2569             int s_start, s_end, s_inc;
2570             int m = 0x80;
2571             int shift;
2572             png_uint_32 i;
2573             png_uint_32 row_width = png_ptr->width;
2574             int value;
2575 
2576 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2577             if (png_ptr->transformations & PNG_PACKSWAP)
2578             {
2579                s_start = 0;
2580                s_end = 6;
2581                s_inc = 2;
2582             }
2583             else
2584 #endif
2585             {
2586                s_start = 6;
2587                s_end = 0;
2588                s_inc = -2;
2589             }
2590 
2591             shift = s_start;
2592 
2593             for (i = 0; i < row_width; i++)
2594             {
2595                if (m & mask)
2596                {
2597                   value = (*sp >> shift) & 0x03;
2598                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2599                   *dp |= (png_byte)(value << shift);
2600                }
2601 
2602                if (shift == s_end)
2603                {
2604                   shift = s_start;
2605                   sp++;
2606                   dp++;
2607                }
2608                else
2609                   shift += s_inc;
2610                if (m == 1)
2611                   m = 0x80;
2612                else
2613                   m >>= 1;
2614             }
2615             break;
2616          }
2617          case 4:
2618          {
2619             png_bytep sp = png_ptr->row_buf + 1;
2620             png_bytep dp = row;
2621             int s_start, s_end, s_inc;
2622             int m = 0x80;
2623             int shift;
2624             png_uint_32 i;
2625             png_uint_32 row_width = png_ptr->width;
2626             int value;
2627 
2628 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2629             if (png_ptr->transformations & PNG_PACKSWAP)
2630             {
2631                s_start = 0;
2632                s_end = 4;
2633                s_inc = 4;
2634             }
2635             else
2636 #endif
2637             {
2638                s_start = 4;
2639                s_end = 0;
2640                s_inc = -4;
2641             }
2642             shift = s_start;
2643 
2644             for (i = 0; i < row_width; i++)
2645             {
2646                if (m & mask)
2647                {
2648                   value = (*sp >> shift) & 0xf;
2649                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2650                   *dp |= (png_byte)(value << shift);
2651                }
2652 
2653                if (shift == s_end)
2654                {
2655                   shift = s_start;
2656                   sp++;
2657                   dp++;
2658                }
2659                else
2660                   shift += s_inc;
2661                if (m == 1)
2662                   m = 0x80;
2663                else
2664                   m >>= 1;
2665             }
2666             break;
2667          }
2668          default:
2669          {
2670             png_bytep sp = png_ptr->row_buf + 1;
2671             png_bytep dp = row;
2672             png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2673             png_uint_32 i;
2674             png_uint_32 row_width = png_ptr->width;
2675             png_byte m = 0x80;
2676 
2677 
2678             for (i = 0; i < row_width; i++)
2679             {
2680                if (m & mask)
2681                {
2682                   png_memcpy(dp, sp, pixel_bytes);
2683                }
2684 
2685                sp += pixel_bytes;
2686                dp += pixel_bytes;
2687 
2688                if (m == 1)
2689                   m = 0x80;
2690                else
2691                   m >>= 1;
2692             }
2693             break;
2694          }
2695       }
2696    }
2697 }
2698 
2699 #ifdef PNG_READ_INTERLACING_SUPPORTED
2700 /* OLD pre-1.0.9 interface:
2701 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2702    png_uint_32 transformations)
2703  */
2704 void /* PRIVATE */
png_do_read_interlace(png_structp png_ptr)2705 png_do_read_interlace(png_structp png_ptr)
2706 {
2707    png_row_infop row_info = &(png_ptr->row_info);
2708    png_bytep row = png_ptr->row_buf + 1;
2709    int pass = png_ptr->pass;
2710    png_uint_32 transformations = png_ptr->transformations;
2711    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2712    /* Offset to next interlace block */
2713    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2714 
2715    png_debug(1, "in png_do_read_interlace");
2716    if (row != NULL && row_info != NULL)
2717    {
2718       png_uint_32 final_width;
2719 
2720       final_width = row_info->width * png_pass_inc[pass];
2721 
2722       switch (row_info->pixel_depth)
2723       {
2724          case 1:
2725          {
2726             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2727             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2728             int sshift, dshift;
2729             int s_start, s_end, s_inc;
2730             int jstop = png_pass_inc[pass];
2731             png_byte v;
2732             png_uint_32 i;
2733             int j;
2734 
2735 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2736             if (transformations & PNG_PACKSWAP)
2737             {
2738                 sshift = (int)((row_info->width + 7) & 0x07);
2739                 dshift = (int)((final_width + 7) & 0x07);
2740                 s_start = 7;
2741                 s_end = 0;
2742                 s_inc = -1;
2743             }
2744             else
2745 #endif
2746             {
2747                 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2748                 dshift = 7 - (int)((final_width + 7) & 0x07);
2749                 s_start = 0;
2750                 s_end = 7;
2751                 s_inc = 1;
2752             }
2753 
2754             for (i = 0; i < row_info->width; i++)
2755             {
2756                v = (png_byte)((*sp >> sshift) & 0x01);
2757                for (j = 0; j < jstop; j++)
2758                {
2759                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2760                   *dp |= (png_byte)(v << dshift);
2761                   if (dshift == s_end)
2762                   {
2763                      dshift = s_start;
2764                      dp--;
2765                   }
2766                   else
2767                      dshift += s_inc;
2768                }
2769                if (sshift == s_end)
2770                {
2771                   sshift = s_start;
2772                   sp--;
2773                }
2774                else
2775                   sshift += s_inc;
2776             }
2777             break;
2778          }
2779          case 2:
2780          {
2781             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2782             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2783             int sshift, dshift;
2784             int s_start, s_end, s_inc;
2785             int jstop = png_pass_inc[pass];
2786             png_uint_32 i;
2787 
2788 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2789             if (transformations & PNG_PACKSWAP)
2790             {
2791                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2792                dshift = (int)(((final_width + 3) & 0x03) << 1);
2793                s_start = 6;
2794                s_end = 0;
2795                s_inc = -2;
2796             }
2797             else
2798 #endif
2799             {
2800                sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2801                dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2802                s_start = 0;
2803                s_end = 6;
2804                s_inc = 2;
2805             }
2806 
2807             for (i = 0; i < row_info->width; i++)
2808             {
2809                png_byte v;
2810                int j;
2811 
2812                v = (png_byte)((*sp >> sshift) & 0x03);
2813                for (j = 0; j < jstop; j++)
2814                {
2815                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2816                   *dp |= (png_byte)(v << dshift);
2817                   if (dshift == s_end)
2818                   {
2819                      dshift = s_start;
2820                      dp--;
2821                   }
2822                   else
2823                      dshift += s_inc;
2824                }
2825                if (sshift == s_end)
2826                {
2827                   sshift = s_start;
2828                   sp--;
2829                }
2830                else
2831                   sshift += s_inc;
2832             }
2833             break;
2834          }
2835          case 4:
2836          {
2837             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2838             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2839             int sshift, dshift;
2840             int s_start, s_end, s_inc;
2841             png_uint_32 i;
2842             int jstop = png_pass_inc[pass];
2843 
2844 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2845             if (transformations & PNG_PACKSWAP)
2846             {
2847                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2848                dshift = (int)(((final_width + 1) & 0x01) << 2);
2849                s_start = 4;
2850                s_end = 0;
2851                s_inc = -4;
2852             }
2853             else
2854 #endif
2855             {
2856                sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2857                dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2858                s_start = 0;
2859                s_end = 4;
2860                s_inc = 4;
2861             }
2862 
2863             for (i = 0; i < row_info->width; i++)
2864             {
2865                png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2866                int j;
2867 
2868                for (j = 0; j < jstop; j++)
2869                {
2870                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2871                   *dp |= (png_byte)(v << dshift);
2872                   if (dshift == s_end)
2873                   {
2874                      dshift = s_start;
2875                      dp--;
2876                   }
2877                   else
2878                      dshift += s_inc;
2879                }
2880                if (sshift == s_end)
2881                {
2882                   sshift = s_start;
2883                   sp--;
2884                }
2885                else
2886                   sshift += s_inc;
2887             }
2888             break;
2889          }
2890          default:
2891          {
2892             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2893             png_bytep sp = row + (png_size_t)(row_info->width - 1)
2894                 * pixel_bytes;
2895             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2896 
2897             int jstop = png_pass_inc[pass];
2898             png_uint_32 i;
2899 
2900             for (i = 0; i < row_info->width; i++)
2901             {
2902                png_byte v[8];
2903                int j;
2904 
2905                png_memcpy(v, sp, pixel_bytes);
2906                for (j = 0; j < jstop; j++)
2907                {
2908                   png_memcpy(dp, v, pixel_bytes);
2909                   dp -= pixel_bytes;
2910                }
2911                sp -= pixel_bytes;
2912             }
2913             break;
2914          }
2915       }
2916       row_info->width = final_width;
2917       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
2918    }
2919 #ifndef PNG_READ_PACKSWAP_SUPPORTED
2920    transformations = transformations; /* Silence compiler warning */
2921 #endif
2922 }
2923 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2924 
2925 void /* PRIVATE */
png_read_filter_row(png_structp png_ptr,png_row_infop row_info,png_bytep row,png_bytep prev_row,int filter)2926 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2927    png_bytep prev_row, int filter)
2928 {
2929    png_debug(1, "in png_read_filter_row");
2930    png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
2931    switch (filter)
2932    {
2933       case PNG_FILTER_VALUE_NONE:
2934          break;
2935       case PNG_FILTER_VALUE_SUB:
2936       {
2937          png_uint_32 i;
2938          png_uint_32 istop = row_info->rowbytes;
2939          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2940          png_bytep rp = row + bpp;
2941          png_bytep lp = row;
2942 
2943          for (i = bpp; i < istop; i++)
2944          {
2945             *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2946             rp++;
2947          }
2948          break;
2949       }
2950       case PNG_FILTER_VALUE_UP:
2951       {
2952          png_uint_32 i;
2953          png_uint_32 istop = row_info->rowbytes;
2954          png_bytep rp = row;
2955          png_bytep pp = prev_row;
2956 
2957          for (i = 0; i < istop; i++)
2958          {
2959             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2960             rp++;
2961          }
2962          break;
2963       }
2964       case PNG_FILTER_VALUE_AVG:
2965       {
2966          png_uint_32 i;
2967          png_bytep rp = row;
2968          png_bytep pp = prev_row;
2969          png_bytep lp = row;
2970          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2971          png_uint_32 istop = row_info->rowbytes - bpp;
2972 
2973          for (i = 0; i < bpp; i++)
2974          {
2975             *rp = (png_byte)(((int)(*rp) +
2976                ((int)(*pp++) / 2 )) & 0xff);
2977             rp++;
2978          }
2979 
2980          for (i = 0; i < istop; i++)
2981          {
2982             *rp = (png_byte)(((int)(*rp) +
2983                (int)(*pp++ + *lp++) / 2 ) & 0xff);
2984             rp++;
2985          }
2986          break;
2987       }
2988       case PNG_FILTER_VALUE_PAETH:
2989       {
2990          png_uint_32 i;
2991          png_bytep rp = row;
2992          png_bytep pp = prev_row;
2993          png_bytep lp = row;
2994          png_bytep cp = prev_row;
2995          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2996          png_uint_32 istop=row_info->rowbytes - bpp;
2997 
2998          for (i = 0; i < bpp; i++)
2999          {
3000             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
3001             rp++;
3002          }
3003 
3004          for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
3005          {
3006             int a, b, c, pa, pb, pc, p;
3007 
3008             a = *lp++;
3009             b = *pp++;
3010             c = *cp++;
3011 
3012             p = b - c;
3013             pc = a - c;
3014 
3015 #ifdef PNG_USE_ABS
3016             pa = abs(p);
3017             pb = abs(pc);
3018             pc = abs(p + pc);
3019 #else
3020             pa = p < 0 ? -p : p;
3021             pb = pc < 0 ? -pc : pc;
3022             pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3023 #endif
3024 
3025             /*
3026                if (pa <= pb && pa <= pc)
3027                   p = a;
3028                else if (pb <= pc)
3029                   p = b;
3030                else
3031                   p = c;
3032              */
3033 
3034             p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
3035 
3036             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
3037             rp++;
3038          }
3039          break;
3040       }
3041       default:
3042          png_warning(png_ptr, "Ignoring bad adaptive filter type");
3043          *row = 0;
3044          break;
3045    }
3046 }
3047 
3048 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3049 void /* PRIVATE */
png_read_finish_row(png_structp png_ptr)3050 png_read_finish_row(png_structp png_ptr)
3051 {
3052 #ifdef PNG_READ_INTERLACING_SUPPORTED
3053    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3054 
3055    /* Start of interlace block */
3056    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3057 
3058    /* Offset to next interlace block */
3059    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3060 
3061    /* Start of interlace block in the y direction */
3062    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3063 
3064    /* Offset to next interlace block in the y direction */
3065    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3066 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3067 
3068    png_debug(1, "in png_read_finish_row");
3069    png_ptr->row_number++;
3070    if (png_ptr->row_number < png_ptr->num_rows)
3071       return;
3072 
3073 #ifdef PNG_READ_INTERLACING_SUPPORTED
3074    if (png_ptr->interlaced)
3075    {
3076       png_ptr->row_number = 0;
3077       png_memset_check(png_ptr, png_ptr->prev_row, 0,
3078          png_ptr->rowbytes + 1);
3079       do
3080       {
3081          png_ptr->pass++;
3082          if (png_ptr->pass >= 7)
3083             break;
3084          png_ptr->iwidth = (png_ptr->width +
3085             png_pass_inc[png_ptr->pass] - 1 -
3086             png_pass_start[png_ptr->pass]) /
3087             png_pass_inc[png_ptr->pass];
3088 
3089          if (!(png_ptr->transformations & PNG_INTERLACE))
3090          {
3091             png_ptr->num_rows = (png_ptr->height +
3092                png_pass_yinc[png_ptr->pass] - 1 -
3093                png_pass_ystart[png_ptr->pass]) /
3094                png_pass_yinc[png_ptr->pass];
3095             if (!(png_ptr->num_rows))
3096                continue;
3097          }
3098          else  /* if (png_ptr->transformations & PNG_INTERLACE) */
3099             break;
3100       } while (png_ptr->iwidth == 0);
3101 
3102       if (png_ptr->pass < 7)
3103          return;
3104    }
3105 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3106 
3107    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3108    {
3109 #ifdef PNG_USE_LOCAL_ARRAYS
3110       PNG_CONST PNG_IDAT;
3111 #endif
3112       char extra;
3113       int ret;
3114 
3115       png_ptr->zstream.next_out = (Byte *)&extra;
3116       png_ptr->zstream.avail_out = (uInt)1;
3117       for (;;)
3118       {
3119          if (!(png_ptr->zstream.avail_in))
3120          {
3121             while (!png_ptr->idat_size)
3122             {
3123                png_byte chunk_length[4];
3124 
3125                png_crc_finish(png_ptr, 0);
3126 
3127                png_read_data(png_ptr, chunk_length, 4);
3128                png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
3129                png_reset_crc(png_ptr);
3130                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3131                if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
3132                   png_error(png_ptr, "Not enough image data");
3133 
3134             }
3135             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3136             png_ptr->zstream.next_in = png_ptr->zbuf;
3137             if (png_ptr->zbuf_size > png_ptr->idat_size)
3138                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3139             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3140             png_ptr->idat_size -= png_ptr->zstream.avail_in;
3141          }
3142          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3143          if (ret == Z_STREAM_END)
3144          {
3145             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3146                png_ptr->idat_size)
3147                png_warning(png_ptr, "Extra compressed data.");
3148             png_ptr->mode |= PNG_AFTER_IDAT;
3149             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3150             break;
3151          }
3152          if (ret != Z_OK)
3153             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3154                       "Decompression Error");
3155 
3156          if (!(png_ptr->zstream.avail_out))
3157          {
3158             png_warning(png_ptr, "Extra compressed data.");
3159             png_ptr->mode |= PNG_AFTER_IDAT;
3160             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3161             break;
3162          }
3163 
3164       }
3165       png_ptr->zstream.avail_out = 0;
3166    }
3167 
3168    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3169       png_warning(png_ptr, "Extra compression data.");
3170 
3171    inflateReset(&png_ptr->zstream);
3172 
3173    png_ptr->mode |= PNG_AFTER_IDAT;
3174 }
3175 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3176 
3177 void /* PRIVATE */
png_read_start_row(png_structp png_ptr)3178 png_read_start_row(png_structp png_ptr)
3179 {
3180 #ifdef PNG_READ_INTERLACING_SUPPORTED
3181    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3182 
3183    /* Start of interlace block */
3184    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3185 
3186    /* Offset to next interlace block */
3187    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3188 
3189    /* Start of interlace block in the y direction */
3190    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3191 
3192    /* Offset to next interlace block in the y direction */
3193    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3194 #endif
3195 
3196    int max_pixel_depth;
3197    png_size_t row_bytes;
3198 
3199    png_debug(1, "in png_read_start_row");
3200    png_ptr->zstream.avail_in = 0;
3201    png_init_read_transformations(png_ptr);
3202 #ifdef PNG_READ_INTERLACING_SUPPORTED
3203    if (png_ptr->interlaced)
3204    {
3205       if (!(png_ptr->transformations & PNG_INTERLACE))
3206          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3207             png_pass_ystart[0]) / png_pass_yinc[0];
3208       else
3209          png_ptr->num_rows = png_ptr->height;
3210 
3211       png_ptr->iwidth = (png_ptr->width +
3212          png_pass_inc[png_ptr->pass] - 1 -
3213          png_pass_start[png_ptr->pass]) /
3214          png_pass_inc[png_ptr->pass];
3215    }
3216    else
3217 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3218    {
3219       png_ptr->num_rows = png_ptr->height;
3220       png_ptr->iwidth = png_ptr->width;
3221    }
3222    max_pixel_depth = png_ptr->pixel_depth;
3223 
3224 #ifdef PNG_READ_PACK_SUPPORTED
3225    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3226       max_pixel_depth = 8;
3227 #endif
3228 
3229 #ifdef PNG_READ_EXPAND_SUPPORTED
3230    if (png_ptr->transformations & PNG_EXPAND)
3231    {
3232       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3233       {
3234          if (png_ptr->num_trans)
3235             max_pixel_depth = 32;
3236          else
3237             max_pixel_depth = 24;
3238       }
3239       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3240       {
3241          if (max_pixel_depth < 8)
3242             max_pixel_depth = 8;
3243          if (png_ptr->num_trans)
3244             max_pixel_depth *= 2;
3245       }
3246       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3247       {
3248          if (png_ptr->num_trans)
3249          {
3250             max_pixel_depth *= 4;
3251             max_pixel_depth /= 3;
3252          }
3253       }
3254    }
3255 #endif
3256 
3257 #ifdef PNG_READ_FILLER_SUPPORTED
3258    if (png_ptr->transformations & (PNG_FILLER))
3259    {
3260       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3261          max_pixel_depth = 32;
3262       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3263       {
3264          if (max_pixel_depth <= 8)
3265             max_pixel_depth = 16;
3266          else
3267             max_pixel_depth = 32;
3268       }
3269       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3270       {
3271          if (max_pixel_depth <= 32)
3272             max_pixel_depth = 32;
3273          else
3274             max_pixel_depth = 64;
3275       }
3276    }
3277 #endif
3278 
3279 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3280    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3281    {
3282       if (
3283 #ifdef PNG_READ_EXPAND_SUPPORTED
3284         (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3285 #endif
3286 #ifdef PNG_READ_FILLER_SUPPORTED
3287         (png_ptr->transformations & (PNG_FILLER)) ||
3288 #endif
3289         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3290       {
3291          if (max_pixel_depth <= 16)
3292             max_pixel_depth = 32;
3293          else
3294             max_pixel_depth = 64;
3295       }
3296       else
3297       {
3298          if (max_pixel_depth <= 8)
3299            {
3300              if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3301                max_pixel_depth = 32;
3302              else
3303                max_pixel_depth = 24;
3304            }
3305          else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3306             max_pixel_depth = 64;
3307          else
3308             max_pixel_depth = 48;
3309       }
3310    }
3311 #endif
3312 
3313 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3314 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3315    if (png_ptr->transformations & PNG_USER_TRANSFORM)
3316      {
3317        int user_pixel_depth = png_ptr->user_transform_depth*
3318          png_ptr->user_transform_channels;
3319        if (user_pixel_depth > max_pixel_depth)
3320          max_pixel_depth=user_pixel_depth;
3321      }
3322 #endif
3323 
3324    /* Align the width on the next larger 8 pixels.  Mainly used
3325     * for interlacing
3326     */
3327    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3328    /* Calculate the maximum bytes needed, adding a byte and a pixel
3329     * for safety's sake
3330     */
3331    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
3332       1 + ((max_pixel_depth + 7) >> 3);
3333 #ifdef PNG_MAX_MALLOC_64K
3334    if (row_bytes > (png_uint_32)65536L)
3335       png_error(png_ptr, "This image requires a row greater than 64KB");
3336 #endif
3337 
3338    if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
3339    {
3340      png_free(png_ptr, png_ptr->big_row_buf);
3341      if (png_ptr->interlaced)
3342         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
3343             row_bytes + 64);
3344      else
3345         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
3346             row_bytes + 64);
3347      png_ptr->old_big_row_buf_size = row_bytes + 64;
3348 
3349      /* Use 32 bytes of padding before and after row_buf. */
3350      png_ptr->row_buf = png_ptr->big_row_buf + 32;
3351      png_ptr->old_big_row_buf_size = row_bytes + 64;
3352    }
3353 
3354 #ifdef PNG_MAX_MALLOC_64K
3355    if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
3356       png_error(png_ptr, "This image requires a row greater than 64KB");
3357 #endif
3358    if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3359       png_error(png_ptr, "Row has too many bytes to allocate in memory.");
3360 
3361    if (row_bytes + 1 > png_ptr->old_prev_row_size)
3362    {
3363       png_free(png_ptr, png_ptr->prev_row);
3364       png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3365         row_bytes + 1));
3366       png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
3367       png_ptr->old_prev_row_size = row_bytes + 1;
3368    }
3369 
3370    png_ptr->rowbytes = row_bytes;
3371 
3372    png_debug1(3, "width = %lu,", png_ptr->width);
3373    png_debug1(3, "height = %lu,", png_ptr->height);
3374    png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
3375    png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
3376    png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
3377    png_debug1(3, "irowbytes = %lu",
3378        PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
3379 
3380    png_ptr->flags |= PNG_FLAG_ROW_INIT;
3381 }
3382 #endif /* PNG_READ_SUPPORTED */
3383