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