source: rtems-graphics-toolkit/libpng-1.5.11/pngrutil.c @ 248419a

Last change on this file since 248419a was 248419a, checked in by Sebastian Huber <sebastian.huber@…>, on 07/12/12 at 07:28:02

Update libpng from 1.2.41 to 1.5.11

  • Property mode set to 100644
File size: 119.8 KB
Line 
1
2/* pngrutil.c - utilities to read a PNG file
3 *
4 * Last changed in libpng 1.5.10 [March 8, 2012]
5 * Copyright (c) 1998-2012 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 *
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
12 *
13 * This file contains routines that are only called from within
14 * libpng itself during the course of reading an image.
15 */
16
17#include "pngpriv.h"
18
19#ifdef PNG_READ_SUPPORTED
20
21#define png_strtod(p,a,b) strtod(a,b)
22
23png_uint_32 PNGAPI
24png_get_uint_31(png_structp png_ptr, png_const_bytep buf)
25{
26   png_uint_32 uval = png_get_uint_32(buf);
27
28   if (uval > PNG_UINT_31_MAX)
29      png_error(png_ptr, "PNG unsigned integer out of range");
30
31   return (uval);
32}
33
34#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
35/* The following is a variation on the above for use with the fixed
36 * point values used for gAMA and cHRM.  Instead of png_error it
37 * issues a warning and returns (-1) - an invalid value because both
38 * gAMA and cHRM use *unsigned* integers for fixed point values.
39 */
40#define PNG_FIXED_ERROR (-1)
41
42static png_fixed_point /* PRIVATE */
43png_get_fixed_point(png_structp png_ptr, png_const_bytep buf)
44{
45   png_uint_32 uval = png_get_uint_32(buf);
46
47   if (uval <= PNG_UINT_31_MAX)
48      return (png_fixed_point)uval; /* known to be in range */
49
50   /* The caller can turn off the warning by passing NULL. */
51   if (png_ptr != NULL)
52      png_warning(png_ptr, "PNG fixed point integer out of range");
53
54   return PNG_FIXED_ERROR;
55}
56#endif
57
58#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
59/* NOTE: the read macros will obscure these definitions, so that if
60 * PNG_USE_READ_MACROS is set the library will not use them internally,
61 * but the APIs will still be available externally.
62 *
63 * The parentheses around "PNGAPI function_name" in the following three
64 * functions are necessary because they allow the macros to co-exist with
65 * these (unused but exported) functions.
66 */
67
68/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
69png_uint_32 (PNGAPI
70png_get_uint_32)(png_const_bytep buf)
71{
72   png_uint_32 uval =
73       ((png_uint_32)(*(buf    )) << 24) +
74       ((png_uint_32)(*(buf + 1)) << 16) +
75       ((png_uint_32)(*(buf + 2)) <<  8) +
76       ((png_uint_32)(*(buf + 3))      ) ;
77
78   return uval;
79}
80
81/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
82 * data is stored in the PNG file in two's complement format and there
83 * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
84 * the following code does a two's complement to native conversion.
85 */
86png_int_32 (PNGAPI
87png_get_int_32)(png_const_bytep buf)
88{
89   png_uint_32 uval = png_get_uint_32(buf);
90   if ((uval & 0x80000000) == 0) /* non-negative */
91      return uval;
92
93   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
94   return -(png_int_32)uval;
95}
96
97/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
98png_uint_16 (PNGAPI
99png_get_uint_16)(png_const_bytep buf)
100{
101   /* ANSI-C requires an int value to accomodate at least 16 bits so this
102    * works and allows the compiler not to worry about possible narrowing
103    * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
104    * than 16 bits either.)
105    */
106   unsigned int val =
107       ((unsigned int)(*buf) << 8) +
108       ((unsigned int)(*(buf + 1)));
109
110   return (png_uint_16)val;
111}
112
113#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
114
115/* Read and check the PNG file signature */
116void /* PRIVATE */
117png_read_sig(png_structp png_ptr, png_infop info_ptr)
118{
119   png_size_t num_checked, num_to_check;
120
121   /* Exit if the user application does not expect a signature. */
122   if (png_ptr->sig_bytes >= 8)
123      return;
124
125   num_checked = png_ptr->sig_bytes;
126   num_to_check = 8 - num_checked;
127
128#ifdef PNG_IO_STATE_SUPPORTED
129   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
130#endif
131
132   /* The signature must be serialized in a single I/O call. */
133   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
134   png_ptr->sig_bytes = 8;
135
136   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
137   {
138      if (num_checked < 4 &&
139          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
140         png_error(png_ptr, "Not a PNG file");
141      else
142         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
143   }
144   if (num_checked < 3)
145      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
146}
147
148/* Read the chunk header (length + type name).
149 * Put the type name into png_ptr->chunk_name, and return the length.
150 */
151png_uint_32 /* PRIVATE */
152png_read_chunk_header(png_structp png_ptr)
153{
154   png_byte buf[8];
155   png_uint_32 length;
156
157#ifdef PNG_IO_STATE_SUPPORTED
158   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
159#endif
160
161   /* Read the length and the chunk name.
162    * This must be performed in a single I/O call.
163    */
164   png_read_data(png_ptr, buf, 8);
165   length = png_get_uint_31(png_ptr, buf);
166
167   /* Put the chunk name into png_ptr->chunk_name. */
168   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
169
170   png_debug2(0, "Reading %lx chunk, length = %lu",
171       (unsigned long)png_ptr->chunk_name, (unsigned long)length);
172
173   /* Reset the crc and run it over the chunk name. */
174   png_reset_crc(png_ptr);
175   png_calculate_crc(png_ptr, buf + 4, 4);
176
177   /* Check to see if chunk name is valid. */
178   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
179
180#ifdef PNG_IO_STATE_SUPPORTED
181   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
182#endif
183
184   return length;
185}
186
187/* Read data, and (optionally) run it through the CRC. */
188void /* PRIVATE */
189png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
190{
191   if (png_ptr == NULL)
192      return;
193
194   png_read_data(png_ptr, buf, length);
195   png_calculate_crc(png_ptr, buf, length);
196}
197
198/* Optionally skip data and then check the CRC.  Depending on whether we
199 * are reading a ancillary or critical chunk, and how the program has set
200 * things up, we may calculate the CRC on the data and print a message.
201 * Returns '1' if there was a CRC error, '0' otherwise.
202 */
203int /* PRIVATE */
204png_crc_finish(png_structp png_ptr, png_uint_32 skip)
205{
206   png_size_t i;
207   png_size_t istop = png_ptr->zbuf_size;
208
209   for (i = (png_size_t)skip; i > istop; i -= istop)
210   {
211      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
212   }
213
214   if (i)
215   {
216      png_crc_read(png_ptr, png_ptr->zbuf, i);
217   }
218
219   if (png_crc_error(png_ptr))
220   {
221      if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ?
222          !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
223          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
224      {
225         png_chunk_warning(png_ptr, "CRC error");
226      }
227
228      else
229      {
230         png_chunk_benign_error(png_ptr, "CRC error");
231         return (0);
232      }
233
234      return (1);
235   }
236
237   return (0);
238}
239
240/* Compare the CRC stored in the PNG file with that calculated by libpng from
241 * the data it has read thus far.
242 */
243int /* PRIVATE */
244png_crc_error(png_structp png_ptr)
245{
246   png_byte crc_bytes[4];
247   png_uint_32 crc;
248   int need_crc = 1;
249
250   if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
251   {
252      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
253          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
254         need_crc = 0;
255   }
256
257   else /* critical */
258   {
259      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
260         need_crc = 0;
261   }
262
263#ifdef PNG_IO_STATE_SUPPORTED
264   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
265#endif
266
267   /* The chunk CRC must be serialized in a single I/O call. */
268   png_read_data(png_ptr, crc_bytes, 4);
269
270   if (need_crc)
271   {
272      crc = png_get_uint_32(crc_bytes);
273      return ((int)(crc != png_ptr->crc));
274   }
275
276   else
277      return (0);
278}
279
280#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
281static png_size_t
282png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
283    png_bytep output, png_size_t output_size)
284{
285   png_size_t count = 0;
286
287   /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
288    * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
289    * more".  Consequently it is necessary to chunk the input to zlib.  This
290    * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
291    * that can be stored in a uInt.)  It is possible to set ZLIB_IO_MAX to a
292    * lower value in pngpriv.h and this may sometimes have a performance
293    * advantage, because it forces access of the input data to be separated from
294    * at least some of the use by some period of time.
295    */
296   png_ptr->zstream.next_in = data;
297   /* avail_in is set below from 'size' */
298   png_ptr->zstream.avail_in = 0;
299
300   while (1)
301   {
302      int ret, avail;
303
304      /* The setting of 'avail_in' used to be outside the loop; by setting it
305       * inside it is possible to chunk the input to zlib and simply rely on
306       * zlib to advance the 'next_in' pointer.  This allows arbitrary amounts o
307       * data to be passed through zlib at the unavoidable cost of requiring a
308       * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
309       * input bytes.
310       */
311      if (png_ptr->zstream.avail_in == 0 && size > 0)
312      {
313         if (size <= ZLIB_IO_MAX)
314         {
315            /* The value is less than ZLIB_IO_MAX so the cast is safe: */
316            png_ptr->zstream.avail_in = (uInt)size;
317            size = 0;
318         }
319
320         else
321         {
322            png_ptr->zstream.avail_in = ZLIB_IO_MAX;
323            size -= ZLIB_IO_MAX;
324         }
325      }
326
327      /* Reset the output buffer each time round - we empty it
328       * after every inflate call.
329       */
330      png_ptr->zstream.next_out = png_ptr->zbuf;
331      png_ptr->zstream.avail_out = png_ptr->zbuf_size;
332
333      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
334      avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
335
336      /* First copy/count any new output - but only if we didn't
337       * get an error code.
338       */
339      if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
340      {
341         png_size_t space = avail; /* > 0, see above */
342
343         if (output != 0 && output_size > count)
344         {
345            png_size_t copy = output_size - count;
346
347            if (space < copy)
348               copy = space;
349
350            png_memcpy(output + count, png_ptr->zbuf, copy);
351         }
352         count += space;
353      }
354
355      if (ret == Z_OK)
356         continue;
357
358      /* Termination conditions - always reset the zstream, it
359       * must be left in inflateInit state.
360       */
361      png_ptr->zstream.avail_in = 0;
362      inflateReset(&png_ptr->zstream);
363
364      if (ret == Z_STREAM_END)
365         return count; /* NOTE: may be zero. */
366
367      /* Now handle the error codes - the API always returns 0
368       * and the error message is dumped into the uncompressed
369       * buffer if available.
370       */
371#     ifdef PNG_WARNINGS_SUPPORTED
372      {
373         png_const_charp msg;
374
375         if (png_ptr->zstream.msg != 0)
376            msg = png_ptr->zstream.msg;
377
378         else switch (ret)
379         {
380            case Z_BUF_ERROR:
381               msg = "Buffer error in compressed datastream";
382               break;
383
384            case Z_DATA_ERROR:
385               msg = "Data error in compressed datastream";
386               break;
387
388            default:
389               msg = "Incomplete compressed datastream";
390               break;
391         }
392
393         png_chunk_warning(png_ptr, msg);
394      }
395#     endif
396
397      /* 0 means an error - notice that this code simply ignores
398       * zero length compressed chunks as a result.
399       */
400      return 0;
401   }
402}
403
404/*
405 * Decompress trailing data in a chunk.  The assumption is that chunkdata
406 * points at an allocated area holding the contents of a chunk with a
407 * trailing compressed part.  What we get back is an allocated area
408 * holding the original prefix part and an uncompressed version of the
409 * trailing part (the malloc area passed in is freed).
410 */
411void /* PRIVATE */
412png_decompress_chunk(png_structp png_ptr, int comp_type,
413    png_size_t chunklength,
414    png_size_t prefix_size, png_size_t *newlength)
415{
416   /* The caller should guarantee this */
417   if (prefix_size > chunklength)
418   {
419      /* The recovery is to delete the chunk. */
420      png_warning(png_ptr, "invalid chunklength");
421      prefix_size = 0; /* To delete everything */
422   }
423
424   else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
425   {
426      png_size_t expanded_size = png_inflate(png_ptr,
427          (png_bytep)(png_ptr->chunkdata + prefix_size),
428          chunklength - prefix_size,
429          0,            /* output */
430          0);           /* output size */
431
432      /* Now check the limits on this chunk - if the limit fails the
433       * compressed data will be removed, the prefix will remain.
434       */
435      if (prefix_size >= (~(png_size_t)0) - 1 ||
436         expanded_size >= (~(png_size_t)0) - 1 - prefix_size
437#ifdef PNG_USER_LIMITS_SUPPORTED
438         || (png_ptr->user_chunk_malloc_max &&
439          (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
440#else
441         || ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
442          prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
443#endif
444         )
445         png_warning(png_ptr, "Exceeded size limit while expanding chunk");
446
447      /* If the size is zero either there was an error and a message
448       * has already been output (warning) or the size really is zero
449       * and we have nothing to do - the code will exit through the
450       * error case below.
451       */
452      else if (expanded_size > 0)
453      {
454         /* Success (maybe) - really uncompress the chunk. */
455         png_size_t new_size = 0;
456         png_charp text = (png_charp)png_malloc_warn(png_ptr,
457             prefix_size + expanded_size + 1);
458
459         if (text != NULL)
460         {
461            png_memcpy(text, png_ptr->chunkdata, prefix_size);
462            new_size = png_inflate(png_ptr,
463                (png_bytep)(png_ptr->chunkdata + prefix_size),
464                chunklength - prefix_size,
465                (png_bytep)(text + prefix_size), expanded_size);
466            text[prefix_size + expanded_size] = 0; /* just in case */
467
468            if (new_size == expanded_size)
469            {
470               png_free(png_ptr, png_ptr->chunkdata);
471               png_ptr->chunkdata = text;
472               *newlength = prefix_size + expanded_size;
473               return; /* The success return! */
474            }
475
476            png_warning(png_ptr, "png_inflate logic error");
477            png_free(png_ptr, text);
478         }
479
480         else
481            png_warning(png_ptr, "Not enough memory to decompress chunk");
482      }
483   }
484
485   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
486   {
487      PNG_WARNING_PARAMETERS(p)
488      png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type);
489      png_formatted_warning(png_ptr, p, "Unknown compression type @1");
490
491      /* The recovery is to simply drop the data. */
492   }
493
494   /* Generic error return - leave the prefix, delete the compressed
495    * data, reallocate the chunkdata to remove the potentially large
496    * amount of compressed data.
497    */
498   {
499      png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1);
500
501      if (text != NULL)
502      {
503         if (prefix_size > 0)
504            png_memcpy(text, png_ptr->chunkdata, prefix_size);
505
506         png_free(png_ptr, png_ptr->chunkdata);
507         png_ptr->chunkdata = text;
508
509         /* This is an extra zero in the 'uncompressed' part. */
510         *(png_ptr->chunkdata + prefix_size) = 0x00;
511      }
512      /* Ignore a malloc error here - it is safe. */
513   }
514
515   *newlength = prefix_size;
516}
517#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
518
519/* Read and check the IDHR chunk */
520void /* PRIVATE */
521png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
522{
523   png_byte buf[13];
524   png_uint_32 width, height;
525   int bit_depth, color_type, compression_type, filter_type;
526   int interlace_type;
527
528   png_debug(1, "in png_handle_IHDR");
529
530   if (png_ptr->mode & PNG_HAVE_IHDR)
531      png_error(png_ptr, "Out of place IHDR");
532
533   /* Check the length */
534   if (length != 13)
535      png_error(png_ptr, "Invalid IHDR chunk");
536
537   png_ptr->mode |= PNG_HAVE_IHDR;
538
539   png_crc_read(png_ptr, buf, 13);
540   png_crc_finish(png_ptr, 0);
541
542   width = png_get_uint_31(png_ptr, buf);
543   height = png_get_uint_31(png_ptr, buf + 4);
544   bit_depth = buf[8];
545   color_type = buf[9];
546   compression_type = buf[10];
547   filter_type = buf[11];
548   interlace_type = buf[12];
549
550   /* Set internal variables */
551   png_ptr->width = width;
552   png_ptr->height = height;
553   png_ptr->bit_depth = (png_byte)bit_depth;
554   png_ptr->interlaced = (png_byte)interlace_type;
555   png_ptr->color_type = (png_byte)color_type;
556#ifdef PNG_MNG_FEATURES_SUPPORTED
557   png_ptr->filter_type = (png_byte)filter_type;
558#endif
559   png_ptr->compression_type = (png_byte)compression_type;
560
561   /* Find number of channels */
562   switch (png_ptr->color_type)
563   {
564      default: /* invalid, png_set_IHDR calls png_error */
565      case PNG_COLOR_TYPE_GRAY:
566      case PNG_COLOR_TYPE_PALETTE:
567         png_ptr->channels = 1;
568         break;
569
570      case PNG_COLOR_TYPE_RGB:
571         png_ptr->channels = 3;
572         break;
573
574      case PNG_COLOR_TYPE_GRAY_ALPHA:
575         png_ptr->channels = 2;
576         break;
577
578      case PNG_COLOR_TYPE_RGB_ALPHA:
579         png_ptr->channels = 4;
580         break;
581   }
582
583   /* Set up other useful info */
584   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
585   png_ptr->channels);
586   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
587   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
588   png_debug1(3, "channels = %d", png_ptr->channels);
589   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
590   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
591       color_type, interlace_type, compression_type, filter_type);
592}
593
594/* Read and check the palette */
595void /* PRIVATE */
596png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
597{
598   png_color palette[PNG_MAX_PALETTE_LENGTH];
599   int num, i;
600#ifdef PNG_POINTER_INDEXING_SUPPORTED
601   png_colorp pal_ptr;
602#endif
603
604   png_debug(1, "in png_handle_PLTE");
605
606   if (!(png_ptr->mode & PNG_HAVE_IHDR))
607      png_error(png_ptr, "Missing IHDR before PLTE");
608
609   else if (png_ptr->mode & PNG_HAVE_IDAT)
610   {
611      png_warning(png_ptr, "Invalid PLTE after IDAT");
612      png_crc_finish(png_ptr, length);
613      return;
614   }
615
616   else if (png_ptr->mode & PNG_HAVE_PLTE)
617      png_error(png_ptr, "Duplicate PLTE chunk");
618
619   png_ptr->mode |= PNG_HAVE_PLTE;
620
621   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
622   {
623      png_warning(png_ptr,
624          "Ignoring PLTE chunk in grayscale PNG");
625      png_crc_finish(png_ptr, length);
626      return;
627   }
628
629#ifndef PNG_READ_OPT_PLTE_SUPPORTED
630   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
631   {
632      png_crc_finish(png_ptr, length);
633      return;
634   }
635#endif
636
637   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
638   {
639      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
640      {
641         png_warning(png_ptr, "Invalid palette chunk");
642         png_crc_finish(png_ptr, length);
643         return;
644      }
645
646      else
647      {
648         png_error(png_ptr, "Invalid palette chunk");
649      }
650   }
651
652   num = (int)length / 3;
653
654#ifdef PNG_POINTER_INDEXING_SUPPORTED
655   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
656   {
657      png_byte buf[3];
658
659      png_crc_read(png_ptr, buf, 3);
660      pal_ptr->red = buf[0];
661      pal_ptr->green = buf[1];
662      pal_ptr->blue = buf[2];
663   }
664#else
665   for (i = 0; i < num; i++)
666   {
667      png_byte buf[3];
668
669      png_crc_read(png_ptr, buf, 3);
670      /* Don't depend upon png_color being any order */
671      palette[i].red = buf[0];
672      palette[i].green = buf[1];
673      palette[i].blue = buf[2];
674   }
675#endif
676
677   /* If we actually need the PLTE chunk (ie for a paletted image), we do
678    * whatever the normal CRC configuration tells us.  However, if we
679    * have an RGB image, the PLTE can be considered ancillary, so
680    * we will act as though it is.
681    */
682#ifndef PNG_READ_OPT_PLTE_SUPPORTED
683   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
684#endif
685   {
686      png_crc_finish(png_ptr, 0);
687   }
688
689#ifndef PNG_READ_OPT_PLTE_SUPPORTED
690   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
691   {
692      /* If we don't want to use the data from an ancillary chunk,
693       * we have two options: an error abort, or a warning and we
694       * ignore the data in this chunk (which should be OK, since
695       * it's considered ancillary for a RGB or RGBA image).
696       */
697      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
698      {
699         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
700         {
701            png_chunk_benign_error(png_ptr, "CRC error");
702         }
703
704         else
705         {
706            png_chunk_warning(png_ptr, "CRC error");
707            return;
708         }
709      }
710
711      /* Otherwise, we (optionally) emit a warning and use the chunk. */
712      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
713      {
714         png_chunk_warning(png_ptr, "CRC error");
715      }
716   }
717#endif
718
719   png_set_PLTE(png_ptr, info_ptr, palette, num);
720
721#ifdef PNG_READ_tRNS_SUPPORTED
722   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
723   {
724      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
725      {
726         if (png_ptr->num_trans > (png_uint_16)num)
727         {
728            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
729            png_ptr->num_trans = (png_uint_16)num;
730         }
731
732         if (info_ptr->num_trans > (png_uint_16)num)
733         {
734            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
735            info_ptr->num_trans = (png_uint_16)num;
736         }
737      }
738   }
739#endif
740
741}
742
743void /* PRIVATE */
744png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
745{
746   png_debug(1, "in png_handle_IEND");
747
748   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
749   {
750      png_error(png_ptr, "No image in file");
751   }
752
753   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
754
755   if (length != 0)
756   {
757      png_warning(png_ptr, "Incorrect IEND chunk length");
758   }
759
760   png_crc_finish(png_ptr, length);
761
762   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
763}
764
765#ifdef PNG_READ_gAMA_SUPPORTED
766void /* PRIVATE */
767png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
768{
769   png_fixed_point igamma;
770   png_byte buf[4];
771
772   png_debug(1, "in png_handle_gAMA");
773
774   if (!(png_ptr->mode & PNG_HAVE_IHDR))
775      png_error(png_ptr, "Missing IHDR before gAMA");
776
777   else if (png_ptr->mode & PNG_HAVE_IDAT)
778   {
779      png_warning(png_ptr, "Invalid gAMA after IDAT");
780      png_crc_finish(png_ptr, length);
781      return;
782   }
783
784   else if (png_ptr->mode & PNG_HAVE_PLTE)
785      /* Should be an error, but we can cope with it */
786      png_warning(png_ptr, "Out of place gAMA chunk");
787
788   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
789#ifdef PNG_READ_sRGB_SUPPORTED
790       && !(info_ptr->valid & PNG_INFO_sRGB)
791#endif
792       )
793   {
794      png_warning(png_ptr, "Duplicate gAMA chunk");
795      png_crc_finish(png_ptr, length);
796      return;
797   }
798
799   if (length != 4)
800   {
801      png_warning(png_ptr, "Incorrect gAMA chunk length");
802      png_crc_finish(png_ptr, length);
803      return;
804   }
805
806   png_crc_read(png_ptr, buf, 4);
807
808   if (png_crc_finish(png_ptr, 0))
809      return;
810
811   igamma = png_get_fixed_point(NULL, buf);
812
813   /* Check for zero gamma or an error. */
814   if (igamma <= 0)
815   {
816      png_warning(png_ptr,
817          "Ignoring gAMA chunk with out of range gamma");
818
819      return;
820   }
821
822#  ifdef PNG_READ_sRGB_SUPPORTED
823   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
824   {
825      if (PNG_OUT_OF_RANGE(igamma, 45500, 500))
826      {
827         PNG_WARNING_PARAMETERS(p)
828         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
829         png_formatted_warning(png_ptr, p,
830             "Ignoring incorrect gAMA value @1 when sRGB is also present");
831         return;
832      }
833   }
834#  endif /* PNG_READ_sRGB_SUPPORTED */
835
836#  ifdef PNG_READ_GAMMA_SUPPORTED
837   /* Gamma correction on read is supported. */
838   png_ptr->gamma = igamma;
839#  endif
840   /* And set the 'info' structure members. */
841   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
842}
843#endif
844
845#ifdef PNG_READ_sBIT_SUPPORTED
846void /* PRIVATE */
847png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
848{
849   png_size_t truelen;
850   png_byte buf[4];
851
852   png_debug(1, "in png_handle_sBIT");
853
854   buf[0] = buf[1] = buf[2] = buf[3] = 0;
855
856   if (!(png_ptr->mode & PNG_HAVE_IHDR))
857      png_error(png_ptr, "Missing IHDR before sBIT");
858
859   else if (png_ptr->mode & PNG_HAVE_IDAT)
860   {
861      png_warning(png_ptr, "Invalid sBIT after IDAT");
862      png_crc_finish(png_ptr, length);
863      return;
864   }
865
866   else if (png_ptr->mode & PNG_HAVE_PLTE)
867   {
868      /* Should be an error, but we can cope with it */
869      png_warning(png_ptr, "Out of place sBIT chunk");
870   }
871
872   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
873   {
874      png_warning(png_ptr, "Duplicate sBIT chunk");
875      png_crc_finish(png_ptr, length);
876      return;
877   }
878
879   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
880      truelen = 3;
881
882   else
883      truelen = (png_size_t)png_ptr->channels;
884
885   if (length != truelen || length > 4)
886   {
887      png_warning(png_ptr, "Incorrect sBIT chunk length");
888      png_crc_finish(png_ptr, length);
889      return;
890   }
891
892   png_crc_read(png_ptr, buf, truelen);
893
894   if (png_crc_finish(png_ptr, 0))
895      return;
896
897   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
898   {
899      png_ptr->sig_bit.red = buf[0];
900      png_ptr->sig_bit.green = buf[1];
901      png_ptr->sig_bit.blue = buf[2];
902      png_ptr->sig_bit.alpha = buf[3];
903   }
904
905   else
906   {
907      png_ptr->sig_bit.gray = buf[0];
908      png_ptr->sig_bit.red = buf[0];
909      png_ptr->sig_bit.green = buf[0];
910      png_ptr->sig_bit.blue = buf[0];
911      png_ptr->sig_bit.alpha = buf[1];
912   }
913
914   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
915}
916#endif
917
918#ifdef PNG_READ_cHRM_SUPPORTED
919void /* PRIVATE */
920png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
921{
922   png_byte buf[32];
923   png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue,
924      y_blue;
925
926   png_debug(1, "in png_handle_cHRM");
927
928   if (!(png_ptr->mode & PNG_HAVE_IHDR))
929      png_error(png_ptr, "Missing IHDR before cHRM");
930
931   else if (png_ptr->mode & PNG_HAVE_IDAT)
932   {
933      png_warning(png_ptr, "Invalid cHRM after IDAT");
934      png_crc_finish(png_ptr, length);
935      return;
936   }
937
938   else if (png_ptr->mode & PNG_HAVE_PLTE)
939      /* Should be an error, but we can cope with it */
940      png_warning(png_ptr, "Out of place cHRM chunk");
941
942   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
943#  ifdef PNG_READ_sRGB_SUPPORTED
944       && !(info_ptr->valid & PNG_INFO_sRGB)
945#  endif
946      )
947   {
948      png_warning(png_ptr, "Duplicate cHRM chunk");
949      png_crc_finish(png_ptr, length);
950      return;
951   }
952
953   if (length != 32)
954   {
955      png_warning(png_ptr, "Incorrect cHRM chunk length");
956      png_crc_finish(png_ptr, length);
957      return;
958   }
959
960   png_crc_read(png_ptr, buf, 32);
961
962   if (png_crc_finish(png_ptr, 0))
963      return;
964
965   x_white = png_get_fixed_point(NULL, buf);
966   y_white = png_get_fixed_point(NULL, buf + 4);
967   x_red   = png_get_fixed_point(NULL, buf + 8);
968   y_red   = png_get_fixed_point(NULL, buf + 12);
969   x_green = png_get_fixed_point(NULL, buf + 16);
970   y_green = png_get_fixed_point(NULL, buf + 20);
971   x_blue  = png_get_fixed_point(NULL, buf + 24);
972   y_blue  = png_get_fixed_point(NULL, buf + 28);
973
974   if (x_white == PNG_FIXED_ERROR ||
975       y_white == PNG_FIXED_ERROR ||
976       x_red   == PNG_FIXED_ERROR ||
977       y_red   == PNG_FIXED_ERROR ||
978       x_green == PNG_FIXED_ERROR ||
979       y_green == PNG_FIXED_ERROR ||
980       x_blue  == PNG_FIXED_ERROR ||
981       y_blue  == PNG_FIXED_ERROR)
982   {
983      png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities");
984      return;
985   }
986
987#ifdef PNG_READ_sRGB_SUPPORTED
988   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
989   {
990      if (PNG_OUT_OF_RANGE(x_white, 31270,  1000) ||
991          PNG_OUT_OF_RANGE(y_white, 32900,  1000) ||
992          PNG_OUT_OF_RANGE(x_red,   64000,  1000) ||
993          PNG_OUT_OF_RANGE(y_red,   33000,  1000) ||
994          PNG_OUT_OF_RANGE(x_green, 30000,  1000) ||
995          PNG_OUT_OF_RANGE(y_green, 60000,  1000) ||
996          PNG_OUT_OF_RANGE(x_blue,  15000,  1000) ||
997          PNG_OUT_OF_RANGE(y_blue,   6000,  1000))
998      {
999         PNG_WARNING_PARAMETERS(p)
1000
1001         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white);
1002         png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white);
1003         png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red);
1004         png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red);
1005         png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green);
1006         png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green);
1007         png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue);
1008         png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue);
1009
1010         png_formatted_warning(png_ptr, p,
1011             "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) "
1012             "when sRGB is also present");
1013      }
1014      return;
1015   }
1016#endif /* PNG_READ_sRGB_SUPPORTED */
1017
1018#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1019   /* Store the _white values as default coefficients for the rgb to gray
1020    * operation if it is supported.  Check if the transform is already set to
1021    * avoid destroying the transform values.
1022    */
1023   if (!png_ptr->rgb_to_gray_coefficients_set)
1024   {
1025      /* png_set_background has not been called and we haven't seen an sRGB
1026       * chunk yet.  Find the XYZ of the three end points.
1027       */
1028      png_XYZ XYZ;
1029      png_xy xy;
1030
1031      xy.redx = x_red;
1032      xy.redy = y_red;
1033      xy.greenx = x_green;
1034      xy.greeny = y_green;
1035      xy.bluex = x_blue;
1036      xy.bluey = y_blue;
1037      xy.whitex = x_white;
1038      xy.whitey = y_white;
1039
1040      if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
1041      {
1042         /* The success case, because XYZ_from_xy normalises to a reference
1043          * white Y of 1.0 we just need to scale the numbers.  This should
1044          * always work just fine. It is an internal error if this overflows.
1045          */
1046         {
1047            png_fixed_point r, g, b;
1048            if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) &&
1049               r >= 0 && r <= 32768 &&
1050               png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) &&
1051               g >= 0 && g <= 32768 &&
1052               png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) &&
1053               b >= 0 && b <= 32768 &&
1054               r+g+b <= 32769)
1055            {
1056               /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
1057                * all of the coefficients were rounded up.  Handle this by
1058                * reducing the *largest* coefficient by 1; this matches the
1059                * approach used for the default coefficients in pngrtran.c
1060                */
1061               int add = 0;
1062
1063               if (r+g+b > 32768)
1064                  add = -1;
1065               else if (r+g+b < 32768)
1066                  add = 1;
1067
1068               if (add != 0)
1069               {
1070                  if (g >= r && g >= b)
1071                     g += add;
1072                  else if (r >= g && r >= b)
1073                     r += add;
1074                  else
1075                     b += add;
1076               }
1077
1078               /* Check for an internal error. */
1079               if (r+g+b != 32768)
1080                  png_error(png_ptr,
1081                     "internal error handling cHRM coefficients");
1082
1083               png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
1084               png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
1085            }
1086
1087            /* This is a png_error at present even though it could be ignored -
1088             * it should never happen, but it is important that if it does, the
1089             * bug is fixed.
1090             */
1091            else
1092               png_error(png_ptr, "internal error handling cHRM->XYZ");
1093         }
1094      }
1095   }
1096#endif
1097
1098   png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
1099      x_green, y_green, x_blue, y_blue);
1100}
1101#endif
1102
1103#ifdef PNG_READ_sRGB_SUPPORTED
1104void /* PRIVATE */
1105png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1106{
1107   int intent;
1108   png_byte buf[1];
1109
1110   png_debug(1, "in png_handle_sRGB");
1111
1112   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1113      png_error(png_ptr, "Missing IHDR before sRGB");
1114
1115   else if (png_ptr->mode & PNG_HAVE_IDAT)
1116   {
1117      png_warning(png_ptr, "Invalid sRGB after IDAT");
1118      png_crc_finish(png_ptr, length);
1119      return;
1120   }
1121
1122   else if (png_ptr->mode & PNG_HAVE_PLTE)
1123      /* Should be an error, but we can cope with it */
1124      png_warning(png_ptr, "Out of place sRGB chunk");
1125
1126   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
1127   {
1128      png_warning(png_ptr, "Duplicate sRGB chunk");
1129      png_crc_finish(png_ptr, length);
1130      return;
1131   }
1132
1133   if (length != 1)
1134   {
1135      png_warning(png_ptr, "Incorrect sRGB chunk length");
1136      png_crc_finish(png_ptr, length);
1137      return;
1138   }
1139
1140   png_crc_read(png_ptr, buf, 1);
1141
1142   if (png_crc_finish(png_ptr, 0))
1143      return;
1144
1145   intent = buf[0];
1146
1147   /* Check for bad intent */
1148   if (intent >= PNG_sRGB_INTENT_LAST)
1149   {
1150      png_warning(png_ptr, "Unknown sRGB intent");
1151      return;
1152   }
1153
1154#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
1155   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
1156   {
1157      if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500))
1158      {
1159         PNG_WARNING_PARAMETERS(p)
1160
1161         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed,
1162            info_ptr->gamma);
1163
1164         png_formatted_warning(png_ptr, p,
1165             "Ignoring incorrect gAMA value @1 when sRGB is also present");
1166      }
1167   }
1168#endif /* PNG_READ_gAMA_SUPPORTED */
1169
1170#ifdef PNG_READ_cHRM_SUPPORTED
1171   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1172      if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270,  1000) ||
1173          PNG_OUT_OF_RANGE(info_ptr->y_white, 32900,  1000) ||
1174          PNG_OUT_OF_RANGE(info_ptr->x_red,   64000,  1000) ||
1175          PNG_OUT_OF_RANGE(info_ptr->y_red,   33000,  1000) ||
1176          PNG_OUT_OF_RANGE(info_ptr->x_green, 30000,  1000) ||
1177          PNG_OUT_OF_RANGE(info_ptr->y_green, 60000,  1000) ||
1178          PNG_OUT_OF_RANGE(info_ptr->x_blue,  15000,  1000) ||
1179          PNG_OUT_OF_RANGE(info_ptr->y_blue,   6000,  1000))
1180      {
1181         png_warning(png_ptr,
1182             "Ignoring incorrect cHRM value when sRGB is also present");
1183      }
1184#endif /* PNG_READ_cHRM_SUPPORTED */
1185
1186   /* This is recorded for use when handling the cHRM chunk above.  An sRGB
1187    * chunk unconditionally overwrites the coefficients for grayscale conversion
1188    * too.
1189    */
1190   png_ptr->is_sRGB = 1;
1191
1192#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1193      /* Don't overwrite user supplied values: */
1194      if (!png_ptr->rgb_to_gray_coefficients_set)
1195      {
1196         /* These numbers come from the sRGB specification (or, since one has to
1197          * pay much money to get a copy, the wikipedia sRGB page) the
1198          * chromaticity values quoted have been inverted to get the reverse
1199          * transformation from RGB to XYZ and the 'Y' coefficients scaled by
1200          * 32768 (then rounded).
1201          *
1202          * sRGB and ITU Rec-709 both truncate the values for the D65 white
1203          * point to four digits and, even though it actually stores five
1204          * digits, the PNG spec gives the truncated value.
1205          *
1206          * This means that when the chromaticities are converted back to XYZ
1207          * end points we end up with (6968,23435,2366), which, as described in
1208          * pngrtran.c, would overflow.  If the five digit precision and up is
1209          * used we get, instead:
1210          *
1211          *    6968*R + 23435*G + 2365*B
1212          *
1213          * (Notice that this rounds the blue coefficient down, rather than the
1214          * choice used in pngrtran.c which is to round the green one down.)
1215          */
1216         png_ptr->rgb_to_gray_red_coeff   =  6968; /* 0.212639005871510 */
1217         png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */
1218         /* png_ptr->rgb_to_gray_blue_coeff  =  2366; 0.072192315360734 */
1219
1220         /* The following keeps the cHRM chunk from destroying the
1221          * coefficients again in the event that it follows the sRGB chunk.
1222          */
1223         png_ptr->rgb_to_gray_coefficients_set = 1;
1224      }
1225#  endif
1226
1227   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1228}
1229#endif /* PNG_READ_sRGB_SUPPORTED */
1230
1231#ifdef PNG_READ_iCCP_SUPPORTED
1232void /* PRIVATE */
1233png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1234/* Note: this does not properly handle chunks that are > 64K under DOS */
1235{
1236   png_byte compression_type;
1237   png_bytep pC;
1238   png_charp profile;
1239   png_uint_32 skip = 0;
1240   png_uint_32 profile_size;
1241   png_alloc_size_t profile_length;
1242   png_size_t slength, prefix_length, data_length;
1243
1244   png_debug(1, "in png_handle_iCCP");
1245
1246   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1247      png_error(png_ptr, "Missing IHDR before iCCP");
1248
1249   else if (png_ptr->mode & PNG_HAVE_IDAT)
1250   {
1251      png_warning(png_ptr, "Invalid iCCP after IDAT");
1252      png_crc_finish(png_ptr, length);
1253      return;
1254   }
1255
1256   else if (png_ptr->mode & PNG_HAVE_PLTE)
1257      /* Should be an error, but we can cope with it */
1258      png_warning(png_ptr, "Out of place iCCP chunk");
1259
1260   if ((png_ptr->mode & PNG_HAVE_iCCP) || (info_ptr != NULL &&
1261      (info_ptr->valid & (PNG_INFO_iCCP|PNG_INFO_sRGB))))
1262   {
1263      png_warning(png_ptr, "Duplicate iCCP chunk");
1264      png_crc_finish(png_ptr, length);
1265      return;
1266   }
1267
1268   png_ptr->mode |= PNG_HAVE_iCCP;
1269
1270#ifdef PNG_MAX_MALLOC_64K
1271   if (length > (png_uint_32)65535L)
1272   {
1273      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1274      skip = length - (png_uint_32)65535L;
1275      length = (png_uint_32)65535L;
1276   }
1277#endif
1278
1279   png_free(png_ptr, png_ptr->chunkdata);
1280   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1281   slength = length;
1282   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1283
1284   if (png_crc_finish(png_ptr, skip))
1285   {
1286      png_free(png_ptr, png_ptr->chunkdata);
1287      png_ptr->chunkdata = NULL;
1288      return;
1289   }
1290
1291   png_ptr->chunkdata[slength] = 0x00;
1292
1293   for (profile = png_ptr->chunkdata; *profile; profile++)
1294      /* Empty loop to find end of name */ ;
1295
1296   ++profile;
1297
1298   /* There should be at least one zero (the compression type byte)
1299    * following the separator, and we should be on it
1300    */
1301   if (profile >= png_ptr->chunkdata + slength - 1)
1302   {
1303      png_free(png_ptr, png_ptr->chunkdata);
1304      png_ptr->chunkdata = NULL;
1305      png_warning(png_ptr, "Malformed iCCP chunk");
1306      return;
1307   }
1308
1309   /* Compression_type should always be zero */
1310   compression_type = *profile++;
1311
1312   if (compression_type)
1313   {
1314      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1315      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
1316                                 wrote nonzero) */
1317   }
1318
1319   prefix_length = profile - png_ptr->chunkdata;
1320   png_decompress_chunk(png_ptr, compression_type,
1321       slength, prefix_length, &data_length);
1322
1323   profile_length = data_length - prefix_length;
1324
1325   if (prefix_length > data_length || profile_length < 4)
1326   {
1327      png_free(png_ptr, png_ptr->chunkdata);
1328      png_ptr->chunkdata = NULL;
1329      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1330      return;
1331   }
1332
1333   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1334   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1335   profile_size = ((*(pC    )) << 24) |
1336                  ((*(pC + 1)) << 16) |
1337                  ((*(pC + 2)) <<  8) |
1338                  ((*(pC + 3))      );
1339
1340   /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
1341    * because profile_size is a 32 bit value.
1342    */
1343   if (profile_size < profile_length)
1344      profile_length = profile_size;
1345
1346   /* And the following guarantees that profile_size == profile_length. */
1347   if (profile_size > profile_length)
1348   {
1349      PNG_WARNING_PARAMETERS(p)
1350
1351      png_free(png_ptr, png_ptr->chunkdata);
1352      png_ptr->chunkdata = NULL;
1353
1354      png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size);
1355      png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length);
1356      png_formatted_warning(png_ptr, p,
1357         "Ignoring iCCP chunk with declared size = @1 and actual length = @2");
1358      return;
1359   }
1360
1361   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1362       compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
1363       profile_size);
1364   png_free(png_ptr, png_ptr->chunkdata);
1365   png_ptr->chunkdata = NULL;
1366}
1367#endif /* PNG_READ_iCCP_SUPPORTED */
1368
1369#ifdef PNG_READ_sPLT_SUPPORTED
1370void /* PRIVATE */
1371png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1372/* Note: this does not properly handle chunks that are > 64K under DOS */
1373{
1374   png_bytep entry_start;
1375   png_sPLT_t new_palette;
1376   png_sPLT_entryp pp;
1377   png_uint_32 data_length;
1378   int entry_size, i;
1379   png_uint_32 skip = 0;
1380   png_size_t slength;
1381   png_uint_32 dl;
1382   png_size_t max_dl;
1383
1384   png_debug(1, "in png_handle_sPLT");
1385
1386#ifdef PNG_USER_LIMITS_SUPPORTED
1387
1388   if (png_ptr->user_chunk_cache_max != 0)
1389   {
1390      if (png_ptr->user_chunk_cache_max == 1)
1391      {
1392         png_crc_finish(png_ptr, length);
1393         return;
1394      }
1395
1396      if (--png_ptr->user_chunk_cache_max == 1)
1397      {
1398         png_warning(png_ptr, "No space in chunk cache for sPLT");
1399         png_crc_finish(png_ptr, length);
1400         return;
1401      }
1402   }
1403#endif
1404
1405   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1406      png_error(png_ptr, "Missing IHDR before sPLT");
1407
1408   else if (png_ptr->mode & PNG_HAVE_IDAT)
1409   {
1410      png_warning(png_ptr, "Invalid sPLT after IDAT");
1411      png_crc_finish(png_ptr, length);
1412      return;
1413   }
1414
1415#ifdef PNG_MAX_MALLOC_64K
1416   if (length > (png_uint_32)65535L)
1417   {
1418      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1419      skip = length - (png_uint_32)65535L;
1420      length = (png_uint_32)65535L;
1421   }
1422#endif
1423
1424   png_free(png_ptr, png_ptr->chunkdata);
1425   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1426
1427   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
1428    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
1429    * potential breakage point if the types in pngconf.h aren't exactly right.
1430    */
1431   slength = length;
1432   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1433
1434   if (png_crc_finish(png_ptr, skip))
1435   {
1436      png_free(png_ptr, png_ptr->chunkdata);
1437      png_ptr->chunkdata = NULL;
1438      return;
1439   }
1440
1441   png_ptr->chunkdata[slength] = 0x00;
1442
1443   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1444       entry_start++)
1445      /* Empty loop to find end of name */ ;
1446
1447   ++entry_start;
1448
1449   /* A sample depth should follow the separator, and we should be on it  */
1450   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1451   {
1452      png_free(png_ptr, png_ptr->chunkdata);
1453      png_ptr->chunkdata = NULL;
1454      png_warning(png_ptr, "malformed sPLT chunk");
1455      return;
1456   }
1457
1458   new_palette.depth = *entry_start++;
1459   entry_size = (new_palette.depth == 8 ? 6 : 10);
1460   /* This must fit in a png_uint_32 because it is derived from the original
1461    * chunk data length (and use 'length', not 'slength' here for clarity -
1462    * they are guaranteed to be the same, see the tests above.)
1463    */
1464   data_length = length - (png_uint_32)(entry_start -
1465      (png_bytep)png_ptr->chunkdata);
1466
1467   /* Integrity-check the data length */
1468   if (data_length % entry_size)
1469   {
1470      png_free(png_ptr, png_ptr->chunkdata);
1471      png_ptr->chunkdata = NULL;
1472      png_warning(png_ptr, "sPLT chunk has bad length");
1473      return;
1474   }
1475
1476   dl = (png_int_32)(data_length / entry_size);
1477   max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry);
1478
1479   if (dl > max_dl)
1480   {
1481       png_warning(png_ptr, "sPLT chunk too long");
1482       return;
1483   }
1484
1485   new_palette.nentries = (png_int_32)(data_length / entry_size);
1486
1487   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1488       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1489
1490   if (new_palette.entries == NULL)
1491   {
1492       png_warning(png_ptr, "sPLT chunk requires too much memory");
1493       return;
1494   }
1495
1496#ifdef PNG_POINTER_INDEXING_SUPPORTED
1497   for (i = 0; i < new_palette.nentries; i++)
1498   {
1499      pp = new_palette.entries + i;
1500
1501      if (new_palette.depth == 8)
1502      {
1503         pp->red = *entry_start++;
1504         pp->green = *entry_start++;
1505         pp->blue = *entry_start++;
1506         pp->alpha = *entry_start++;
1507      }
1508
1509      else
1510      {
1511         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1512         pp->green = png_get_uint_16(entry_start); entry_start += 2;
1513         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1514         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1515      }
1516
1517      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1518   }
1519#else
1520   pp = new_palette.entries;
1521
1522   for (i = 0; i < new_palette.nentries; i++)
1523   {
1524
1525      if (new_palette.depth == 8)
1526      {
1527         pp[i].red   = *entry_start++;
1528         pp[i].green = *entry_start++;
1529         pp[i].blue  = *entry_start++;
1530         pp[i].alpha = *entry_start++;
1531      }
1532
1533      else
1534      {
1535         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
1536         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1537         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
1538         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1539      }
1540
1541      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
1542   }
1543#endif
1544
1545   /* Discard all chunk data except the name and stash that */
1546   new_palette.name = png_ptr->chunkdata;
1547
1548   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1549
1550   png_free(png_ptr, png_ptr->chunkdata);
1551   png_ptr->chunkdata = NULL;
1552   png_free(png_ptr, new_palette.entries);
1553}
1554#endif /* PNG_READ_sPLT_SUPPORTED */
1555
1556#ifdef PNG_READ_tRNS_SUPPORTED
1557void /* PRIVATE */
1558png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1559{
1560   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1561
1562   png_debug(1, "in png_handle_tRNS");
1563
1564   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1565      png_error(png_ptr, "Missing IHDR before tRNS");
1566
1567   else if (png_ptr->mode & PNG_HAVE_IDAT)
1568   {
1569      png_warning(png_ptr, "Invalid tRNS after IDAT");
1570      png_crc_finish(png_ptr, length);
1571      return;
1572   }
1573
1574   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1575   {
1576      png_warning(png_ptr, "Duplicate tRNS chunk");
1577      png_crc_finish(png_ptr, length);
1578      return;
1579   }
1580
1581   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1582   {
1583      png_byte buf[2];
1584
1585      if (length != 2)
1586      {
1587         png_warning(png_ptr, "Incorrect tRNS chunk length");
1588         png_crc_finish(png_ptr, length);
1589         return;
1590      }
1591
1592      png_crc_read(png_ptr, buf, 2);
1593      png_ptr->num_trans = 1;
1594      png_ptr->trans_color.gray = png_get_uint_16(buf);
1595   }
1596
1597   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1598   {
1599      png_byte buf[6];
1600
1601      if (length != 6)
1602      {
1603         png_warning(png_ptr, "Incorrect tRNS chunk length");
1604         png_crc_finish(png_ptr, length);
1605         return;
1606      }
1607
1608      png_crc_read(png_ptr, buf, (png_size_t)length);
1609      png_ptr->num_trans = 1;
1610      png_ptr->trans_color.red = png_get_uint_16(buf);
1611      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
1612      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
1613   }
1614
1615   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1616   {
1617      if (!(png_ptr->mode & PNG_HAVE_PLTE))
1618      {
1619         /* Should be an error, but we can cope with it. */
1620         png_warning(png_ptr, "Missing PLTE before tRNS");
1621      }
1622
1623      if (length > (png_uint_32)png_ptr->num_palette ||
1624          length > PNG_MAX_PALETTE_LENGTH)
1625      {
1626         png_warning(png_ptr, "Incorrect tRNS chunk length");
1627         png_crc_finish(png_ptr, length);
1628         return;
1629      }
1630
1631      if (length == 0)
1632      {
1633         png_warning(png_ptr, "Zero length tRNS chunk");
1634         png_crc_finish(png_ptr, length);
1635         return;
1636      }
1637
1638      png_crc_read(png_ptr, readbuf, (png_size_t)length);
1639      png_ptr->num_trans = (png_uint_16)length;
1640   }
1641
1642   else
1643   {
1644      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1645      png_crc_finish(png_ptr, length);
1646      return;
1647   }
1648
1649   if (png_crc_finish(png_ptr, 0))
1650   {
1651      png_ptr->num_trans = 0;
1652      return;
1653   }
1654
1655   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1656       &(png_ptr->trans_color));
1657}
1658#endif
1659
1660#ifdef PNG_READ_bKGD_SUPPORTED
1661void /* PRIVATE */
1662png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1663{
1664   png_size_t truelen;
1665   png_byte buf[6];
1666   png_color_16 background;
1667
1668   png_debug(1, "in png_handle_bKGD");
1669
1670   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1671      png_error(png_ptr, "Missing IHDR before bKGD");
1672
1673   else if (png_ptr->mode & PNG_HAVE_IDAT)
1674   {
1675      png_warning(png_ptr, "Invalid bKGD after IDAT");
1676      png_crc_finish(png_ptr, length);
1677      return;
1678   }
1679
1680   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1681       !(png_ptr->mode & PNG_HAVE_PLTE))
1682   {
1683      png_warning(png_ptr, "Missing PLTE before bKGD");
1684      png_crc_finish(png_ptr, length);
1685      return;
1686   }
1687
1688   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1689   {
1690      png_warning(png_ptr, "Duplicate bKGD chunk");
1691      png_crc_finish(png_ptr, length);
1692      return;
1693   }
1694
1695   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1696      truelen = 1;
1697
1698   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1699      truelen = 6;
1700
1701   else
1702      truelen = 2;
1703
1704   if (length != truelen)
1705   {
1706      png_warning(png_ptr, "Incorrect bKGD chunk length");
1707      png_crc_finish(png_ptr, length);
1708      return;
1709   }
1710
1711   png_crc_read(png_ptr, buf, truelen);
1712
1713   if (png_crc_finish(png_ptr, 0))
1714      return;
1715
1716   /* We convert the index value into RGB components so that we can allow
1717    * arbitrary RGB values for background when we have transparency, and
1718    * so it is easy to determine the RGB values of the background color
1719    * from the info_ptr struct.
1720    */
1721   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1722   {
1723      background.index = buf[0];
1724
1725      if (info_ptr && info_ptr->num_palette)
1726      {
1727         if (buf[0] >= info_ptr->num_palette)
1728         {
1729            png_warning(png_ptr, "Incorrect bKGD chunk index value");
1730            return;
1731         }
1732
1733         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
1734         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
1735         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
1736      }
1737
1738      else
1739         background.red = background.green = background.blue = 0;
1740
1741      background.gray = 0;
1742   }
1743
1744   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1745   {
1746      background.index = 0;
1747      background.red =
1748      background.green =
1749      background.blue =
1750      background.gray = png_get_uint_16(buf);
1751   }
1752
1753   else
1754   {
1755      background.index = 0;
1756      background.red = png_get_uint_16(buf);
1757      background.green = png_get_uint_16(buf + 2);
1758      background.blue = png_get_uint_16(buf + 4);
1759      background.gray = 0;
1760   }
1761
1762   png_set_bKGD(png_ptr, info_ptr, &background);
1763}
1764#endif
1765
1766#ifdef PNG_READ_hIST_SUPPORTED
1767void /* PRIVATE */
1768png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1769{
1770   unsigned int num, i;
1771   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1772
1773   png_debug(1, "in png_handle_hIST");
1774
1775   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1776      png_error(png_ptr, "Missing IHDR before hIST");
1777
1778   else if (png_ptr->mode & PNG_HAVE_IDAT)
1779   {
1780      png_warning(png_ptr, "Invalid hIST after IDAT");
1781      png_crc_finish(png_ptr, length);
1782      return;
1783   }
1784
1785   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1786   {
1787      png_warning(png_ptr, "Missing PLTE before hIST");
1788      png_crc_finish(png_ptr, length);
1789      return;
1790   }
1791
1792   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1793   {
1794      png_warning(png_ptr, "Duplicate hIST chunk");
1795      png_crc_finish(png_ptr, length);
1796      return;
1797   }
1798
1799   if (length > 2*PNG_MAX_PALETTE_LENGTH ||
1800       length != (unsigned int) (2*png_ptr->num_palette))
1801   {
1802      png_warning(png_ptr, "Incorrect hIST chunk length");
1803      png_crc_finish(png_ptr, length);
1804      return;
1805   }
1806
1807   num = length / 2 ;
1808
1809   for (i = 0; i < num; i++)
1810   {
1811      png_byte buf[2];
1812
1813      png_crc_read(png_ptr, buf, 2);
1814      readbuf[i] = png_get_uint_16(buf);
1815   }
1816
1817   if (png_crc_finish(png_ptr, 0))
1818      return;
1819
1820   png_set_hIST(png_ptr, info_ptr, readbuf);
1821}
1822#endif
1823
1824#ifdef PNG_READ_pHYs_SUPPORTED
1825void /* PRIVATE */
1826png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1827{
1828   png_byte buf[9];
1829   png_uint_32 res_x, res_y;
1830   int unit_type;
1831
1832   png_debug(1, "in png_handle_pHYs");
1833
1834   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1835      png_error(png_ptr, "Missing IHDR before pHYs");
1836
1837   else if (png_ptr->mode & PNG_HAVE_IDAT)
1838   {
1839      png_warning(png_ptr, "Invalid pHYs after IDAT");
1840      png_crc_finish(png_ptr, length);
1841      return;
1842   }
1843
1844   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1845   {
1846      png_warning(png_ptr, "Duplicate pHYs chunk");
1847      png_crc_finish(png_ptr, length);
1848      return;
1849   }
1850
1851   if (length != 9)
1852   {
1853      png_warning(png_ptr, "Incorrect pHYs chunk length");
1854      png_crc_finish(png_ptr, length);
1855      return;
1856   }
1857
1858   png_crc_read(png_ptr, buf, 9);
1859
1860   if (png_crc_finish(png_ptr, 0))
1861      return;
1862
1863   res_x = png_get_uint_32(buf);
1864   res_y = png_get_uint_32(buf + 4);
1865   unit_type = buf[8];
1866   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1867}
1868#endif
1869
1870#ifdef PNG_READ_oFFs_SUPPORTED
1871void /* PRIVATE */
1872png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1873{
1874   png_byte buf[9];
1875   png_int_32 offset_x, offset_y;
1876   int unit_type;
1877
1878   png_debug(1, "in png_handle_oFFs");
1879
1880   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1881      png_error(png_ptr, "Missing IHDR before oFFs");
1882
1883   else if (png_ptr->mode & PNG_HAVE_IDAT)
1884   {
1885      png_warning(png_ptr, "Invalid oFFs after IDAT");
1886      png_crc_finish(png_ptr, length);
1887      return;
1888   }
1889
1890   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1891   {
1892      png_warning(png_ptr, "Duplicate oFFs chunk");
1893      png_crc_finish(png_ptr, length);
1894      return;
1895   }
1896
1897   if (length != 9)
1898   {
1899      png_warning(png_ptr, "Incorrect oFFs chunk length");
1900      png_crc_finish(png_ptr, length);
1901      return;
1902   }
1903
1904   png_crc_read(png_ptr, buf, 9);
1905
1906   if (png_crc_finish(png_ptr, 0))
1907      return;
1908
1909   offset_x = png_get_int_32(buf);
1910   offset_y = png_get_int_32(buf + 4);
1911   unit_type = buf[8];
1912   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1913}
1914#endif
1915
1916#ifdef PNG_READ_pCAL_SUPPORTED
1917/* Read the pCAL chunk (described in the PNG Extensions document) */
1918void /* PRIVATE */
1919png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1920{
1921   png_int_32 X0, X1;
1922   png_byte type, nparams;
1923   png_charp buf, units, endptr;
1924   png_charpp params;
1925   png_size_t slength;
1926   int i;
1927
1928   png_debug(1, "in png_handle_pCAL");
1929
1930   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1931      png_error(png_ptr, "Missing IHDR before pCAL");
1932
1933   else if (png_ptr->mode & PNG_HAVE_IDAT)
1934   {
1935      png_warning(png_ptr, "Invalid pCAL after IDAT");
1936      png_crc_finish(png_ptr, length);
1937      return;
1938   }
1939
1940   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1941   {
1942      png_warning(png_ptr, "Duplicate pCAL chunk");
1943      png_crc_finish(png_ptr, length);
1944      return;
1945   }
1946
1947   png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
1948       length + 1);
1949   png_free(png_ptr, png_ptr->chunkdata);
1950   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1951
1952   if (png_ptr->chunkdata == NULL)
1953   {
1954      png_warning(png_ptr, "No memory for pCAL purpose");
1955      return;
1956   }
1957
1958   slength = length;
1959   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1960
1961   if (png_crc_finish(png_ptr, 0))
1962   {
1963      png_free(png_ptr, png_ptr->chunkdata);
1964      png_ptr->chunkdata = NULL;
1965      return;
1966   }
1967
1968   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1969
1970   png_debug(3, "Finding end of pCAL purpose string");
1971   for (buf = png_ptr->chunkdata; *buf; buf++)
1972      /* Empty loop */ ;
1973
1974   endptr = png_ptr->chunkdata + slength;
1975
1976   /* We need to have at least 12 bytes after the purpose string
1977    * in order to get the parameter information.
1978    */
1979   if (endptr <= buf + 12)
1980   {
1981      png_warning(png_ptr, "Invalid pCAL data");
1982      png_free(png_ptr, png_ptr->chunkdata);
1983      png_ptr->chunkdata = NULL;
1984      return;
1985   }
1986
1987   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1988   X0 = png_get_int_32((png_bytep)buf+1);
1989   X1 = png_get_int_32((png_bytep)buf+5);
1990   type = buf[9];
1991   nparams = buf[10];
1992   units = buf + 11;
1993
1994   png_debug(3, "Checking pCAL equation type and number of parameters");
1995   /* Check that we have the right number of parameters for known
1996    * equation types.
1997    */
1998   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1999       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
2000       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
2001       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
2002   {
2003      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
2004      png_free(png_ptr, png_ptr->chunkdata);
2005      png_ptr->chunkdata = NULL;
2006      return;
2007   }
2008
2009   else if (type >= PNG_EQUATION_LAST)
2010   {
2011      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
2012   }
2013
2014   for (buf = units; *buf; buf++)
2015      /* Empty loop to move past the units string. */ ;
2016
2017   png_debug(3, "Allocating pCAL parameters array");
2018
2019   params = (png_charpp)png_malloc_warn(png_ptr,
2020       (png_size_t)(nparams * png_sizeof(png_charp)));
2021
2022   if (params == NULL)
2023   {
2024      png_free(png_ptr, png_ptr->chunkdata);
2025      png_ptr->chunkdata = NULL;
2026      png_warning(png_ptr, "No memory for pCAL params");
2027      return;
2028   }
2029
2030   /* Get pointers to the start of each parameter string. */
2031   for (i = 0; i < (int)nparams; i++)
2032   {
2033      buf++; /* Skip the null string terminator from previous parameter. */
2034
2035      png_debug1(3, "Reading pCAL parameter %d", i);
2036
2037      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
2038         /* Empty loop to move past each parameter string */ ;
2039
2040      /* Make sure we haven't run out of data yet */
2041      if (buf > endptr)
2042      {
2043         png_warning(png_ptr, "Invalid pCAL data");
2044         png_free(png_ptr, png_ptr->chunkdata);
2045         png_ptr->chunkdata = NULL;
2046         png_free(png_ptr, params);
2047         return;
2048      }
2049   }
2050
2051   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
2052      units, params);
2053
2054   png_free(png_ptr, png_ptr->chunkdata);
2055   png_ptr->chunkdata = NULL;
2056   png_free(png_ptr, params);
2057}
2058#endif
2059
2060#ifdef PNG_READ_sCAL_SUPPORTED
2061/* Read the sCAL chunk */
2062void /* PRIVATE */
2063png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2064{
2065   png_size_t slength, i;
2066   int state;
2067
2068   png_debug(1, "in png_handle_sCAL");
2069
2070   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2071      png_error(png_ptr, "Missing IHDR before sCAL");
2072
2073   else if (png_ptr->mode & PNG_HAVE_IDAT)
2074   {
2075      png_warning(png_ptr, "Invalid sCAL after IDAT");
2076      png_crc_finish(png_ptr, length);
2077      return;
2078   }
2079
2080   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
2081   {
2082      png_warning(png_ptr, "Duplicate sCAL chunk");
2083      png_crc_finish(png_ptr, length);
2084      return;
2085   }
2086
2087   /* Need unit type, width, \0, height: minimum 4 bytes */
2088   else if (length < 4)
2089   {
2090      png_warning(png_ptr, "sCAL chunk too short");
2091      png_crc_finish(png_ptr, length);
2092      return;
2093   }
2094
2095   png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
2096      length + 1);
2097
2098   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2099
2100   if (png_ptr->chunkdata == NULL)
2101   {
2102      png_warning(png_ptr, "Out of memory while processing sCAL chunk");
2103      png_crc_finish(png_ptr, length);
2104      return;
2105   }
2106
2107   slength = length;
2108   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2109   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
2110
2111   if (png_crc_finish(png_ptr, 0))
2112   {
2113      png_free(png_ptr, png_ptr->chunkdata);
2114      png_ptr->chunkdata = NULL;
2115      return;
2116   }
2117
2118   /* Validate the unit. */
2119   if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2)
2120   {
2121      png_warning(png_ptr, "Invalid sCAL ignored: invalid unit");
2122      png_free(png_ptr, png_ptr->chunkdata);
2123      png_ptr->chunkdata = NULL;
2124      return;
2125   }
2126
2127   /* Validate the ASCII numbers, need two ASCII numbers separated by
2128    * a '\0' and they need to fit exactly in the chunk data.
2129    */
2130   i = 1;
2131   state = 0;
2132
2133   if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
2134       i >= slength || png_ptr->chunkdata[i++] != 0)
2135      png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format");
2136
2137   else if (!PNG_FP_IS_POSITIVE(state))
2138      png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width");
2139
2140   else
2141   {
2142      png_size_t heighti = i;
2143
2144      state = 0;
2145      if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
2146          i != slength)
2147         png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format");
2148
2149      else if (!PNG_FP_IS_POSITIVE(state))
2150         png_warning(png_ptr,
2151            "Invalid sCAL chunk ignored: non-positive height");
2152
2153      else
2154         /* This is the (only) success case. */
2155         png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0],
2156            png_ptr->chunkdata+1, png_ptr->chunkdata+heighti);
2157   }
2158
2159   /* Clean up - just free the temporarily allocated buffer. */
2160   png_free(png_ptr, png_ptr->chunkdata);
2161   png_ptr->chunkdata = NULL;
2162}
2163#endif
2164
2165#ifdef PNG_READ_tIME_SUPPORTED
2166void /* PRIVATE */
2167png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2168{
2169   png_byte buf[7];
2170   png_time mod_time;
2171
2172   png_debug(1, "in png_handle_tIME");
2173
2174   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2175      png_error(png_ptr, "Out of place tIME chunk");
2176
2177   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
2178   {
2179      png_warning(png_ptr, "Duplicate tIME chunk");
2180      png_crc_finish(png_ptr, length);
2181      return;
2182   }
2183
2184   if (png_ptr->mode & PNG_HAVE_IDAT)
2185      png_ptr->mode |= PNG_AFTER_IDAT;
2186
2187   if (length != 7)
2188   {
2189      png_warning(png_ptr, "Incorrect tIME chunk length");
2190      png_crc_finish(png_ptr, length);
2191      return;
2192   }
2193
2194   png_crc_read(png_ptr, buf, 7);
2195
2196   if (png_crc_finish(png_ptr, 0))
2197      return;
2198
2199   mod_time.second = buf[6];
2200   mod_time.minute = buf[5];
2201   mod_time.hour = buf[4];
2202   mod_time.day = buf[3];
2203   mod_time.month = buf[2];
2204   mod_time.year = png_get_uint_16(buf);
2205
2206   png_set_tIME(png_ptr, info_ptr, &mod_time);
2207}
2208#endif
2209
2210#ifdef PNG_READ_tEXt_SUPPORTED
2211/* Note: this does not properly handle chunks that are > 64K under DOS */
2212void /* PRIVATE */
2213png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2214{
2215   png_textp text_ptr;
2216   png_charp key;
2217   png_charp text;
2218   png_uint_32 skip = 0;
2219   png_size_t slength;
2220   int ret;
2221
2222   png_debug(1, "in png_handle_tEXt");
2223
2224#ifdef PNG_USER_LIMITS_SUPPORTED
2225   if (png_ptr->user_chunk_cache_max != 0)
2226   {
2227      if (png_ptr->user_chunk_cache_max == 1)
2228      {
2229         png_crc_finish(png_ptr, length);
2230         return;
2231      }
2232
2233      if (--png_ptr->user_chunk_cache_max == 1)
2234      {
2235         png_warning(png_ptr, "No space in chunk cache for tEXt");
2236         png_crc_finish(png_ptr, length);
2237         return;
2238      }
2239   }
2240#endif
2241
2242   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2243      png_error(png_ptr, "Missing IHDR before tEXt");
2244
2245   if (png_ptr->mode & PNG_HAVE_IDAT)
2246      png_ptr->mode |= PNG_AFTER_IDAT;
2247
2248#ifdef PNG_MAX_MALLOC_64K
2249   if (length > (png_uint_32)65535L)
2250   {
2251      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2252      skip = length - (png_uint_32)65535L;
2253      length = (png_uint_32)65535L;
2254   }
2255#endif
2256
2257   png_free(png_ptr, png_ptr->chunkdata);
2258
2259   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2260
2261   if (png_ptr->chunkdata == NULL)
2262   {
2263     png_warning(png_ptr, "No memory to process text chunk");
2264     return;
2265   }
2266
2267   slength = length;
2268   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2269
2270   if (png_crc_finish(png_ptr, skip))
2271   {
2272      png_free(png_ptr, png_ptr->chunkdata);
2273      png_ptr->chunkdata = NULL;
2274      return;
2275   }
2276
2277   key = png_ptr->chunkdata;
2278
2279   key[slength] = 0x00;
2280
2281   for (text = key; *text; text++)
2282      /* Empty loop to find end of key */ ;
2283
2284   if (text != key + slength)
2285      text++;
2286
2287   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2288       png_sizeof(png_text));
2289
2290   if (text_ptr == NULL)
2291   {
2292      png_warning(png_ptr, "Not enough memory to process text chunk");
2293      png_free(png_ptr, png_ptr->chunkdata);
2294      png_ptr->chunkdata = NULL;
2295      return;
2296   }
2297
2298   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2299   text_ptr->key = key;
2300   text_ptr->lang = NULL;
2301   text_ptr->lang_key = NULL;
2302   text_ptr->itxt_length = 0;
2303   text_ptr->text = text;
2304   text_ptr->text_length = png_strlen(text);
2305
2306   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2307
2308   png_free(png_ptr, png_ptr->chunkdata);
2309   png_ptr->chunkdata = NULL;
2310   png_free(png_ptr, text_ptr);
2311
2312   if (ret)
2313      png_warning(png_ptr, "Insufficient memory to process text chunk");
2314}
2315#endif
2316
2317#ifdef PNG_READ_zTXt_SUPPORTED
2318/* Note: this does not correctly handle chunks that are > 64K under DOS */
2319void /* PRIVATE */
2320png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2321{
2322   png_textp text_ptr;
2323   png_charp text;
2324   int comp_type;
2325   int ret;
2326   png_size_t slength, prefix_len, data_len;
2327
2328   png_debug(1, "in png_handle_zTXt");
2329
2330#ifdef PNG_USER_LIMITS_SUPPORTED
2331   if (png_ptr->user_chunk_cache_max != 0)
2332   {
2333      if (png_ptr->user_chunk_cache_max == 1)
2334      {
2335         png_crc_finish(png_ptr, length);
2336         return;
2337      }
2338
2339      if (--png_ptr->user_chunk_cache_max == 1)
2340      {
2341         png_warning(png_ptr, "No space in chunk cache for zTXt");
2342         png_crc_finish(png_ptr, length);
2343         return;
2344      }
2345   }
2346#endif
2347
2348   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2349      png_error(png_ptr, "Missing IHDR before zTXt");
2350
2351   if (png_ptr->mode & PNG_HAVE_IDAT)
2352      png_ptr->mode |= PNG_AFTER_IDAT;
2353
2354#ifdef PNG_MAX_MALLOC_64K
2355   /* We will no doubt have problems with chunks even half this size, but
2356    * there is no hard and fast rule to tell us where to stop.
2357    */
2358   if (length > (png_uint_32)65535L)
2359   {
2360      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2361      png_crc_finish(png_ptr, length);
2362      return;
2363   }
2364#endif
2365
2366   png_free(png_ptr, png_ptr->chunkdata);
2367   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2368
2369   if (png_ptr->chunkdata == NULL)
2370   {
2371      png_warning(png_ptr, "Out of memory processing zTXt chunk");
2372      return;
2373   }
2374
2375   slength = length;
2376   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2377
2378   if (png_crc_finish(png_ptr, 0))
2379   {
2380      png_free(png_ptr, png_ptr->chunkdata);
2381      png_ptr->chunkdata = NULL;
2382      return;
2383   }
2384
2385   png_ptr->chunkdata[slength] = 0x00;
2386
2387   for (text = png_ptr->chunkdata; *text; text++)
2388      /* Empty loop */ ;
2389
2390   /* zTXt must have some text after the chunkdataword */
2391   if (text >= png_ptr->chunkdata + slength - 2)
2392   {
2393      png_warning(png_ptr, "Truncated zTXt chunk");
2394      png_free(png_ptr, png_ptr->chunkdata);
2395      png_ptr->chunkdata = NULL;
2396      return;
2397   }
2398
2399   else
2400   {
2401       comp_type = *(++text);
2402
2403       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2404       {
2405          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2406          comp_type = PNG_TEXT_COMPRESSION_zTXt;
2407       }
2408
2409       text++;        /* Skip the compression_method byte */
2410   }
2411
2412   prefix_len = text - png_ptr->chunkdata;
2413
2414   png_decompress_chunk(png_ptr, comp_type,
2415       (png_size_t)length, prefix_len, &data_len);
2416
2417   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2418       png_sizeof(png_text));
2419
2420   if (text_ptr == NULL)
2421   {
2422      png_warning(png_ptr, "Not enough memory to process zTXt chunk");
2423      png_free(png_ptr, png_ptr->chunkdata);
2424      png_ptr->chunkdata = NULL;
2425      return;
2426   }
2427
2428   text_ptr->compression = comp_type;
2429   text_ptr->key = png_ptr->chunkdata;
2430   text_ptr->lang = NULL;
2431   text_ptr->lang_key = NULL;
2432   text_ptr->itxt_length = 0;
2433   text_ptr->text = png_ptr->chunkdata + prefix_len;
2434   text_ptr->text_length = data_len;
2435
2436   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2437
2438   png_free(png_ptr, text_ptr);
2439   png_free(png_ptr, png_ptr->chunkdata);
2440   png_ptr->chunkdata = NULL;
2441
2442   if (ret)
2443      png_error(png_ptr, "Insufficient memory to store zTXt chunk");
2444}
2445#endif
2446
2447#ifdef PNG_READ_iTXt_SUPPORTED
2448/* Note: this does not correctly handle chunks that are > 64K under DOS */
2449void /* PRIVATE */
2450png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2451{
2452   png_textp text_ptr;
2453   png_charp key, lang, text, lang_key;
2454   int comp_flag;
2455   int comp_type = 0;
2456   int ret;
2457   png_size_t slength, prefix_len, data_len;
2458
2459   png_debug(1, "in png_handle_iTXt");
2460
2461#ifdef PNG_USER_LIMITS_SUPPORTED
2462   if (png_ptr->user_chunk_cache_max != 0)
2463   {
2464      if (png_ptr->user_chunk_cache_max == 1)
2465      {
2466         png_crc_finish(png_ptr, length);
2467         return;
2468      }
2469
2470      if (--png_ptr->user_chunk_cache_max == 1)
2471      {
2472         png_warning(png_ptr, "No space in chunk cache for iTXt");
2473         png_crc_finish(png_ptr, length);
2474         return;
2475      }
2476   }
2477#endif
2478
2479   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2480      png_error(png_ptr, "Missing IHDR before iTXt");
2481
2482   if (png_ptr->mode & PNG_HAVE_IDAT)
2483      png_ptr->mode |= PNG_AFTER_IDAT;
2484
2485#ifdef PNG_MAX_MALLOC_64K
2486   /* We will no doubt have problems with chunks even half this size, but
2487    * there is no hard and fast rule to tell us where to stop.
2488    */
2489   if (length > (png_uint_32)65535L)
2490   {
2491      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2492      png_crc_finish(png_ptr, length);
2493      return;
2494   }
2495#endif
2496
2497   png_free(png_ptr, png_ptr->chunkdata);
2498   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2499
2500   if (png_ptr->chunkdata == NULL)
2501   {
2502      png_warning(png_ptr, "No memory to process iTXt chunk");
2503      return;
2504   }
2505
2506   slength = length;
2507   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2508
2509   if (png_crc_finish(png_ptr, 0))
2510   {
2511      png_free(png_ptr, png_ptr->chunkdata);
2512      png_ptr->chunkdata = NULL;
2513      return;
2514   }
2515
2516   png_ptr->chunkdata[slength] = 0x00;
2517
2518   for (lang = png_ptr->chunkdata; *lang; lang++)
2519      /* Empty loop */ ;
2520
2521   lang++;        /* Skip NUL separator */
2522
2523   /* iTXt must have a language tag (possibly empty), two compression bytes,
2524    * translated keyword (possibly empty), and possibly some text after the
2525    * keyword
2526    */
2527
2528   if (lang >= png_ptr->chunkdata + slength - 3)
2529   {
2530      png_warning(png_ptr, "Truncated iTXt chunk");
2531      png_free(png_ptr, png_ptr->chunkdata);
2532      png_ptr->chunkdata = NULL;
2533      return;
2534   }
2535
2536   else
2537   {
2538      comp_flag = *lang++;
2539      comp_type = *lang++;
2540   }
2541
2542   if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt))
2543   {
2544      png_warning(png_ptr, "Unknown iTXt compression type or method");
2545      png_free(png_ptr, png_ptr->chunkdata);
2546      png_ptr->chunkdata = NULL;
2547      return;
2548   }
2549
2550   for (lang_key = lang; *lang_key; lang_key++)
2551      /* Empty loop */ ;
2552
2553   lang_key++;        /* Skip NUL separator */
2554
2555   if (lang_key >= png_ptr->chunkdata + slength)
2556   {
2557      png_warning(png_ptr, "Truncated iTXt chunk");
2558      png_free(png_ptr, png_ptr->chunkdata);
2559      png_ptr->chunkdata = NULL;
2560      return;
2561   }
2562
2563   for (text = lang_key; *text; text++)
2564      /* Empty loop */ ;
2565
2566   text++;        /* Skip NUL separator */
2567
2568   if (text >= png_ptr->chunkdata + slength)
2569   {
2570      png_warning(png_ptr, "Malformed iTXt chunk");
2571      png_free(png_ptr, png_ptr->chunkdata);
2572      png_ptr->chunkdata = NULL;
2573      return;
2574   }
2575
2576   prefix_len = text - png_ptr->chunkdata;
2577
2578   key=png_ptr->chunkdata;
2579
2580   if (comp_flag)
2581      png_decompress_chunk(png_ptr, comp_type,
2582          (size_t)length, prefix_len, &data_len);
2583
2584   else
2585      data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2586
2587   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2588       png_sizeof(png_text));
2589
2590   if (text_ptr == NULL)
2591   {
2592      png_warning(png_ptr, "Not enough memory to process iTXt chunk");
2593      png_free(png_ptr, png_ptr->chunkdata);
2594      png_ptr->chunkdata = NULL;
2595      return;
2596   }
2597
2598   text_ptr->compression = (int)comp_flag + 1;
2599   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2600   text_ptr->lang = png_ptr->chunkdata + (lang - key);
2601   text_ptr->itxt_length = data_len;
2602   text_ptr->text_length = 0;
2603   text_ptr->key = png_ptr->chunkdata;
2604   text_ptr->text = png_ptr->chunkdata + prefix_len;
2605
2606   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2607
2608   png_free(png_ptr, text_ptr);
2609   png_free(png_ptr, png_ptr->chunkdata);
2610   png_ptr->chunkdata = NULL;
2611
2612   if (ret)
2613      png_error(png_ptr, "Insufficient memory to store iTXt chunk");
2614}
2615#endif
2616
2617/* This function is called when we haven't found a handler for a
2618 * chunk.  If there isn't a problem with the chunk itself (ie bad
2619 * chunk name, CRC, or a critical chunk), the chunk is silently ignored
2620 * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2621 * case it will be saved away to be written out later.
2622 */
2623void /* PRIVATE */
2624png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2625{
2626   png_uint_32 skip = 0;
2627
2628   png_debug(1, "in png_handle_unknown");
2629
2630#ifdef PNG_USER_LIMITS_SUPPORTED
2631   if (png_ptr->user_chunk_cache_max != 0)
2632   {
2633      if (png_ptr->user_chunk_cache_max == 1)
2634      {
2635         png_crc_finish(png_ptr, length);
2636         return;
2637      }
2638
2639      if (--png_ptr->user_chunk_cache_max == 1)
2640      {
2641         png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2642         png_crc_finish(png_ptr, length);
2643         return;
2644      }
2645   }
2646#endif
2647
2648   if (png_ptr->mode & PNG_HAVE_IDAT)
2649   {
2650      if (png_ptr->chunk_name != png_IDAT)
2651         png_ptr->mode |= PNG_AFTER_IDAT;
2652   }
2653
2654   if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
2655   {
2656#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2657      if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
2658          PNG_HANDLE_CHUNK_ALWAYS
2659#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2660          && png_ptr->read_user_chunk_fn == NULL
2661#endif
2662          )
2663#endif
2664         png_chunk_error(png_ptr, "unknown critical chunk");
2665   }
2666
2667#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2668   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2669#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2670       || (png_ptr->read_user_chunk_fn != NULL)
2671#endif
2672       )
2673   {
2674#ifdef PNG_MAX_MALLOC_64K
2675      if (length > 65535)
2676      {
2677         png_warning(png_ptr, "unknown chunk too large to fit in memory");
2678         skip = length - 65535;
2679         length = 65535;
2680      }
2681#endif
2682
2683      /* TODO: this code is very close to the unknown handling in pngpread.c,
2684       * maybe it can be put into a common utility routine?
2685       * png_struct::unknown_chunk is just used as a temporary variable, along
2686       * with the data into which the chunk is read.  These can be eliminated.
2687       */
2688      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
2689      png_ptr->unknown_chunk.size = (png_size_t)length;
2690
2691      if (length == 0)
2692         png_ptr->unknown_chunk.data = NULL;
2693
2694      else
2695      {
2696         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2697         png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
2698      }
2699
2700#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2701      if (png_ptr->read_user_chunk_fn != NULL)
2702      {
2703         /* Callback to user unknown chunk handler */
2704         int ret;
2705
2706         ret = (*(png_ptr->read_user_chunk_fn))
2707             (png_ptr, &png_ptr->unknown_chunk);
2708
2709         if (ret < 0)
2710            png_chunk_error(png_ptr, "error in user chunk");
2711
2712         if (ret == 0)
2713         {
2714            if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
2715            {
2716#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2717               if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
2718                   PNG_HANDLE_CHUNK_ALWAYS)
2719#endif
2720                  png_chunk_error(png_ptr, "unknown critical chunk");
2721            }
2722
2723            png_set_unknown_chunks(png_ptr, info_ptr,
2724                &png_ptr->unknown_chunk, 1);
2725         }
2726      }
2727
2728      else
2729#endif
2730         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2731
2732      png_free(png_ptr, png_ptr->unknown_chunk.data);
2733      png_ptr->unknown_chunk.data = NULL;
2734   }
2735
2736   else
2737#endif
2738      skip = length;
2739
2740   png_crc_finish(png_ptr, skip);
2741
2742#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2743   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
2744#endif
2745}
2746
2747/* This function is called to verify that a chunk name is valid.
2748 * This function can't have the "critical chunk check" incorporated
2749 * into it, since in the future we will need to be able to call user
2750 * functions to handle unknown critical chunks after we check that
2751 * the chunk name itself is valid.
2752 */
2753
2754/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
2755 *
2756 * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2757 */
2758
2759void /* PRIVATE */
2760png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name)
2761{
2762   int i;
2763
2764   png_debug(1, "in png_check_chunk_name");
2765
2766   for (i=1; i<=4; ++i)
2767   {
2768      int c = chunk_name & 0xff;
2769
2770      if (c < 65 || c > 122 || (c > 90 && c < 97))
2771         png_chunk_error(png_ptr, "invalid chunk type");
2772
2773      chunk_name >>= 8;
2774   }
2775}
2776
2777/* Combines the row recently read in with the existing pixels in the row.  This
2778 * routine takes care of alpha and transparency if requested.  This routine also
2779 * handles the two methods of progressive display of interlaced images,
2780 * depending on the 'display' value; if 'display' is true then the whole row
2781 * (dp) is filled from the start by replicating the available pixels.  If
2782 * 'display' is false only those pixels present in the pass are filled in.
2783 */
2784void /* PRIVATE */
2785png_combine_row(png_structp png_ptr, png_bytep dp, int display)
2786{
2787   unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
2788   png_const_bytep sp = png_ptr->row_buf + 1;
2789   png_uint_32 row_width = png_ptr->width;
2790   unsigned int pass = png_ptr->pass;
2791   png_bytep end_ptr = 0;
2792   png_byte end_byte = 0;
2793   unsigned int end_mask;
2794
2795   png_debug(1, "in png_combine_row");
2796
2797   /* Added in 1.5.6: it should not be possible to enter this routine until at
2798    * least one row has been read from the PNG data and transformed.
2799    */
2800   if (pixel_depth == 0)
2801      png_error(png_ptr, "internal row logic error");
2802
2803   /* Added in 1.5.4: the pixel depth should match the information returned by
2804    * any call to png_read_update_info at this point.  Do not continue if we got
2805    * this wrong.
2806    */
2807   if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
2808          PNG_ROWBYTES(pixel_depth, row_width))
2809      png_error(png_ptr, "internal row size calculation error");
2810
2811   /* Don't expect this to ever happen: */
2812   if (row_width == 0)
2813      png_error(png_ptr, "internal row width error");
2814
2815   /* Preserve the last byte in cases where only part of it will be overwritten,
2816    * the multiply below may overflow, we don't care because ANSI-C guarantees
2817    * we get the low bits.
2818    */
2819   end_mask = (pixel_depth * row_width) & 7;
2820   if (end_mask != 0)
2821   {
2822      /* end_ptr == NULL is a flag to say do nothing */
2823      end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
2824      end_byte = *end_ptr;
2825#     ifdef PNG_READ_PACKSWAP_SUPPORTED
2826         if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
2827            end_mask = 0xff << end_mask;
2828
2829         else /* big-endian byte */
2830#     endif
2831         end_mask = 0xff >> end_mask;
2832      /* end_mask is now the bits to *keep* from the destination row */
2833   }
2834
2835   /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy()
2836    * will also happen if interlacing isn't supported or if the application
2837    * does not call png_set_interlace_handling().  In the latter cases the
2838    * caller just gets a sequence of the unexpanded rows from each interlace
2839    * pass.
2840    */
2841#ifdef PNG_READ_INTERLACING_SUPPORTED
2842   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
2843      pass < 6 && (display == 0 ||
2844      /* The following copies everything for 'display' on passes 0, 2 and 4. */
2845      (display == 1 && (pass & 1) != 0)))
2846   {
2847      /* Narrow images may have no bits in a pass; the caller should handle
2848       * this, but this test is cheap:
2849       */
2850      if (row_width <= PNG_PASS_START_COL(pass))
2851         return;
2852
2853      if (pixel_depth < 8)
2854      {
2855         /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
2856          * into 32 bits, then a single loop over the bytes using the four byte
2857          * values in the 32-bit mask can be used.  For the 'display' option the
2858          * expanded mask may also not require any masking within a byte.  To
2859          * make this work the PACKSWAP option must be taken into account - it
2860          * simply requires the pixels to be reversed in each byte.
2861          *
2862          * The 'regular' case requires a mask for each of the first 6 passes,
2863          * the 'display' case does a copy for the even passes in the range
2864          * 0..6.  This has already been handled in the test above.
2865          *
2866          * The masks are arranged as four bytes with the first byte to use in
2867          * the lowest bits (little-endian) regardless of the order (PACKSWAP or
2868          * not) of the pixels in each byte.
2869          *
2870          * NOTE: the whole of this logic depends on the caller of this function
2871          * only calling it on rows appropriate to the pass.  This function only
2872          * understands the 'x' logic; the 'y' logic is handled by the caller.
2873          *
2874          * The following defines allow generation of compile time constant bit
2875          * masks for each pixel depth and each possibility of swapped or not
2876          * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,
2877          * is in the range 0..7; and the result is 1 if the pixel is to be
2878          * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'
2879          * for the block method.
2880          *
2881          * With some compilers a compile time expression of the general form:
2882          *
2883          *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
2884          *
2885          * Produces warnings with values of 'shift' in the range 33 to 63
2886          * because the right hand side of the ?: expression is evaluated by
2887          * the compiler even though it isn't used.  Microsoft Visual C (various
2888          * versions) and the Intel C compiler are known to do this.  To avoid
2889          * this the following macros are used in 1.5.6.  This is a temporary
2890          * solution to avoid destabilizing the code during the release process.
2891          */
2892#        if PNG_USE_COMPILE_TIME_MASKS
2893#           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
2894#           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
2895#        else
2896#           define PNG_LSR(x,s) ((x)>>(s))
2897#           define PNG_LSL(x,s) ((x)<<(s))
2898#        endif
2899#        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
2900           PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
2901#        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
2902           PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
2903
2904         /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is
2905          * little endian - the first pixel is at bit 0 - however the extra
2906          * parameter 's' can be set to cause the mask position to be swapped
2907          * within each byte, to match the PNG format.  This is done by XOR of
2908          * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
2909          */
2910#        define PIXEL_MASK(p,x,d,s) \
2911            (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
2912
2913         /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
2914          */
2915#        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
2916#        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
2917
2918         /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp
2919          * cases the result needs replicating, for the 4-bpp case the above
2920          * generates a full 32 bits.
2921          */
2922#        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
2923
2924#        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
2925            S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
2926            S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
2927
2928#        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
2929            B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
2930            B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
2931
2932#if PNG_USE_COMPILE_TIME_MASKS
2933         /* Utility macros to construct all the masks for a depth/swap
2934          * combination.  The 's' parameter says whether the format is PNG
2935          * (big endian bytes) or not.  Only the three odd-numbered passes are
2936          * required for the display/block algorithm.
2937          */
2938#        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
2939            S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
2940
2941#        define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }
2942
2943#        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
2944
2945         /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
2946          * then pass:
2947          */
2948         static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
2949         {
2950            /* Little-endian byte masks for PACKSWAP */
2951            { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
2952            /* Normal (big-endian byte) masks - PNG format */
2953            { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
2954         };
2955
2956         /* display_mask has only three entries for the odd passes, so index by
2957          * pass>>1.
2958          */
2959         static PNG_CONST png_uint_32 display_mask[2][3][3] =
2960         {
2961            /* Little-endian byte masks for PACKSWAP */
2962            { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
2963            /* Normal (big-endian byte) masks - PNG format */
2964            { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
2965         };
2966
2967#        define MASK(pass,depth,display,png)\
2968            ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
2969               row_mask[png][DEPTH_INDEX(depth)][pass])
2970
2971#else /* !PNG_USE_COMPILE_TIME_MASKS */
2972         /* This is the runtime alternative: it seems unlikely that this will
2973          * ever be either smaller or faster than the compile time approach.
2974          */
2975#        define MASK(pass,depth,display,png)\
2976            ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
2977#endif /* !PNG_USE_COMPILE_TIME_MASKS */
2978
2979         /* Use the appropriate mask to copy the required bits.  In some cases
2980          * the byte mask will be 0 or 0xff, optimize these cases.  row_width is
2981          * the number of pixels, but the code copies bytes, so it is necessary
2982          * to special case the end.
2983          */
2984         png_uint_32 pixels_per_byte = 8 / pixel_depth;
2985         png_uint_32 mask;
2986
2987#        ifdef PNG_READ_PACKSWAP_SUPPORTED
2988            if (png_ptr->transformations & PNG_PACKSWAP)
2989               mask = MASK(pass, pixel_depth, display, 0);
2990
2991            else
2992#        endif
2993            mask = MASK(pass, pixel_depth, display, 1);
2994
2995         for (;;)
2996         {
2997            png_uint_32 m;
2998
2999            /* It doesn't matter in the following if png_uint_32 has more than
3000             * 32 bits because the high bits always match those in m<<24; it is,
3001             * however, essential to use OR here, not +, because of this.
3002             */
3003            m = mask;
3004            mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
3005            m &= 0xff;
3006
3007            if (m != 0) /* something to copy */
3008            {
3009               if (m != 0xff)
3010                  *dp = (png_byte)((*dp & ~m) | (*sp & m));
3011               else
3012                  *dp = *sp;
3013            }
3014
3015            /* NOTE: this may overwrite the last byte with garbage if the image
3016             * is not an exact number of bytes wide; libpng has always done
3017             * this.
3018             */
3019            if (row_width <= pixels_per_byte)
3020               break; /* May need to restore part of the last byte */
3021
3022            row_width -= pixels_per_byte;
3023            ++dp;
3024            ++sp;
3025         }
3026      }
3027
3028      else /* pixel_depth >= 8 */
3029      {
3030         unsigned int bytes_to_copy, bytes_to_jump;
3031
3032         /* Validate the depth - it must be a multiple of 8 */
3033         if (pixel_depth & 7)
3034            png_error(png_ptr, "invalid user transform pixel depth");
3035
3036         pixel_depth >>= 3; /* now in bytes */
3037         row_width *= pixel_depth;
3038
3039         /* Regardless of pass number the Adam 7 interlace always results in a
3040          * fixed number of pixels to copy then to skip.  There may be a
3041          * different number of pixels to skip at the start though.
3042          */
3043         {
3044            unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
3045
3046            row_width -= offset;
3047            dp += offset;
3048            sp += offset;
3049         }
3050
3051         /* Work out the bytes to copy. */
3052         if (display)
3053         {
3054            /* When doing the 'block' algorithm the pixel in the pass gets
3055             * replicated to adjacent pixels.  This is why the even (0,2,4,6)
3056             * passes are skipped above - the entire expanded row is copied.
3057             */
3058            bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
3059
3060            /* But don't allow this number to exceed the actual row width. */
3061            if (bytes_to_copy > row_width)
3062               bytes_to_copy = row_width;
3063         }
3064
3065         else /* normal row; Adam7 only ever gives us one pixel to copy. */
3066            bytes_to_copy = pixel_depth;
3067
3068         /* In Adam7 there is a constant offset between where the pixels go. */
3069         bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
3070
3071         /* And simply copy these bytes.  Some optimization is possible here,
3072          * depending on the value of 'bytes_to_copy'.  Special case the low
3073          * byte counts, which we know to be frequent.
3074          *
3075          * Notice that these cases all 'return' rather than 'break' - this
3076          * avoids an unnecessary test on whether to restore the last byte
3077          * below.
3078          */
3079         switch (bytes_to_copy)
3080         {
3081            case 1:
3082               for (;;)
3083               {
3084                  *dp = *sp;
3085
3086                  if (row_width <= bytes_to_jump)
3087                     return;
3088
3089                  dp += bytes_to_jump;
3090                  sp += bytes_to_jump;
3091                  row_width -= bytes_to_jump;
3092               }
3093
3094            case 2:
3095               /* There is a possibility of a partial copy at the end here; this
3096                * slows the code down somewhat.
3097                */
3098               do
3099               {
3100                  dp[0] = sp[0], dp[1] = sp[1];
3101
3102                  if (row_width <= bytes_to_jump)
3103                     return;
3104
3105                  sp += bytes_to_jump;
3106                  dp += bytes_to_jump;
3107                  row_width -= bytes_to_jump;
3108               }
3109               while (row_width > 1);
3110
3111               /* And there can only be one byte left at this point: */
3112               *dp = *sp;
3113               return;
3114
3115            case 3:
3116               /* This can only be the RGB case, so each copy is exactly one
3117                * pixel and it is not necessary to check for a partial copy.
3118                */
3119               for(;;)
3120               {
3121                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
3122
3123                  if (row_width <= bytes_to_jump)
3124                     return;
3125
3126                  sp += bytes_to_jump;
3127                  dp += bytes_to_jump;
3128                  row_width -= bytes_to_jump;
3129               }
3130
3131            default:
3132#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
3133               /* Check for double byte alignment and, if possible, use a
3134                * 16-bit copy.  Don't attempt this for narrow images - ones that
3135                * are less than an interlace panel wide.  Don't attempt it for
3136                * wide bytes_to_copy either - use the png_memcpy there.
3137                */
3138               if (bytes_to_copy < 16 /*else use png_memcpy*/ &&
3139                  png_isaligned(dp, png_uint_16) &&
3140                  png_isaligned(sp, png_uint_16) &&
3141                  bytes_to_copy % sizeof (png_uint_16) == 0 &&
3142                  bytes_to_jump % sizeof (png_uint_16) == 0)
3143               {
3144                  /* Everything is aligned for png_uint_16 copies, but try for
3145                   * png_uint_32 first.
3146                   */
3147                  if (png_isaligned(dp, png_uint_32) &&
3148                     png_isaligned(sp, png_uint_32) &&
3149                     bytes_to_copy % sizeof (png_uint_32) == 0 &&
3150                     bytes_to_jump % sizeof (png_uint_32) == 0)
3151                  {
3152                     png_uint_32p dp32 = (png_uint_32p)dp;
3153                     png_const_uint_32p sp32 = (png_const_uint_32p)sp;
3154                     unsigned int skip = (bytes_to_jump-bytes_to_copy) /
3155                        sizeof (png_uint_32);
3156
3157                     do
3158                     {
3159                        size_t c = bytes_to_copy;
3160                        do
3161                        {
3162                           *dp32++ = *sp32++;
3163                           c -= sizeof (png_uint_32);
3164                        }
3165                        while (c > 0);
3166
3167                        if (row_width <= bytes_to_jump)
3168                           return;
3169
3170                        dp32 += skip;
3171                        sp32 += skip;
3172                        row_width -= bytes_to_jump;
3173                     }
3174                     while (bytes_to_copy <= row_width);
3175
3176                     /* Get to here when the row_width truncates the final copy.
3177                      * There will be 1-3 bytes left to copy, so don't try the
3178                      * 16-bit loop below.
3179                      */
3180                     dp = (png_bytep)dp32;
3181                     sp = (png_const_bytep)sp32;
3182                     do
3183                        *dp++ = *sp++;
3184                     while (--row_width > 0);
3185                     return;
3186                  }
3187
3188                  /* Else do it in 16-bit quantities, but only if the size is
3189                   * not too large.
3190                   */
3191                  else
3192                  {
3193                     png_uint_16p dp16 = (png_uint_16p)dp;
3194                     png_const_uint_16p sp16 = (png_const_uint_16p)sp;
3195                     unsigned int skip = (bytes_to_jump-bytes_to_copy) /
3196                        sizeof (png_uint_16);
3197
3198                     do
3199                     {
3200                        size_t c = bytes_to_copy;
3201                        do
3202                        {
3203                           *dp16++ = *sp16++;
3204                           c -= sizeof (png_uint_16);
3205                        }
3206                        while (c > 0);
3207
3208                        if (row_width <= bytes_to_jump)
3209                           return;
3210
3211                        dp16 += skip;
3212                        sp16 += skip;
3213                        row_width -= bytes_to_jump;
3214                     }
3215                     while (bytes_to_copy <= row_width);
3216
3217                     /* End of row - 1 byte left, bytes_to_copy > row_width: */
3218                     dp = (png_bytep)dp16;
3219                     sp = (png_const_bytep)sp16;
3220                     do
3221                        *dp++ = *sp++;
3222                     while (--row_width > 0);
3223                     return;
3224                  }
3225               }
3226#endif /* PNG_ALIGN_ code */
3227
3228               /* The true default - use a png_memcpy: */
3229               for (;;)
3230               {
3231                  png_memcpy(dp, sp, bytes_to_copy);
3232
3233                  if (row_width <= bytes_to_jump)
3234                     return;
3235
3236                  sp += bytes_to_jump;
3237                  dp += bytes_to_jump;
3238                  row_width -= bytes_to_jump;
3239                  if (bytes_to_copy > row_width)
3240                     bytes_to_copy = row_width;
3241               }
3242         }
3243
3244         /* NOT REACHED*/
3245      } /* pixel_depth >= 8 */
3246
3247      /* Here if pixel_depth < 8 to check 'end_ptr' below. */
3248   }
3249   else
3250#endif
3251
3252   /* If here then the switch above wasn't used so just png_memcpy the whole row
3253    * from the temporary row buffer (notice that this overwrites the end of the
3254    * destination row if it is a partial byte.)
3255    */
3256   png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
3257
3258   /* Restore the overwritten bits from the last byte if necessary. */
3259   if (end_ptr != NULL)
3260      *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
3261}
3262
3263#ifdef PNG_READ_INTERLACING_SUPPORTED
3264void /* PRIVATE */
3265png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
3266   png_uint_32 transformations /* Because these may affect the byte layout */)
3267{
3268   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3269   /* Offset to next interlace block */
3270   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3271
3272   png_debug(1, "in png_do_read_interlace");
3273   if (row != NULL && row_info != NULL)
3274   {
3275      png_uint_32 final_width;
3276
3277      final_width = row_info->width * png_pass_inc[pass];
3278
3279      switch (row_info->pixel_depth)
3280      {
3281         case 1:
3282         {
3283            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
3284            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
3285            int sshift, dshift;
3286            int s_start, s_end, s_inc;
3287            int jstop = png_pass_inc[pass];
3288            png_byte v;
3289            png_uint_32 i;
3290            int j;
3291
3292#ifdef PNG_READ_PACKSWAP_SUPPORTED
3293            if (transformations & PNG_PACKSWAP)
3294            {
3295                sshift = (int)((row_info->width + 7) & 0x07);
3296                dshift = (int)((final_width + 7) & 0x07);
3297                s_start = 7;
3298                s_end = 0;
3299                s_inc = -1;
3300            }
3301
3302            else
3303#endif
3304            {
3305                sshift = 7 - (int)((row_info->width + 7) & 0x07);
3306                dshift = 7 - (int)((final_width + 7) & 0x07);
3307                s_start = 0;
3308                s_end = 7;
3309                s_inc = 1;
3310            }
3311
3312            for (i = 0; i < row_info->width; i++)
3313            {
3314               v = (png_byte)((*sp >> sshift) & 0x01);
3315               for (j = 0; j < jstop; j++)
3316               {
3317                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
3318                  *dp |= (png_byte)(v << dshift);
3319
3320                  if (dshift == s_end)
3321                  {
3322                     dshift = s_start;
3323                     dp--;
3324                  }
3325
3326                  else
3327                     dshift += s_inc;
3328               }
3329
3330               if (sshift == s_end)
3331               {
3332                  sshift = s_start;
3333                  sp--;
3334               }
3335
3336               else
3337                  sshift += s_inc;
3338            }
3339            break;
3340         }
3341
3342         case 2:
3343         {
3344            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
3345            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
3346            int sshift, dshift;
3347            int s_start, s_end, s_inc;
3348            int jstop = png_pass_inc[pass];
3349            png_uint_32 i;
3350
3351#ifdef PNG_READ_PACKSWAP_SUPPORTED
3352            if (transformations & PNG_PACKSWAP)
3353            {
3354               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
3355               dshift = (int)(((final_width + 3) & 0x03) << 1);
3356               s_start = 6;
3357               s_end = 0;
3358               s_inc = -2;
3359            }
3360
3361            else
3362#endif
3363            {
3364               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
3365               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
3366               s_start = 0;
3367               s_end = 6;
3368               s_inc = 2;
3369            }
3370
3371            for (i = 0; i < row_info->width; i++)
3372            {
3373               png_byte v;
3374               int j;
3375
3376               v = (png_byte)((*sp >> sshift) & 0x03);
3377               for (j = 0; j < jstop; j++)
3378               {
3379                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
3380                  *dp |= (png_byte)(v << dshift);
3381
3382                  if (dshift == s_end)
3383                  {
3384                     dshift = s_start;
3385                     dp--;
3386                  }
3387
3388                  else
3389                     dshift += s_inc;
3390               }
3391
3392               if (sshift == s_end)
3393               {
3394                  sshift = s_start;
3395                  sp--;
3396               }
3397
3398               else
3399                  sshift += s_inc;
3400            }
3401            break;
3402         }
3403
3404         case 4:
3405         {
3406            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
3407            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
3408            int sshift, dshift;
3409            int s_start, s_end, s_inc;
3410            png_uint_32 i;
3411            int jstop = png_pass_inc[pass];
3412
3413#ifdef PNG_READ_PACKSWAP_SUPPORTED
3414            if (transformations & PNG_PACKSWAP)
3415            {
3416               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
3417               dshift = (int)(((final_width + 1) & 0x01) << 2);
3418               s_start = 4;
3419               s_end = 0;
3420               s_inc = -4;
3421            }
3422
3423            else
3424#endif
3425            {
3426               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
3427               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
3428               s_start = 0;
3429               s_end = 4;
3430               s_inc = 4;
3431            }
3432
3433            for (i = 0; i < row_info->width; i++)
3434            {
3435               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
3436               int j;
3437
3438               for (j = 0; j < jstop; j++)
3439               {
3440                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
3441                  *dp |= (png_byte)(v << dshift);
3442
3443                  if (dshift == s_end)
3444                  {
3445                     dshift = s_start;
3446                     dp--;
3447                  }
3448
3449                  else
3450                     dshift += s_inc;
3451               }
3452
3453               if (sshift == s_end)
3454               {
3455                  sshift = s_start;
3456                  sp--;
3457               }
3458
3459               else
3460                  sshift += s_inc;
3461            }
3462            break;
3463         }
3464
3465         default:
3466         {
3467            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
3468
3469            png_bytep sp = row + (png_size_t)(row_info->width - 1)
3470                * pixel_bytes;
3471
3472            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
3473
3474            int jstop = png_pass_inc[pass];
3475            png_uint_32 i;
3476
3477            for (i = 0; i < row_info->width; i++)
3478            {
3479               png_byte v[8];
3480               int j;
3481
3482               png_memcpy(v, sp, pixel_bytes);
3483
3484               for (j = 0; j < jstop; j++)
3485               {
3486                  png_memcpy(dp, v, pixel_bytes);
3487                  dp -= pixel_bytes;
3488               }
3489
3490               sp -= pixel_bytes;
3491            }
3492            break;
3493         }
3494      }
3495
3496      row_info->width = final_width;
3497      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
3498   }
3499#ifndef PNG_READ_PACKSWAP_SUPPORTED
3500   PNG_UNUSED(transformations)  /* Silence compiler warning */
3501#endif
3502}
3503#endif /* PNG_READ_INTERLACING_SUPPORTED */
3504
3505static void
3506png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
3507   png_const_bytep prev_row)
3508{
3509   png_size_t i;
3510   png_size_t istop = row_info->rowbytes;
3511   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
3512   png_bytep rp = row + bpp;
3513
3514   PNG_UNUSED(prev_row)
3515
3516   for (i = bpp; i < istop; i++)
3517   {
3518      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
3519      rp++;
3520   }
3521}
3522
3523static void
3524png_read_filter_row_up(png_row_infop row_info, png_bytep row,
3525   png_const_bytep prev_row)
3526{
3527   png_size_t i;
3528   png_size_t istop = row_info->rowbytes;
3529   png_bytep rp = row;
3530   png_const_bytep pp = prev_row;
3531
3532   for (i = 0; i < istop; i++)
3533   {
3534      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
3535      rp++;
3536   }
3537}
3538
3539static void
3540png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
3541   png_const_bytep prev_row)
3542{
3543   png_size_t i;
3544   png_bytep rp = row;
3545   png_const_bytep pp = prev_row;
3546   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
3547   png_size_t istop = row_info->rowbytes - bpp;
3548
3549   for (i = 0; i < bpp; i++)
3550   {
3551      *rp = (png_byte)(((int)(*rp) +
3552         ((int)(*pp++) / 2 )) & 0xff);
3553
3554      rp++;
3555   }
3556
3557   for (i = 0; i < istop; i++)
3558   {
3559      *rp = (png_byte)(((int)(*rp) +
3560         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
3561
3562      rp++;
3563   }
3564}
3565
3566static void
3567png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
3568   png_const_bytep prev_row)
3569{
3570   png_bytep rp_end = row + row_info->rowbytes;
3571   int a, c;
3572
3573   /* First pixel/byte */
3574   c = *prev_row++;
3575   a = *row + c;
3576   *row++ = (png_byte)a;
3577
3578   /* Remainder */
3579   while (row < rp_end)
3580   {
3581      int b, pa, pb, pc, p;
3582
3583      a &= 0xff; /* From previous iteration or start */
3584      b = *prev_row++;
3585
3586      p = b - c;
3587      pc = a - c;
3588
3589#     ifdef PNG_USE_ABS
3590         pa = abs(p);
3591         pb = abs(pc);
3592         pc = abs(p + pc);
3593#     else
3594         pa = p < 0 ? -p : p;
3595         pb = pc < 0 ? -pc : pc;
3596         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3597#     endif
3598
3599      /* Find the best predictor, the least of pa, pb, pc favoring the earlier
3600       * ones in the case of a tie.
3601       */
3602      if (pb < pa) pa = pb, a = b;
3603      if (pc < pa) a = c;
3604
3605      /* Calculate the current pixel in a, and move the previous row pixel to c
3606       * for the next time round the loop
3607       */
3608      c = b;
3609      a += *row;
3610      *row++ = (png_byte)a;
3611   }
3612}
3613
3614static void
3615png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
3616   png_const_bytep prev_row)
3617{
3618   int bpp = (row_info->pixel_depth + 7) >> 3;
3619   png_bytep rp_end = row + bpp;
3620
3621   /* Process the first pixel in the row completely (this is the same as 'up'
3622    * because there is only one candidate predictor for the first row).
3623    */
3624   while (row < rp_end)
3625   {
3626      int a = *row + *prev_row++;
3627      *row++ = (png_byte)a;
3628   }
3629
3630   /* Remainder */
3631   rp_end += row_info->rowbytes - bpp;
3632
3633   while (row < rp_end)
3634   {
3635      int a, b, c, pa, pb, pc, p;
3636
3637      c = *(prev_row - bpp);
3638      a = *(row - bpp);
3639      b = *prev_row++;
3640
3641      p = b - c;
3642      pc = a - c;
3643
3644#     ifdef PNG_USE_ABS
3645         pa = abs(p);
3646         pb = abs(pc);
3647         pc = abs(p + pc);
3648#     else
3649         pa = p < 0 ? -p : p;
3650         pb = pc < 0 ? -pc : pc;
3651         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3652#     endif
3653
3654      if (pb < pa) pa = pb, a = b;
3655      if (pc < pa) a = c;
3656
3657      c = b;
3658      a += *row;
3659      *row++ = (png_byte)a;
3660   }
3661}
3662
3663#ifdef PNG_ARM_NEON
3664
3665#ifdef __linux__
3666#include <stdio.h>
3667#include <elf.h>
3668#include <asm/hwcap.h>
3669
3670static int png_have_hwcap(unsigned cap)
3671{
3672   FILE *f = fopen("/proc/self/auxv", "r");
3673   Elf32_auxv_t aux;
3674   int have_cap = 0;
3675
3676   if (!f)
3677      return 0;
3678
3679   while (fread(&aux, sizeof(aux), 1, f) > 0)
3680   {
3681      if (aux.a_type == AT_HWCAP &&
3682          aux.a_un.a_val & cap)
3683      {
3684         have_cap = 1;
3685         break;
3686      }
3687   }
3688
3689   fclose(f);
3690
3691   return have_cap;
3692}
3693#endif /* __linux__ */
3694
3695static void
3696png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
3697{
3698#ifdef __linux__
3699   if (!png_have_hwcap(HWCAP_NEON))
3700      return;
3701#endif
3702
3703   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;
3704
3705   if (bpp == 3)
3706   {
3707      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
3708      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
3709      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3710         png_read_filter_row_paeth3_neon;
3711   }
3712
3713   else if (bpp == 4)
3714   {
3715      pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
3716      pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
3717      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3718          png_read_filter_row_paeth4_neon;
3719   }
3720}
3721#endif /* PNG_ARM_NEON */
3722
3723static void
3724png_init_filter_functions(png_structp pp)
3725{
3726   unsigned int bpp = (pp->pixel_depth + 7) >> 3;
3727
3728   pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
3729   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
3730   pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
3731   if (bpp == 1)
3732      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3733         png_read_filter_row_paeth_1byte_pixel;
3734   else
3735      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3736         png_read_filter_row_paeth_multibyte_pixel;
3737
3738#ifdef PNG_ARM_NEON
3739   png_init_filter_functions_neon(pp, bpp);
3740#endif
3741}
3742
3743void /* PRIVATE */
3744png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row,
3745   png_const_bytep prev_row, int filter)
3746{
3747   if (pp->read_filter[0] == NULL)
3748      png_init_filter_functions(pp);
3749   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
3750      pp->read_filter[filter-1](row_info, row, prev_row);
3751}
3752
3753#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3754void /* PRIVATE */
3755png_read_finish_row(png_structp png_ptr)
3756{
3757#ifdef PNG_READ_INTERLACING_SUPPORTED
3758   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3759
3760   /* Start of interlace block */
3761   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3762
3763   /* Offset to next interlace block */
3764   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3765
3766   /* Start of interlace block in the y direction */
3767   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3768
3769   /* Offset to next interlace block in the y direction */
3770   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3771#endif /* PNG_READ_INTERLACING_SUPPORTED */
3772
3773   png_debug(1, "in png_read_finish_row");
3774   png_ptr->row_number++;
3775   if (png_ptr->row_number < png_ptr->num_rows)
3776      return;
3777
3778#ifdef PNG_READ_INTERLACING_SUPPORTED
3779   if (png_ptr->interlaced)
3780   {
3781      png_ptr->row_number = 0;
3782
3783      /* TO DO: don't do this if prev_row isn't needed (requires
3784       * read-ahead of the next row's filter byte.
3785       */
3786      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3787
3788      do
3789      {
3790         png_ptr->pass++;
3791
3792         if (png_ptr->pass >= 7)
3793            break;
3794
3795         png_ptr->iwidth = (png_ptr->width +
3796            png_pass_inc[png_ptr->pass] - 1 -
3797            png_pass_start[png_ptr->pass]) /
3798            png_pass_inc[png_ptr->pass];
3799
3800         if (!(png_ptr->transformations & PNG_INTERLACE))
3801         {
3802            png_ptr->num_rows = (png_ptr->height +
3803                png_pass_yinc[png_ptr->pass] - 1 -
3804                png_pass_ystart[png_ptr->pass]) /
3805                png_pass_yinc[png_ptr->pass];
3806         }
3807
3808         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
3809            break; /* libpng deinterlacing sees every row */
3810
3811      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
3812
3813      if (png_ptr->pass < 7)
3814         return;
3815   }
3816#endif /* PNG_READ_INTERLACING_SUPPORTED */
3817
3818   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3819   {
3820      char extra;
3821      int ret;
3822
3823      png_ptr->zstream.next_out = (Byte *)&extra;
3824      png_ptr->zstream.avail_out = (uInt)1;
3825
3826      for (;;)
3827      {
3828         if (!(png_ptr->zstream.avail_in))
3829         {
3830            while (!png_ptr->idat_size)
3831            {
3832               png_crc_finish(png_ptr, 0);
3833               png_ptr->idat_size = png_read_chunk_header(png_ptr);
3834               if (png_ptr->chunk_name != png_IDAT)
3835                  png_error(png_ptr, "Not enough image data");
3836            }
3837
3838            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3839            png_ptr->zstream.next_in = png_ptr->zbuf;
3840
3841            if (png_ptr->zbuf_size > png_ptr->idat_size)
3842               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3843
3844            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3845            png_ptr->idat_size -= png_ptr->zstream.avail_in;
3846         }
3847
3848         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3849
3850         if (ret == Z_STREAM_END)
3851         {
3852            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3853                png_ptr->idat_size)
3854               png_warning(png_ptr, "Extra compressed data");
3855
3856            png_ptr->mode |= PNG_AFTER_IDAT;
3857            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3858            break;
3859         }
3860
3861         if (ret != Z_OK)
3862            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3863                "Decompression Error");
3864
3865         if (!(png_ptr->zstream.avail_out))
3866         {
3867            png_warning(png_ptr, "Extra compressed data");
3868            png_ptr->mode |= PNG_AFTER_IDAT;
3869            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3870            break;
3871         }
3872
3873      }
3874      png_ptr->zstream.avail_out = 0;
3875   }
3876
3877   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3878      png_warning(png_ptr, "Extra compression data");
3879
3880   inflateReset(&png_ptr->zstream);
3881
3882   png_ptr->mode |= PNG_AFTER_IDAT;
3883}
3884#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3885
3886void /* PRIVATE */
3887png_read_start_row(png_structp png_ptr)
3888{
3889#ifdef PNG_READ_INTERLACING_SUPPORTED
3890   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3891
3892   /* Start of interlace block */
3893   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3894
3895   /* Offset to next interlace block */
3896   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3897
3898   /* Start of interlace block in the y direction */
3899   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3900
3901   /* Offset to next interlace block in the y direction */
3902   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3903#endif
3904
3905   int max_pixel_depth;
3906   png_size_t row_bytes;
3907
3908   png_debug(1, "in png_read_start_row");
3909   png_ptr->zstream.avail_in = 0;
3910#ifdef PNG_READ_TRANSFORMS_SUPPORTED
3911   png_init_read_transformations(png_ptr);
3912#endif
3913#ifdef PNG_READ_INTERLACING_SUPPORTED
3914   if (png_ptr->interlaced)
3915   {
3916      if (!(png_ptr->transformations & PNG_INTERLACE))
3917         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3918             png_pass_ystart[0]) / png_pass_yinc[0];
3919
3920      else
3921         png_ptr->num_rows = png_ptr->height;
3922
3923      png_ptr->iwidth = (png_ptr->width +
3924          png_pass_inc[png_ptr->pass] - 1 -
3925          png_pass_start[png_ptr->pass]) /
3926          png_pass_inc[png_ptr->pass];
3927   }
3928
3929   else
3930#endif /* PNG_READ_INTERLACING_SUPPORTED */
3931   {
3932      png_ptr->num_rows = png_ptr->height;
3933      png_ptr->iwidth = png_ptr->width;
3934   }
3935
3936   max_pixel_depth = png_ptr->pixel_depth;
3937
3938   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
3939    * calculations to calculate the final pixel depth, then
3940    * png_do_read_transforms actually does the transforms.  This means that the
3941    * code which effectively calculates this value is actually repeated in three
3942    * separate places.  They must all match.  Innocent changes to the order of
3943    * transformations can and will break libpng in a way that causes memory
3944    * overwrites.
3945    *
3946    * TODO: fix this.
3947    */
3948#ifdef PNG_READ_PACK_SUPPORTED
3949   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3950      max_pixel_depth = 8;
3951#endif
3952
3953#ifdef PNG_READ_EXPAND_SUPPORTED
3954   if (png_ptr->transformations & PNG_EXPAND)
3955   {
3956      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3957      {
3958         if (png_ptr->num_trans)
3959            max_pixel_depth = 32;
3960
3961         else
3962            max_pixel_depth = 24;
3963      }
3964
3965      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3966      {
3967         if (max_pixel_depth < 8)
3968            max_pixel_depth = 8;
3969
3970         if (png_ptr->num_trans)
3971            max_pixel_depth *= 2;
3972      }
3973
3974      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3975      {
3976         if (png_ptr->num_trans)
3977         {
3978            max_pixel_depth *= 4;
3979            max_pixel_depth /= 3;
3980         }
3981      }
3982   }
3983#endif
3984
3985#ifdef PNG_READ_EXPAND_16_SUPPORTED
3986   if (png_ptr->transformations & PNG_EXPAND_16)
3987   {
3988#     ifdef PNG_READ_EXPAND_SUPPORTED
3989         /* In fact it is an error if it isn't supported, but checking is
3990          * the safe way.
3991          */
3992         if (png_ptr->transformations & PNG_EXPAND)
3993         {
3994            if (png_ptr->bit_depth < 16)
3995               max_pixel_depth *= 2;
3996         }
3997         else
3998#     endif
3999         png_ptr->transformations &= ~PNG_EXPAND_16;
4000   }
4001#endif
4002
4003#ifdef PNG_READ_FILLER_SUPPORTED
4004   if (png_ptr->transformations & (PNG_FILLER))
4005   {
4006      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
4007      {
4008         if (max_pixel_depth <= 8)
4009            max_pixel_depth = 16;
4010
4011         else
4012            max_pixel_depth = 32;
4013      }
4014
4015      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
4016         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
4017      {
4018         if (max_pixel_depth <= 32)
4019            max_pixel_depth = 32;
4020
4021         else
4022            max_pixel_depth = 64;
4023      }
4024   }
4025#endif
4026
4027#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4028   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
4029   {
4030      if (
4031#ifdef PNG_READ_EXPAND_SUPPORTED
4032          (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
4033#endif
4034#ifdef PNG_READ_FILLER_SUPPORTED
4035          (png_ptr->transformations & (PNG_FILLER)) ||
4036#endif
4037          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
4038      {
4039         if (max_pixel_depth <= 16)
4040            max_pixel_depth = 32;
4041
4042         else
4043            max_pixel_depth = 64;
4044      }
4045
4046      else
4047      {
4048         if (max_pixel_depth <= 8)
4049         {
4050            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4051               max_pixel_depth = 32;
4052
4053            else
4054               max_pixel_depth = 24;
4055         }
4056
4057         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4058            max_pixel_depth = 64;
4059
4060         else
4061            max_pixel_depth = 48;
4062      }
4063   }
4064#endif
4065
4066#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
4067defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
4068   if (png_ptr->transformations & PNG_USER_TRANSFORM)
4069   {
4070      int user_pixel_depth = png_ptr->user_transform_depth *
4071         png_ptr->user_transform_channels;
4072
4073      if (user_pixel_depth > max_pixel_depth)
4074         max_pixel_depth = user_pixel_depth;
4075   }
4076#endif
4077
4078   /* This value is stored in png_struct and double checked in the row read
4079    * code.
4080    */
4081   png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
4082   png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
4083
4084   /* Align the width on the next larger 8 pixels.  Mainly used
4085    * for interlacing
4086    */
4087   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
4088   /* Calculate the maximum bytes needed, adding a byte and a pixel
4089    * for safety's sake
4090    */
4091   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
4092       1 + ((max_pixel_depth + 7) >> 3);
4093
4094#ifdef PNG_MAX_MALLOC_64K
4095   if (row_bytes > (png_uint_32)65536L)
4096      png_error(png_ptr, "This image requires a row greater than 64KB");
4097#endif
4098
4099   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
4100   {
4101     png_free(png_ptr, png_ptr->big_row_buf);
4102     png_free(png_ptr, png_ptr->big_prev_row);
4103
4104     if (png_ptr->interlaced)
4105        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
4106            row_bytes + 48);
4107
4108     else
4109        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4110
4111     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4112
4113#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
4114     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
4115      * of padding before and after row_buf; treat prev_row similarly.
4116      * NOTE: the alignment is to the start of the pixels, one beyond the start
4117      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
4118      * was incorrect; the filter byte was aligned, which had the exact
4119      * opposite effect of that intended.
4120      */
4121     {
4122        png_bytep temp = png_ptr->big_row_buf + 32;
4123        int extra = (int)((temp - (png_bytep)0) & 0x0f);
4124        png_ptr->row_buf = temp - extra - 1/*filter byte*/;
4125
4126        temp = png_ptr->big_prev_row + 32;
4127        extra = (int)((temp - (png_bytep)0) & 0x0f);
4128        png_ptr->prev_row = temp - extra - 1/*filter byte*/;
4129     }
4130
4131#else
4132     /* Use 31 bytes of padding before and 17 bytes after row_buf. */
4133     png_ptr->row_buf = png_ptr->big_row_buf + 31;
4134     png_ptr->prev_row = png_ptr->big_prev_row + 31;
4135#endif
4136     png_ptr->old_big_row_buf_size = row_bytes + 48;
4137   }
4138
4139#ifdef PNG_MAX_MALLOC_64K
4140   if (png_ptr->rowbytes > 65535)
4141      png_error(png_ptr, "This image requires a row greater than 64KB");
4142
4143#endif
4144   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
4145      png_error(png_ptr, "Row has too many bytes to allocate in memory");
4146
4147   png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
4148
4149   png_debug1(3, "width = %u,", png_ptr->width);
4150   png_debug1(3, "height = %u,", png_ptr->height);
4151   png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
4152   png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
4153   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
4154   png_debug1(3, "irowbytes = %lu",
4155       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
4156
4157   png_ptr->flags |= PNG_FLAG_ROW_INIT;
4158}
4159#endif /* PNG_READ_SUPPORTED */
Note: See TracBrowser for help on using the repository browser.