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