media/libpng/pngrutil.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libpng/pngrutil.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,4767 @@
     1.4 +
     1.5 +/* pngrutil.c - utilities to read a PNG file
     1.6 + *
     1.7 + * Last changed in libpng 1.6.10 [March 6, 2014]
     1.8 + * Copyright (c) 1998-2014 Glenn Randers-Pehrson
     1.9 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
    1.10 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
    1.11 + *
    1.12 + * This code is released under the libpng license.
    1.13 + * For conditions of distribution and use, see the disclaimer
    1.14 + * and license in png.h
    1.15 + *
    1.16 + * This file contains routines that are only called from within
    1.17 + * libpng itself during the course of reading an image.
    1.18 + */
    1.19 +
    1.20 +#include "pngpriv.h"
    1.21 +
    1.22 +#ifdef PNG_READ_SUPPORTED
    1.23 +
    1.24 +png_uint_32 PNGAPI
    1.25 +png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
    1.26 +{
    1.27 +   png_uint_32 uval = png_get_uint_32(buf);
    1.28 +
    1.29 +   if (uval > PNG_UINT_31_MAX)
    1.30 +      png_error(png_ptr, "PNG unsigned integer out of range");
    1.31 +
    1.32 +   return (uval);
    1.33 +}
    1.34 +
    1.35 +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
    1.36 +/* The following is a variation on the above for use with the fixed
    1.37 + * point values used for gAMA and cHRM.  Instead of png_error it
    1.38 + * issues a warning and returns (-1) - an invalid value because both
    1.39 + * gAMA and cHRM use *unsigned* integers for fixed point values.
    1.40 + */
    1.41 +#define PNG_FIXED_ERROR (-1)
    1.42 +
    1.43 +static png_fixed_point /* PRIVATE */
    1.44 +png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)
    1.45 +{
    1.46 +   png_uint_32 uval = png_get_uint_32(buf);
    1.47 +
    1.48 +   if (uval <= PNG_UINT_31_MAX)
    1.49 +      return (png_fixed_point)uval; /* known to be in range */
    1.50 +
    1.51 +   /* The caller can turn off the warning by passing NULL. */
    1.52 +   if (png_ptr != NULL)
    1.53 +      png_warning(png_ptr, "PNG fixed point integer out of range");
    1.54 +
    1.55 +   return PNG_FIXED_ERROR;
    1.56 +}
    1.57 +#endif
    1.58 +
    1.59 +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
    1.60 +/* NOTE: the read macros will obscure these definitions, so that if
    1.61 + * PNG_USE_READ_MACROS is set the library will not use them internally,
    1.62 + * but the APIs will still be available externally.
    1.63 + *
    1.64 + * The parentheses around "PNGAPI function_name" in the following three
    1.65 + * functions are necessary because they allow the macros to co-exist with
    1.66 + * these (unused but exported) functions.
    1.67 + */
    1.68 +
    1.69 +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
    1.70 +png_uint_32 (PNGAPI
    1.71 +png_get_uint_32)(png_const_bytep buf)
    1.72 +{
    1.73 +   png_uint_32 uval =
    1.74 +       ((png_uint_32)(*(buf    )) << 24) +
    1.75 +       ((png_uint_32)(*(buf + 1)) << 16) +
    1.76 +       ((png_uint_32)(*(buf + 2)) <<  8) +
    1.77 +       ((png_uint_32)(*(buf + 3))      ) ;
    1.78 +
    1.79 +   return uval;
    1.80 +}
    1.81 +
    1.82 +/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
    1.83 + * data is stored in the PNG file in two's complement format and there
    1.84 + * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
    1.85 + * the following code does a two's complement to native conversion.
    1.86 + */
    1.87 +png_int_32 (PNGAPI
    1.88 +png_get_int_32)(png_const_bytep buf)
    1.89 +{
    1.90 +   png_uint_32 uval = png_get_uint_32(buf);
    1.91 +   if ((uval & 0x80000000) == 0) /* non-negative */
    1.92 +      return uval;
    1.93 +
    1.94 +   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
    1.95 +   return -(png_int_32)uval;
    1.96 +}
    1.97 +
    1.98 +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
    1.99 +png_uint_16 (PNGAPI
   1.100 +png_get_uint_16)(png_const_bytep buf)
   1.101 +{
   1.102 +   /* ANSI-C requires an int value to accomodate at least 16 bits so this
   1.103 +    * works and allows the compiler not to worry about possible narrowing
   1.104 +    * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
   1.105 +    * than 16 bits either.)
   1.106 +    */
   1.107 +   unsigned int val =
   1.108 +       ((unsigned int)(*buf) << 8) +
   1.109 +       ((unsigned int)(*(buf + 1)));
   1.110 +
   1.111 +   return (png_uint_16)val;
   1.112 +}
   1.113 +
   1.114 +#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
   1.115 +
   1.116 +/* Read and check the PNG file signature */
   1.117 +void /* PRIVATE */
   1.118 +png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
   1.119 +{
   1.120 +   png_size_t num_checked, num_to_check;
   1.121 +
   1.122 +   /* Exit if the user application does not expect a signature. */
   1.123 +   if (png_ptr->sig_bytes >= 8)
   1.124 +      return;
   1.125 +
   1.126 +   num_checked = png_ptr->sig_bytes;
   1.127 +   num_to_check = 8 - num_checked;
   1.128 +
   1.129 +#ifdef PNG_IO_STATE_SUPPORTED
   1.130 +   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
   1.131 +#endif
   1.132 +
   1.133 +   /* The signature must be serialized in a single I/O call. */
   1.134 +   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
   1.135 +   png_ptr->sig_bytes = 8;
   1.136 +
   1.137 +   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
   1.138 +   {
   1.139 +      if (num_checked < 4 &&
   1.140 +          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
   1.141 +         png_error(png_ptr, "Not a PNG file");
   1.142 +      else
   1.143 +         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
   1.144 +   }
   1.145 +   if (num_checked < 3)
   1.146 +      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
   1.147 +}
   1.148 +
   1.149 +/* Read the chunk header (length + type name).
   1.150 + * Put the type name into png_ptr->chunk_name, and return the length.
   1.151 + */
   1.152 +png_uint_32 /* PRIVATE */
   1.153 +png_read_chunk_header(png_structrp png_ptr)
   1.154 +{
   1.155 +   png_byte buf[8];
   1.156 +   png_uint_32 length;
   1.157 +
   1.158 +#ifdef PNG_IO_STATE_SUPPORTED
   1.159 +   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
   1.160 +#endif
   1.161 +
   1.162 +   /* Read the length and the chunk name.
   1.163 +    * This must be performed in a single I/O call.
   1.164 +    */
   1.165 +   png_read_data(png_ptr, buf, 8);
   1.166 +   length = png_get_uint_31(png_ptr, buf);
   1.167 +
   1.168 +   /* Put the chunk name into png_ptr->chunk_name. */
   1.169 +   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
   1.170 +
   1.171 +   png_debug2(0, "Reading %lx chunk, length = %lu",
   1.172 +       (unsigned long)png_ptr->chunk_name, (unsigned long)length);
   1.173 +
   1.174 +   /* Reset the crc and run it over the chunk name. */
   1.175 +   png_reset_crc(png_ptr);
   1.176 +   png_calculate_crc(png_ptr, buf + 4, 4);
   1.177 +
   1.178 +   /* Check to see if chunk name is valid. */
   1.179 +   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
   1.180 +
   1.181 +#ifdef PNG_IO_STATE_SUPPORTED
   1.182 +   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
   1.183 +#endif
   1.184 +
   1.185 +   return length;
   1.186 +}
   1.187 +
   1.188 +/* Read data, and (optionally) run it through the CRC. */
   1.189 +void /* PRIVATE */
   1.190 +png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
   1.191 +{
   1.192 +   if (png_ptr == NULL)
   1.193 +      return;
   1.194 +
   1.195 +   png_read_data(png_ptr, buf, length);
   1.196 +   png_calculate_crc(png_ptr, buf, length);
   1.197 +}
   1.198 +
   1.199 +/* Optionally skip data and then check the CRC.  Depending on whether we
   1.200 + * are reading an ancillary or critical chunk, and how the program has set
   1.201 + * things up, we may calculate the CRC on the data and print a message.
   1.202 + * Returns '1' if there was a CRC error, '0' otherwise.
   1.203 + */
   1.204 +int /* PRIVATE */
   1.205 +png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
   1.206 +{
   1.207 +   /* The size of the local buffer for inflate is a good guess as to a
   1.208 +    * reasonable size to use for buffering reads from the application.
   1.209 +    */
   1.210 +   while (skip > 0)
   1.211 +   {
   1.212 +      png_uint_32 len;
   1.213 +      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
   1.214 +
   1.215 +      len = (sizeof tmpbuf);
   1.216 +      if (len > skip)
   1.217 +         len = skip;
   1.218 +      skip -= len;
   1.219 +
   1.220 +      png_crc_read(png_ptr, tmpbuf, len);
   1.221 +   }
   1.222 +
   1.223 +   if (png_crc_error(png_ptr))
   1.224 +   {
   1.225 +      if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) ?
   1.226 +          !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
   1.227 +          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
   1.228 +      {
   1.229 +         png_chunk_warning(png_ptr, "CRC error");
   1.230 +      }
   1.231 +
   1.232 +      else
   1.233 +         png_chunk_error(png_ptr, "CRC error");
   1.234 +
   1.235 +      return (1);
   1.236 +   }
   1.237 +
   1.238 +   return (0);
   1.239 +}
   1.240 +
   1.241 +/* Compare the CRC stored in the PNG file with that calculated by libpng from
   1.242 + * the data it has read thus far.
   1.243 + */
   1.244 +int /* PRIVATE */
   1.245 +png_crc_error(png_structrp png_ptr)
   1.246 +{
   1.247 +   png_byte crc_bytes[4];
   1.248 +   png_uint_32 crc;
   1.249 +   int need_crc = 1;
   1.250 +
   1.251 +   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
   1.252 +   {
   1.253 +      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
   1.254 +          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
   1.255 +         need_crc = 0;
   1.256 +   }
   1.257 +
   1.258 +   else /* critical */
   1.259 +   {
   1.260 +      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
   1.261 +         need_crc = 0;
   1.262 +   }
   1.263 +
   1.264 +#ifdef PNG_IO_STATE_SUPPORTED
   1.265 +   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
   1.266 +#endif
   1.267 +
   1.268 +   /* The chunk CRC must be serialized in a single I/O call. */
   1.269 +   png_read_data(png_ptr, crc_bytes, 4);
   1.270 +
   1.271 +   if (need_crc)
   1.272 +   {
   1.273 +      crc = png_get_uint_32(crc_bytes);
   1.274 +      return ((int)(crc != png_ptr->crc));
   1.275 +   }
   1.276 +
   1.277 +   else
   1.278 +      return (0);
   1.279 +}
   1.280 +
   1.281 +#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
   1.282 +    defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\
   1.283 +    defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\
   1.284 +    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED)
   1.285 +/* Manage the read buffer; this simply reallocates the buffer if it is not small
   1.286 + * enough (or if it is not allocated).  The routine returns a pointer to the
   1.287 + * buffer; if an error occurs and 'warn' is set the routine returns NULL, else
   1.288 + * it will call png_error (via png_malloc) on failure.  (warn == 2 means
   1.289 + * 'silent').
   1.290 + */
   1.291 +static png_bytep
   1.292 +png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
   1.293 +{
   1.294 +   png_bytep buffer = png_ptr->read_buffer;
   1.295 +
   1.296 +   if (buffer != NULL && new_size > png_ptr->read_buffer_size)
   1.297 +   {
   1.298 +      png_ptr->read_buffer = NULL;
   1.299 +      png_ptr->read_buffer = NULL;
   1.300 +      png_ptr->read_buffer_size = 0;
   1.301 +      png_free(png_ptr, buffer);
   1.302 +      buffer = NULL;
   1.303 +   }
   1.304 +
   1.305 +   if (buffer == NULL)
   1.306 +   {
   1.307 +      buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size));
   1.308 +
   1.309 +      if (buffer != NULL)
   1.310 +      {
   1.311 +         png_ptr->read_buffer = buffer;
   1.312 +         png_ptr->read_buffer_size = new_size;
   1.313 +      }
   1.314 +
   1.315 +      else if (warn < 2) /* else silent */
   1.316 +      {
   1.317 +         if (warn)
   1.318 +             png_chunk_warning(png_ptr, "insufficient memory to read chunk");
   1.319 +
   1.320 +         else
   1.321 +             png_chunk_error(png_ptr, "insufficient memory to read chunk");
   1.322 +      }
   1.323 +   }
   1.324 +
   1.325 +   return buffer;
   1.326 +}
   1.327 +#endif /* PNG_READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */
   1.328 +
   1.329 +/* png_inflate_claim: claim the zstream for some nefarious purpose that involves
   1.330 + * decompression.  Returns Z_OK on success, else a zlib error code.  It checks
   1.331 + * the owner but, in final release builds, just issues a warning if some other
   1.332 + * chunk apparently owns the stream.  Prior to release it does a png_error.
   1.333 + */
   1.334 +static int
   1.335 +png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
   1.336 +{
   1.337 +   if (png_ptr->zowner != 0)
   1.338 +   {
   1.339 +      char msg[64];
   1.340 +
   1.341 +      PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner);
   1.342 +      /* So the message that results is "<chunk> using zstream"; this is an
   1.343 +       * internal error, but is very useful for debugging.  i18n requirements
   1.344 +       * are minimal.
   1.345 +       */
   1.346 +      (void)png_safecat(msg, (sizeof msg), 4, " using zstream");
   1.347 +#     if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
   1.348 +         png_chunk_warning(png_ptr, msg);
   1.349 +         png_ptr->zowner = 0;
   1.350 +#     else
   1.351 +         png_chunk_error(png_ptr, msg);
   1.352 +#     endif
   1.353 +   }
   1.354 +
   1.355 +   /* Implementation note: unlike 'png_deflate_claim' this internal function
   1.356 +    * does not take the size of the data as an argument.  Some efficiency could
   1.357 +    * be gained by using this when it is known *if* the zlib stream itself does
   1.358 +    * not record the number; however, this is an illusion: the original writer
   1.359 +    * of the PNG may have selected a lower window size, and we really must
   1.360 +    * follow that because, for systems with with limited capabilities, we
   1.361 +    * would otherwise reject the application's attempts to use a smaller window
   1.362 +    * size (zlib doesn't have an interface to say "this or lower"!).
   1.363 +    *
   1.364 +    * inflateReset2 was added to zlib 1.2.4; before this the window could not be
   1.365 +    * reset, therefore it is necessary to always allocate the maximum window
   1.366 +    * size with earlier zlibs just in case later compressed chunks need it.
   1.367 +    */
   1.368 +   {
   1.369 +      int ret; /* zlib return code */
   1.370 +#     if PNG_ZLIB_VERNUM >= 0x1240
   1.371 +
   1.372 +#        if defined(PNG_SET_OPTION_SUPPORTED) && \
   1.373 +            defined(PNG_MAXIMUM_INFLATE_WINDOW)
   1.374 +            int window_bits;
   1.375 +
   1.376 +            if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
   1.377 +               PNG_OPTION_ON)
   1.378 +               window_bits = 15;
   1.379 +
   1.380 +            else
   1.381 +               window_bits = 0;
   1.382 +#        else
   1.383 +#           define window_bits 0
   1.384 +#        endif
   1.385 +#     endif
   1.386 +
   1.387 +      /* Set this for safety, just in case the previous owner left pointers to
   1.388 +       * memory allocations.
   1.389 +       */
   1.390 +      png_ptr->zstream.next_in = NULL;
   1.391 +      png_ptr->zstream.avail_in = 0;
   1.392 +      png_ptr->zstream.next_out = NULL;
   1.393 +      png_ptr->zstream.avail_out = 0;
   1.394 +
   1.395 +      if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
   1.396 +      {
   1.397 +#        if PNG_ZLIB_VERNUM < 0x1240
   1.398 +            ret = inflateReset(&png_ptr->zstream);
   1.399 +#        else
   1.400 +            ret = inflateReset2(&png_ptr->zstream, window_bits);
   1.401 +#        endif
   1.402 +      }
   1.403 +
   1.404 +      else
   1.405 +      {
   1.406 +#        if PNG_ZLIB_VERNUM < 0x1240
   1.407 +            ret = inflateInit(&png_ptr->zstream);
   1.408 +#        else
   1.409 +            ret = inflateInit2(&png_ptr->zstream, window_bits);
   1.410 +#        endif
   1.411 +
   1.412 +         if (ret == Z_OK)
   1.413 +            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
   1.414 +      }
   1.415 +
   1.416 +      if (ret == Z_OK)
   1.417 +         png_ptr->zowner = owner;
   1.418 +
   1.419 +      else
   1.420 +         png_zstream_error(png_ptr, ret);
   1.421 +
   1.422 +      return ret;
   1.423 +   }
   1.424 +
   1.425 +#  ifdef window_bits
   1.426 +#     undef window_bits
   1.427 +#  endif
   1.428 +}
   1.429 +
   1.430 +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
   1.431 +/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
   1.432 + * allow the caller to do multiple calls if required.  If the 'finish' flag is
   1.433 + * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
   1.434 + * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and
   1.435 + * Z_OK or Z_STREAM_END will be returned on success.
   1.436 + *
   1.437 + * The input and output sizes are updated to the actual amounts of data consumed
   1.438 + * or written, not the amount available (as in a z_stream).  The data pointers
   1.439 + * are not changed, so the next input is (data+input_size) and the next
   1.440 + * available output is (output+output_size).
   1.441 + */
   1.442 +static int
   1.443 +png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
   1.444 +    /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr,
   1.445 +    /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr)
   1.446 +{
   1.447 +   if (png_ptr->zowner == owner) /* Else not claimed */
   1.448 +   {
   1.449 +      int ret;
   1.450 +      png_alloc_size_t avail_out = *output_size_ptr;
   1.451 +      png_uint_32 avail_in = *input_size_ptr;
   1.452 +
   1.453 +      /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it
   1.454 +       * can't even necessarily handle 65536 bytes) because the type uInt is
   1.455 +       * "16 bits or more".  Consequently it is necessary to chunk the input to
   1.456 +       * zlib.  This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the
   1.457 +       * maximum value that can be stored in a uInt.)  It is possible to set
   1.458 +       * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have
   1.459 +       * a performance advantage, because it reduces the amount of data accessed
   1.460 +       * at each step and that may give the OS more time to page it in.
   1.461 +       */
   1.462 +      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
   1.463 +      /* avail_in and avail_out are set below from 'size' */
   1.464 +      png_ptr->zstream.avail_in = 0;
   1.465 +      png_ptr->zstream.avail_out = 0;
   1.466 +
   1.467 +      /* Read directly into the output if it is available (this is set to
   1.468 +       * a local buffer below if output is NULL).
   1.469 +       */
   1.470 +      if (output != NULL)
   1.471 +         png_ptr->zstream.next_out = output;
   1.472 +
   1.473 +      do
   1.474 +      {
   1.475 +         uInt avail;
   1.476 +         Byte local_buffer[PNG_INFLATE_BUF_SIZE];
   1.477 +
   1.478 +         /* zlib INPUT BUFFER */
   1.479 +         /* The setting of 'avail_in' used to be outside the loop; by setting it
   1.480 +          * inside it is possible to chunk the input to zlib and simply rely on
   1.481 +          * zlib to advance the 'next_in' pointer.  This allows arbitrary
   1.482 +          * amounts of data to be passed through zlib at the unavoidable cost of
   1.483 +          * requiring a window save (memcpy of up to 32768 output bytes)
   1.484 +          * every ZLIB_IO_MAX input bytes.
   1.485 +          */
   1.486 +         avail_in += png_ptr->zstream.avail_in; /* not consumed last time */
   1.487 +
   1.488 +         avail = ZLIB_IO_MAX;
   1.489 +
   1.490 +         if (avail_in < avail)
   1.491 +            avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */
   1.492 +
   1.493 +         avail_in -= avail;
   1.494 +         png_ptr->zstream.avail_in = avail;
   1.495 +
   1.496 +         /* zlib OUTPUT BUFFER */
   1.497 +         avail_out += png_ptr->zstream.avail_out; /* not written last time */
   1.498 +
   1.499 +         avail = ZLIB_IO_MAX; /* maximum zlib can process */
   1.500 +
   1.501 +         if (output == NULL)
   1.502 +         {
   1.503 +            /* Reset the output buffer each time round if output is NULL and
   1.504 +             * make available the full buffer, up to 'remaining_space'
   1.505 +             */
   1.506 +            png_ptr->zstream.next_out = local_buffer;
   1.507 +            if ((sizeof local_buffer) < avail)
   1.508 +               avail = (sizeof local_buffer);
   1.509 +         }
   1.510 +
   1.511 +         if (avail_out < avail)
   1.512 +            avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */
   1.513 +
   1.514 +         png_ptr->zstream.avail_out = avail;
   1.515 +         avail_out -= avail;
   1.516 +
   1.517 +         /* zlib inflate call */
   1.518 +         /* In fact 'avail_out' may be 0 at this point, that happens at the end
   1.519 +          * of the read when the final LZ end code was not passed at the end of
   1.520 +          * the previous chunk of input data.  Tell zlib if we have reached the
   1.521 +          * end of the output buffer.
   1.522 +          */
   1.523 +         ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH :
   1.524 +            (finish ? Z_FINISH : Z_SYNC_FLUSH));
   1.525 +      } while (ret == Z_OK);
   1.526 +
   1.527 +      /* For safety kill the local buffer pointer now */
   1.528 +      if (output == NULL)
   1.529 +         png_ptr->zstream.next_out = NULL;
   1.530 +
   1.531 +      /* Claw back the 'size' and 'remaining_space' byte counts. */
   1.532 +      avail_in += png_ptr->zstream.avail_in;
   1.533 +      avail_out += png_ptr->zstream.avail_out;
   1.534 +
   1.535 +      /* Update the input and output sizes; the updated values are the amount
   1.536 +       * consumed or written, effectively the inverse of what zlib uses.
   1.537 +       */
   1.538 +      if (avail_out > 0)
   1.539 +         *output_size_ptr -= avail_out;
   1.540 +
   1.541 +      if (avail_in > 0)
   1.542 +         *input_size_ptr -= avail_in;
   1.543 +
   1.544 +      /* Ensure png_ptr->zstream.msg is set (even in the success case!) */
   1.545 +      png_zstream_error(png_ptr, ret);
   1.546 +      return ret;
   1.547 +   }
   1.548 +
   1.549 +   else
   1.550 +   {
   1.551 +      /* This is a bad internal error.  The recovery assigns to the zstream msg
   1.552 +       * pointer, which is not owned by the caller, but this is safe; it's only
   1.553 +       * used on errors!
   1.554 +       */
   1.555 +      png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
   1.556 +      return Z_STREAM_ERROR;
   1.557 +   }
   1.558 +}
   1.559 +
   1.560 +/*
   1.561 + * Decompress trailing data in a chunk.  The assumption is that read_buffer
   1.562 + * points at an allocated area holding the contents of a chunk with a
   1.563 + * trailing compressed part.  What we get back is an allocated area
   1.564 + * holding the original prefix part and an uncompressed version of the
   1.565 + * trailing part (the malloc area passed in is freed).
   1.566 + */
   1.567 +static int
   1.568 +png_decompress_chunk(png_structrp png_ptr,
   1.569 +   png_uint_32 chunklength, png_uint_32 prefix_size,
   1.570 +   png_alloc_size_t *newlength /* must be initialized to the maximum! */,
   1.571 +   int terminate /*add a '\0' to the end of the uncompressed data*/)
   1.572 +{
   1.573 +   /* TODO: implement different limits for different types of chunk.
   1.574 +    *
   1.575 +    * The caller supplies *newlength set to the maximum length of the
   1.576 +    * uncompressed data, but this routine allocates space for the prefix and
   1.577 +    * maybe a '\0' terminator too.  We have to assume that 'prefix_size' is
   1.578 +    * limited only by the maximum chunk size.
   1.579 +    */
   1.580 +   png_alloc_size_t limit = PNG_SIZE_MAX;
   1.581 +
   1.582 +#  ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
   1.583 +      if (png_ptr->user_chunk_malloc_max > 0 &&
   1.584 +         png_ptr->user_chunk_malloc_max < limit)
   1.585 +         limit = png_ptr->user_chunk_malloc_max;
   1.586 +#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
   1.587 +      if (PNG_USER_CHUNK_MALLOC_MAX < limit)
   1.588 +         limit = PNG_USER_CHUNK_MALLOC_MAX;
   1.589 +#  endif
   1.590 +
   1.591 +   if (limit >= prefix_size + (terminate != 0))
   1.592 +   {
   1.593 +      int ret;
   1.594 +
   1.595 +      limit -= prefix_size + (terminate != 0);
   1.596 +
   1.597 +      if (limit < *newlength)
   1.598 +         *newlength = limit;
   1.599 +
   1.600 +      /* Now try to claim the stream. */
   1.601 +      ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);
   1.602 +
   1.603 +      if (ret == Z_OK)
   1.604 +      {
   1.605 +         png_uint_32 lzsize = chunklength - prefix_size;
   1.606 +
   1.607 +         ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
   1.608 +            /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
   1.609 +            /* output: */ NULL, newlength);
   1.610 +
   1.611 +         if (ret == Z_STREAM_END)
   1.612 +         {
   1.613 +            /* Use 'inflateReset' here, not 'inflateReset2' because this
   1.614 +             * preserves the previously decided window size (otherwise it would
   1.615 +             * be necessary to store the previous window size.)  In practice
   1.616 +             * this doesn't matter anyway, because png_inflate will call inflate
   1.617 +             * with Z_FINISH in almost all cases, so the window will not be
   1.618 +             * maintained.
   1.619 +             */
   1.620 +            if (inflateReset(&png_ptr->zstream) == Z_OK)
   1.621 +            {
   1.622 +               /* Because of the limit checks above we know that the new,
   1.623 +                * expanded, size will fit in a size_t (let alone an
   1.624 +                * png_alloc_size_t).  Use png_malloc_base here to avoid an
   1.625 +                * extra OOM message.
   1.626 +                */
   1.627 +               png_alloc_size_t new_size = *newlength;
   1.628 +               png_alloc_size_t buffer_size = prefix_size + new_size +
   1.629 +                  (terminate != 0);
   1.630 +               png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
   1.631 +                  buffer_size));
   1.632 +
   1.633 +               if (text != NULL)
   1.634 +               {
   1.635 +                  ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
   1.636 +                     png_ptr->read_buffer + prefix_size, &lzsize,
   1.637 +                     text + prefix_size, newlength);
   1.638 +
   1.639 +                  if (ret == Z_STREAM_END)
   1.640 +                  {
   1.641 +                     if (new_size == *newlength)
   1.642 +                     {
   1.643 +                        if (terminate)
   1.644 +                           text[prefix_size + *newlength] = 0;
   1.645 +
   1.646 +                        if (prefix_size > 0)
   1.647 +                           memcpy(text, png_ptr->read_buffer, prefix_size);
   1.648 +
   1.649 +                        {
   1.650 +                           png_bytep old_ptr = png_ptr->read_buffer;
   1.651 +
   1.652 +                           png_ptr->read_buffer = text;
   1.653 +                           png_ptr->read_buffer_size = buffer_size;
   1.654 +                           text = old_ptr; /* freed below */
   1.655 +                        }
   1.656 +                     }
   1.657 +
   1.658 +                     else
   1.659 +                     {
   1.660 +                        /* The size changed on the second read, there can be no
   1.661 +                         * guarantee that anything is correct at this point.
   1.662 +                         * The 'msg' pointer has been set to "unexpected end of
   1.663 +                         * LZ stream", which is fine, but return an error code
   1.664 +                         * that the caller won't accept.
   1.665 +                         */
   1.666 +                        ret = PNG_UNEXPECTED_ZLIB_RETURN;
   1.667 +                     }
   1.668 +                  }
   1.669 +
   1.670 +                  else if (ret == Z_OK)
   1.671 +                     ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */
   1.672 +
   1.673 +                  /* Free the text pointer (this is the old read_buffer on
   1.674 +                   * success)
   1.675 +                   */
   1.676 +                  png_free(png_ptr, text);
   1.677 +
   1.678 +                  /* This really is very benign, but it's still an error because
   1.679 +                   * the extra space may otherwise be used as a Trojan Horse.
   1.680 +                   */
   1.681 +                  if (ret == Z_STREAM_END &&
   1.682 +                     chunklength - prefix_size != lzsize)
   1.683 +                     png_chunk_benign_error(png_ptr, "extra compressed data");
   1.684 +               }
   1.685 +
   1.686 +               else
   1.687 +               {
   1.688 +                  /* Out of memory allocating the buffer */
   1.689 +                  ret = Z_MEM_ERROR;
   1.690 +                  png_zstream_error(png_ptr, Z_MEM_ERROR);
   1.691 +               }
   1.692 +            }
   1.693 +
   1.694 +            else
   1.695 +            {
   1.696 +               /* inflateReset failed, store the error message */
   1.697 +               png_zstream_error(png_ptr, ret);
   1.698 +
   1.699 +               if (ret == Z_STREAM_END)
   1.700 +                  ret = PNG_UNEXPECTED_ZLIB_RETURN;
   1.701 +            }
   1.702 +         }
   1.703 +
   1.704 +         else if (ret == Z_OK)
   1.705 +            ret = PNG_UNEXPECTED_ZLIB_RETURN;
   1.706 +
   1.707 +         /* Release the claimed stream */
   1.708 +         png_ptr->zowner = 0;
   1.709 +      }
   1.710 +
   1.711 +      else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */
   1.712 +         ret = PNG_UNEXPECTED_ZLIB_RETURN;
   1.713 +
   1.714 +      return ret;
   1.715 +   }
   1.716 +
   1.717 +   else
   1.718 +   {
   1.719 +      /* Application/configuration limits exceeded */
   1.720 +      png_zstream_error(png_ptr, Z_MEM_ERROR);
   1.721 +      return Z_MEM_ERROR;
   1.722 +   }
   1.723 +}
   1.724 +#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
   1.725 +
   1.726 +#ifdef PNG_READ_iCCP_SUPPORTED
   1.727 +/* Perform a partial read and decompress, producing 'avail_out' bytes and
   1.728 + * reading from the current chunk as required.
   1.729 + */
   1.730 +static int
   1.731 +png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
   1.732 +   png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
   1.733 +   int finish)
   1.734 +{
   1.735 +   if (png_ptr->zowner == png_ptr->chunk_name)
   1.736 +   {
   1.737 +      int ret;
   1.738 +
   1.739 +      /* next_in and avail_in must have been initialized by the caller. */
   1.740 +      png_ptr->zstream.next_out = next_out;
   1.741 +      png_ptr->zstream.avail_out = 0; /* set in the loop */
   1.742 +
   1.743 +      do
   1.744 +      {
   1.745 +         if (png_ptr->zstream.avail_in == 0)
   1.746 +         {
   1.747 +            if (read_size > *chunk_bytes)
   1.748 +               read_size = (uInt)*chunk_bytes;
   1.749 +            *chunk_bytes -= read_size;
   1.750 +
   1.751 +            if (read_size > 0)
   1.752 +               png_crc_read(png_ptr, read_buffer, read_size);
   1.753 +
   1.754 +            png_ptr->zstream.next_in = read_buffer;
   1.755 +            png_ptr->zstream.avail_in = read_size;
   1.756 +         }
   1.757 +
   1.758 +         if (png_ptr->zstream.avail_out == 0)
   1.759 +         {
   1.760 +            uInt avail = ZLIB_IO_MAX;
   1.761 +            if (avail > *out_size)
   1.762 +               avail = (uInt)*out_size;
   1.763 +            *out_size -= avail;
   1.764 +
   1.765 +            png_ptr->zstream.avail_out = avail;
   1.766 +         }
   1.767 +
   1.768 +         /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all
   1.769 +          * the available output is produced; this allows reading of truncated
   1.770 +          * streams.
   1.771 +          */
   1.772 +         ret = inflate(&png_ptr->zstream,
   1.773 +            *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
   1.774 +      }
   1.775 +      while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
   1.776 +
   1.777 +      *out_size += png_ptr->zstream.avail_out;
   1.778 +      png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */
   1.779 +
   1.780 +      /* Ensure the error message pointer is always set: */
   1.781 +      png_zstream_error(png_ptr, ret);
   1.782 +      return ret;
   1.783 +   }
   1.784 +
   1.785 +   else
   1.786 +   {
   1.787 +      png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
   1.788 +      return Z_STREAM_ERROR;
   1.789 +   }
   1.790 +}
   1.791 +#endif
   1.792 +
   1.793 +/* Read and check the IDHR chunk */
   1.794 +void /* PRIVATE */
   1.795 +png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
   1.796 +{
   1.797 +   png_byte buf[13];
   1.798 +   png_uint_32 width, height;
   1.799 +   int bit_depth, color_type, compression_type, filter_type;
   1.800 +   int interlace_type;
   1.801 +
   1.802 +   png_debug(1, "in png_handle_IHDR");
   1.803 +
   1.804 +   if (png_ptr->mode & PNG_HAVE_IHDR)
   1.805 +      png_chunk_error(png_ptr, "out of place");
   1.806 +
   1.807 +   /* Check the length */
   1.808 +   if (length != 13)
   1.809 +      png_chunk_error(png_ptr, "invalid");
   1.810 +
   1.811 +   png_ptr->mode |= PNG_HAVE_IHDR;
   1.812 +
   1.813 +   png_crc_read(png_ptr, buf, 13);
   1.814 +   png_crc_finish(png_ptr, 0);
   1.815 +
   1.816 +   width = png_get_uint_31(png_ptr, buf);
   1.817 +   height = png_get_uint_31(png_ptr, buf + 4);
   1.818 +   bit_depth = buf[8];
   1.819 +   color_type = buf[9];
   1.820 +   compression_type = buf[10];
   1.821 +   filter_type = buf[11];
   1.822 +   interlace_type = buf[12];
   1.823 +
   1.824 +#ifdef PNG_READ_APNG_SUPPORTED
   1.825 +   png_ptr->first_frame_width = width;
   1.826 +   png_ptr->first_frame_height = height;
   1.827 +#endif
   1.828 +
   1.829 +   /* Set internal variables */
   1.830 +   png_ptr->width = width;
   1.831 +   png_ptr->height = height;
   1.832 +   png_ptr->bit_depth = (png_byte)bit_depth;
   1.833 +   png_ptr->interlaced = (png_byte)interlace_type;
   1.834 +   png_ptr->color_type = (png_byte)color_type;
   1.835 +#ifdef PNG_MNG_FEATURES_SUPPORTED
   1.836 +   png_ptr->filter_type = (png_byte)filter_type;
   1.837 +#endif
   1.838 +   png_ptr->compression_type = (png_byte)compression_type;
   1.839 +
   1.840 +   /* Find number of channels */
   1.841 +   switch (png_ptr->color_type)
   1.842 +   {
   1.843 +      default: /* invalid, png_set_IHDR calls png_error */
   1.844 +      case PNG_COLOR_TYPE_GRAY:
   1.845 +      case PNG_COLOR_TYPE_PALETTE:
   1.846 +         png_ptr->channels = 1;
   1.847 +         break;
   1.848 +
   1.849 +      case PNG_COLOR_TYPE_RGB:
   1.850 +         png_ptr->channels = 3;
   1.851 +         break;
   1.852 +
   1.853 +      case PNG_COLOR_TYPE_GRAY_ALPHA:
   1.854 +         png_ptr->channels = 2;
   1.855 +         break;
   1.856 +
   1.857 +      case PNG_COLOR_TYPE_RGB_ALPHA:
   1.858 +         png_ptr->channels = 4;
   1.859 +         break;
   1.860 +   }
   1.861 +
   1.862 +   /* Set up other useful info */
   1.863 +   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
   1.864 +   png_ptr->channels);
   1.865 +   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
   1.866 +   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
   1.867 +   png_debug1(3, "channels = %d", png_ptr->channels);
   1.868 +   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
   1.869 +   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
   1.870 +       color_type, interlace_type, compression_type, filter_type);
   1.871 +}
   1.872 +
   1.873 +/* Read and check the palette */
   1.874 +void /* PRIVATE */
   1.875 +png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
   1.876 +{
   1.877 +   png_color palette[PNG_MAX_PALETTE_LENGTH];
   1.878 +   int num, i;
   1.879 +#ifdef PNG_POINTER_INDEXING_SUPPORTED
   1.880 +   png_colorp pal_ptr;
   1.881 +#endif
   1.882 +
   1.883 +   png_debug(1, "in png_handle_PLTE");
   1.884 +
   1.885 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1.886 +      png_chunk_error(png_ptr, "missing IHDR");
   1.887 +
   1.888 +   /* Moved to before the 'after IDAT' check below because otherwise duplicate
   1.889 +    * PLTE chunks are potentially ignored (the spec says there shall not be more
   1.890 +    * than one PLTE, the error is not treated as benign, so this check trumps
   1.891 +    * the requirement that PLTE appears before IDAT.)
   1.892 +    */
   1.893 +   else if (png_ptr->mode & PNG_HAVE_PLTE)
   1.894 +      png_chunk_error(png_ptr, "duplicate");
   1.895 +
   1.896 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
   1.897 +   {
   1.898 +      /* This is benign because the non-benign error happened before, when an
   1.899 +       * IDAT was encountered in a color-mapped image with no PLTE.
   1.900 +       */
   1.901 +      png_crc_finish(png_ptr, length);
   1.902 +      png_chunk_benign_error(png_ptr, "out of place");
   1.903 +      return;
   1.904 +   }
   1.905 +
   1.906 +   png_ptr->mode |= PNG_HAVE_PLTE;
   1.907 +
   1.908 +   if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
   1.909 +   {
   1.910 +      png_crc_finish(png_ptr, length);
   1.911 +      png_chunk_benign_error(png_ptr, "ignored in grayscale PNG");
   1.912 +      return;
   1.913 +   }
   1.914 +
   1.915 +#ifndef PNG_READ_OPT_PLTE_SUPPORTED
   1.916 +   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
   1.917 +   {
   1.918 +      png_crc_finish(png_ptr, length);
   1.919 +      return;
   1.920 +   }
   1.921 +#endif
   1.922 +
   1.923 +   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
   1.924 +   {
   1.925 +      png_crc_finish(png_ptr, length);
   1.926 +
   1.927 +      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
   1.928 +         png_chunk_benign_error(png_ptr, "invalid");
   1.929 +
   1.930 +      else
   1.931 +         png_chunk_error(png_ptr, "invalid");
   1.932 +
   1.933 +      return;
   1.934 +   }
   1.935 +
   1.936 +   /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
   1.937 +   num = (int)length / 3;
   1.938 +
   1.939 +#ifdef PNG_POINTER_INDEXING_SUPPORTED
   1.940 +   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
   1.941 +   {
   1.942 +      png_byte buf[3];
   1.943 +
   1.944 +      png_crc_read(png_ptr, buf, 3);
   1.945 +      pal_ptr->red = buf[0];
   1.946 +      pal_ptr->green = buf[1];
   1.947 +      pal_ptr->blue = buf[2];
   1.948 +   }
   1.949 +#else
   1.950 +   for (i = 0; i < num; i++)
   1.951 +   {
   1.952 +      png_byte buf[3];
   1.953 +
   1.954 +      png_crc_read(png_ptr, buf, 3);
   1.955 +      /* Don't depend upon png_color being any order */
   1.956 +      palette[i].red = buf[0];
   1.957 +      palette[i].green = buf[1];
   1.958 +      palette[i].blue = buf[2];
   1.959 +   }
   1.960 +#endif
   1.961 +
   1.962 +   /* If we actually need the PLTE chunk (ie for a paletted image), we do
   1.963 +    * whatever the normal CRC configuration tells us.  However, if we
   1.964 +    * have an RGB image, the PLTE can be considered ancillary, so
   1.965 +    * we will act as though it is.
   1.966 +    */
   1.967 +#ifndef PNG_READ_OPT_PLTE_SUPPORTED
   1.968 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1.969 +#endif
   1.970 +   {
   1.971 +      png_crc_finish(png_ptr, 0);
   1.972 +   }
   1.973 +
   1.974 +#ifndef PNG_READ_OPT_PLTE_SUPPORTED
   1.975 +   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
   1.976 +   {
   1.977 +      /* If we don't want to use the data from an ancillary chunk,
   1.978 +       * we have two options: an error abort, or a warning and we
   1.979 +       * ignore the data in this chunk (which should be OK, since
   1.980 +       * it's considered ancillary for a RGB or RGBA image).
   1.981 +       *
   1.982 +       * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the
   1.983 +       * chunk type to determine whether to check the ancillary or the critical
   1.984 +       * flags.
   1.985 +       */
   1.986 +      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
   1.987 +      {
   1.988 +         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
   1.989 +            return;
   1.990 +
   1.991 +         else
   1.992 +            png_chunk_error(png_ptr, "CRC error");
   1.993 +      }
   1.994 +
   1.995 +      /* Otherwise, we (optionally) emit a warning and use the chunk. */
   1.996 +      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
   1.997 +         png_chunk_warning(png_ptr, "CRC error");
   1.998 +   }
   1.999 +#endif
  1.1000 +
  1.1001 +   /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its
  1.1002 +    * own copy of the palette.  This has the side effect that when png_start_row
  1.1003 +    * is called (this happens after any call to png_read_update_info) the
  1.1004 +    * info_ptr palette gets changed.  This is extremely unexpected and
  1.1005 +    * confusing.
  1.1006 +    *
  1.1007 +    * Fix this by not sharing the palette in this way.
  1.1008 +    */
  1.1009 +   png_set_PLTE(png_ptr, info_ptr, palette, num);
  1.1010 +
  1.1011 +   /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before
  1.1012 +    * IDAT.  Prior to 1.6.0 this was not checked; instead the code merely
  1.1013 +    * checked the apparent validity of a tRNS chunk inserted before PLTE on a
  1.1014 +    * palette PNG.  1.6.0 attempts to rigorously follow the standard and
  1.1015 +    * therefore does a benign error if the erroneous condition is detected *and*
  1.1016 +    * cancels the tRNS if the benign error returns.  The alternative is to
  1.1017 +    * amend the standard since it would be rather hypocritical of the standards
  1.1018 +    * maintainers to ignore it.
  1.1019 +    */
  1.1020 +#ifdef PNG_READ_tRNS_SUPPORTED
  1.1021 +   if (png_ptr->num_trans > 0 ||
  1.1022 +      (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))
  1.1023 +   {
  1.1024 +      /* Cancel this because otherwise it would be used if the transforms
  1.1025 +       * require it.  Don't cancel the 'valid' flag because this would prevent
  1.1026 +       * detection of duplicate chunks.
  1.1027 +       */
  1.1028 +      png_ptr->num_trans = 0;
  1.1029 +
  1.1030 +      if (info_ptr != NULL)
  1.1031 +         info_ptr->num_trans = 0;
  1.1032 +
  1.1033 +      png_chunk_benign_error(png_ptr, "tRNS must be after");
  1.1034 +   }
  1.1035 +#endif
  1.1036 +
  1.1037 +#ifdef PNG_READ_hIST_SUPPORTED
  1.1038 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
  1.1039 +      png_chunk_benign_error(png_ptr, "hIST must be after");
  1.1040 +#endif
  1.1041 +
  1.1042 +#ifdef PNG_READ_bKGD_SUPPORTED
  1.1043 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
  1.1044 +      png_chunk_benign_error(png_ptr, "bKGD must be after");
  1.1045 +#endif
  1.1046 +}
  1.1047 +
  1.1048 +void /* PRIVATE */
  1.1049 +png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1050 +{
  1.1051 +   png_debug(1, "in png_handle_IEND");
  1.1052 +
  1.1053 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
  1.1054 +      png_chunk_error(png_ptr, "out of place");
  1.1055 +
  1.1056 +   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
  1.1057 +
  1.1058 +   png_crc_finish(png_ptr, length);
  1.1059 +
  1.1060 +   if (length != 0)
  1.1061 +      png_chunk_benign_error(png_ptr, "invalid");
  1.1062 +
  1.1063 +   PNG_UNUSED(info_ptr)
  1.1064 +}
  1.1065 +
  1.1066 +#ifdef PNG_READ_gAMA_SUPPORTED
  1.1067 +void /* PRIVATE */
  1.1068 +png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1069 +{
  1.1070 +   png_fixed_point igamma;
  1.1071 +   png_byte buf[4];
  1.1072 +
  1.1073 +   png_debug(1, "in png_handle_gAMA");
  1.1074 +
  1.1075 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1076 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1077 +
  1.1078 +   else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
  1.1079 +   {
  1.1080 +      png_crc_finish(png_ptr, length);
  1.1081 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1082 +      return;
  1.1083 +   }
  1.1084 +
  1.1085 +   if (length != 4)
  1.1086 +   {
  1.1087 +      png_crc_finish(png_ptr, length);
  1.1088 +      png_chunk_benign_error(png_ptr, "invalid");
  1.1089 +      return;
  1.1090 +   }
  1.1091 +
  1.1092 +   png_crc_read(png_ptr, buf, 4);
  1.1093 +
  1.1094 +   if (png_crc_finish(png_ptr, 0))
  1.1095 +      return;
  1.1096 +
  1.1097 +   igamma = png_get_fixed_point(NULL, buf);
  1.1098 +
  1.1099 +   png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma);
  1.1100 +   png_colorspace_sync(png_ptr, info_ptr);
  1.1101 +}
  1.1102 +#endif
  1.1103 +
  1.1104 +#ifdef PNG_READ_sBIT_SUPPORTED
  1.1105 +void /* PRIVATE */
  1.1106 +png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1107 +{
  1.1108 +   unsigned int truelen, i;
  1.1109 +   png_byte sample_depth;
  1.1110 +   png_byte buf[4];
  1.1111 +
  1.1112 +   png_debug(1, "in png_handle_sBIT");
  1.1113 +
  1.1114 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1115 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1116 +
  1.1117 +   else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
  1.1118 +   {
  1.1119 +      png_crc_finish(png_ptr, length);
  1.1120 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1121 +      return;
  1.1122 +   }
  1.1123 +
  1.1124 +   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
  1.1125 +   {
  1.1126 +      png_crc_finish(png_ptr, length);
  1.1127 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.1128 +      return;
  1.1129 +   }
  1.1130 +
  1.1131 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1.1132 +   {
  1.1133 +      truelen = 3;
  1.1134 +      sample_depth = 8;
  1.1135 +   }
  1.1136 +
  1.1137 +   else
  1.1138 +   {
  1.1139 +      truelen = png_ptr->channels;
  1.1140 +      sample_depth = png_ptr->bit_depth;
  1.1141 +   }
  1.1142 +
  1.1143 +   if (length != truelen || length > 4)
  1.1144 +   {
  1.1145 +      png_chunk_benign_error(png_ptr, "invalid");
  1.1146 +      png_crc_finish(png_ptr, length);
  1.1147 +      return;
  1.1148 +   }
  1.1149 +
  1.1150 +   buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;
  1.1151 +   png_crc_read(png_ptr, buf, truelen);
  1.1152 +
  1.1153 +   if (png_crc_finish(png_ptr, 0))
  1.1154 +      return;
  1.1155 +
  1.1156 +   for (i=0; i<truelen; ++i)
  1.1157 +      if (buf[i] == 0 || buf[i] > sample_depth)
  1.1158 +      {
  1.1159 +         png_chunk_benign_error(png_ptr, "invalid");
  1.1160 +         return;
  1.1161 +      }
  1.1162 +
  1.1163 +   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1.1164 +   {
  1.1165 +      png_ptr->sig_bit.red = buf[0];
  1.1166 +      png_ptr->sig_bit.green = buf[1];
  1.1167 +      png_ptr->sig_bit.blue = buf[2];
  1.1168 +      png_ptr->sig_bit.alpha = buf[3];
  1.1169 +   }
  1.1170 +
  1.1171 +   else
  1.1172 +   {
  1.1173 +      png_ptr->sig_bit.gray = buf[0];
  1.1174 +      png_ptr->sig_bit.red = buf[0];
  1.1175 +      png_ptr->sig_bit.green = buf[0];
  1.1176 +      png_ptr->sig_bit.blue = buf[0];
  1.1177 +      png_ptr->sig_bit.alpha = buf[1];
  1.1178 +   }
  1.1179 +
  1.1180 +   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
  1.1181 +}
  1.1182 +#endif
  1.1183 +
  1.1184 +#ifdef PNG_READ_cHRM_SUPPORTED
  1.1185 +void /* PRIVATE */
  1.1186 +png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1187 +{
  1.1188 +   png_byte buf[32];
  1.1189 +   png_xy xy;
  1.1190 +
  1.1191 +   png_debug(1, "in png_handle_cHRM");
  1.1192 +
  1.1193 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1194 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1195 +
  1.1196 +   else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
  1.1197 +   {
  1.1198 +      png_crc_finish(png_ptr, length);
  1.1199 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1200 +      return;
  1.1201 +   }
  1.1202 +
  1.1203 +   if (length != 32)
  1.1204 +   {
  1.1205 +      png_crc_finish(png_ptr, length);
  1.1206 +      png_chunk_benign_error(png_ptr, "invalid");
  1.1207 +      return;
  1.1208 +   }
  1.1209 +
  1.1210 +   png_crc_read(png_ptr, buf, 32);
  1.1211 +
  1.1212 +   if (png_crc_finish(png_ptr, 0))
  1.1213 +      return;
  1.1214 +
  1.1215 +   xy.whitex = png_get_fixed_point(NULL, buf);
  1.1216 +   xy.whitey = png_get_fixed_point(NULL, buf + 4);
  1.1217 +   xy.redx   = png_get_fixed_point(NULL, buf + 8);
  1.1218 +   xy.redy   = png_get_fixed_point(NULL, buf + 12);
  1.1219 +   xy.greenx = png_get_fixed_point(NULL, buf + 16);
  1.1220 +   xy.greeny = png_get_fixed_point(NULL, buf + 20);
  1.1221 +   xy.bluex  = png_get_fixed_point(NULL, buf + 24);
  1.1222 +   xy.bluey  = png_get_fixed_point(NULL, buf + 28);
  1.1223 +
  1.1224 +   if (xy.whitex == PNG_FIXED_ERROR ||
  1.1225 +       xy.whitey == PNG_FIXED_ERROR ||
  1.1226 +       xy.redx   == PNG_FIXED_ERROR ||
  1.1227 +       xy.redy   == PNG_FIXED_ERROR ||
  1.1228 +       xy.greenx == PNG_FIXED_ERROR ||
  1.1229 +       xy.greeny == PNG_FIXED_ERROR ||
  1.1230 +       xy.bluex  == PNG_FIXED_ERROR ||
  1.1231 +       xy.bluey  == PNG_FIXED_ERROR)
  1.1232 +   {
  1.1233 +      png_chunk_benign_error(png_ptr, "invalid values");
  1.1234 +      return;
  1.1235 +   }
  1.1236 +
  1.1237 +   /* If a colorspace error has already been output skip this chunk */
  1.1238 +   if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
  1.1239 +      return;
  1.1240 +
  1.1241 +   if (png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM)
  1.1242 +   {
  1.1243 +      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
  1.1244 +      png_colorspace_sync(png_ptr, info_ptr);
  1.1245 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.1246 +      return;
  1.1247 +   }
  1.1248 +
  1.1249 +   png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
  1.1250 +   (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
  1.1251 +      1/*prefer cHRM values*/);
  1.1252 +   png_colorspace_sync(png_ptr, info_ptr);
  1.1253 +}
  1.1254 +#endif
  1.1255 +
  1.1256 +#ifdef PNG_READ_sRGB_SUPPORTED
  1.1257 +void /* PRIVATE */
  1.1258 +png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1259 +{
  1.1260 +   png_byte intent;
  1.1261 +
  1.1262 +   png_debug(1, "in png_handle_sRGB");
  1.1263 +
  1.1264 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1265 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1266 +
  1.1267 +   else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
  1.1268 +   {
  1.1269 +      png_crc_finish(png_ptr, length);
  1.1270 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1271 +      return;
  1.1272 +   }
  1.1273 +
  1.1274 +   if (length != 1)
  1.1275 +   {
  1.1276 +      png_crc_finish(png_ptr, length);
  1.1277 +      png_chunk_benign_error(png_ptr, "invalid");
  1.1278 +      return;
  1.1279 +   }
  1.1280 +
  1.1281 +   png_crc_read(png_ptr, &intent, 1);
  1.1282 +
  1.1283 +   if (png_crc_finish(png_ptr, 0))
  1.1284 +      return;
  1.1285 +
  1.1286 +   /* If a colorspace error has already been output skip this chunk */
  1.1287 +   if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
  1.1288 +      return;
  1.1289 +
  1.1290 +   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
  1.1291 +    * this.
  1.1292 +    */
  1.1293 +   if (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT)
  1.1294 +   {
  1.1295 +      png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
  1.1296 +      png_colorspace_sync(png_ptr, info_ptr);
  1.1297 +      png_chunk_benign_error(png_ptr, "too many profiles");
  1.1298 +      return;
  1.1299 +   }
  1.1300 +
  1.1301 +   (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
  1.1302 +   png_colorspace_sync(png_ptr, info_ptr);
  1.1303 +}
  1.1304 +#endif /* PNG_READ_sRGB_SUPPORTED */
  1.1305 +
  1.1306 +#ifdef PNG_READ_iCCP_SUPPORTED
  1.1307 +void /* PRIVATE */
  1.1308 +png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1309 +/* Note: this does not properly handle profiles that are > 64K under DOS */
  1.1310 +{
  1.1311 +   png_const_charp errmsg = NULL; /* error message output, or no error */
  1.1312 +   int finished = 0; /* crc checked */
  1.1313 +
  1.1314 +   png_debug(1, "in png_handle_iCCP");
  1.1315 +
  1.1316 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1317 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1318 +
  1.1319 +   else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
  1.1320 +   {
  1.1321 +      png_crc_finish(png_ptr, length);
  1.1322 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1323 +      return;
  1.1324 +   }
  1.1325 +
  1.1326 +   /* Consistent with all the above colorspace handling an obviously *invalid*
  1.1327 +    * chunk is just ignored, so does not invalidate the color space.  An
  1.1328 +    * alternative is to set the 'invalid' flags at the start of this routine
  1.1329 +    * and only clear them in they were not set before and all the tests pass.
  1.1330 +    * The minimum 'deflate' stream is assumed to be just the 2 byte header and 4
  1.1331 +    * byte checksum.  The keyword must be one character and there is a
  1.1332 +    * terminator (0) byte and the compression method.
  1.1333 +    */
  1.1334 +   if (length < 9)
  1.1335 +   {
  1.1336 +      png_crc_finish(png_ptr, length);
  1.1337 +      png_chunk_benign_error(png_ptr, "too short");
  1.1338 +      return;
  1.1339 +   }
  1.1340 +
  1.1341 +   /* If a colorspace error has already been output skip this chunk */
  1.1342 +   if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
  1.1343 +   {
  1.1344 +      png_crc_finish(png_ptr, length);
  1.1345 +      return;
  1.1346 +   }
  1.1347 +
  1.1348 +   /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
  1.1349 +    * this.
  1.1350 +    */
  1.1351 +   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0)
  1.1352 +   {
  1.1353 +      uInt read_length, keyword_length;
  1.1354 +      char keyword[81];
  1.1355 +
  1.1356 +      /* Find the keyword; the keyword plus separator and compression method
  1.1357 +       * bytes can be at most 81 characters long.
  1.1358 +       */
  1.1359 +      read_length = 81; /* maximum */
  1.1360 +      if (read_length > length)
  1.1361 +         read_length = (uInt)length;
  1.1362 +
  1.1363 +      png_crc_read(png_ptr, (png_bytep)keyword, read_length);
  1.1364 +      length -= read_length;
  1.1365 +
  1.1366 +      keyword_length = 0;
  1.1367 +      while (keyword_length < 80 && keyword_length < read_length &&
  1.1368 +         keyword[keyword_length] != 0)
  1.1369 +         ++keyword_length;
  1.1370 +
  1.1371 +      /* TODO: make the keyword checking common */
  1.1372 +      if (keyword_length >= 1 && keyword_length <= 79)
  1.1373 +      {
  1.1374 +         /* We only understand '0' compression - deflate - so if we get a
  1.1375 +          * different value we can't safely decode the chunk.
  1.1376 +          */
  1.1377 +         if (keyword_length+1 < read_length &&
  1.1378 +            keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE)
  1.1379 +         {
  1.1380 +            read_length -= keyword_length+2;
  1.1381 +
  1.1382 +            if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
  1.1383 +            {
  1.1384 +               Byte profile_header[132];
  1.1385 +               Byte local_buffer[PNG_INFLATE_BUF_SIZE];
  1.1386 +               png_alloc_size_t size = (sizeof profile_header);
  1.1387 +
  1.1388 +               png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
  1.1389 +               png_ptr->zstream.avail_in = read_length;
  1.1390 +               (void)png_inflate_read(png_ptr, local_buffer,
  1.1391 +                  (sizeof local_buffer), &length, profile_header, &size,
  1.1392 +                  0/*finish: don't, because the output is too small*/);
  1.1393 +
  1.1394 +               if (size == 0)
  1.1395 +               {
  1.1396 +                  /* We have the ICC profile header; do the basic header checks.
  1.1397 +                   */
  1.1398 +                  const png_uint_32 profile_length =
  1.1399 +                     png_get_uint_32(profile_header);
  1.1400 +
  1.1401 +                  if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
  1.1402 +                     keyword, profile_length))
  1.1403 +                  {
  1.1404 +                     /* The length is apparently ok, so we can check the 132
  1.1405 +                      * byte header.
  1.1406 +                      */
  1.1407 +                     if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
  1.1408 +                        keyword, profile_length, profile_header,
  1.1409 +                        png_ptr->color_type))
  1.1410 +                     {
  1.1411 +                        /* Now read the tag table; a variable size buffer is
  1.1412 +                         * needed at this point, allocate one for the whole
  1.1413 +                         * profile.  The header check has already validated
  1.1414 +                         * that none of these stuff will overflow.
  1.1415 +                         */
  1.1416 +                        const png_uint_32 tag_count = png_get_uint_32(
  1.1417 +                           profile_header+128);
  1.1418 +                        png_bytep profile = png_read_buffer(png_ptr,
  1.1419 +                           profile_length, 2/*silent*/);
  1.1420 +
  1.1421 +                        if (profile != NULL)
  1.1422 +                        {
  1.1423 +                           memcpy(profile, profile_header,
  1.1424 +                              (sizeof profile_header));
  1.1425 +
  1.1426 +                           size = 12 * tag_count;
  1.1427 +
  1.1428 +                           (void)png_inflate_read(png_ptr, local_buffer,
  1.1429 +                              (sizeof local_buffer), &length,
  1.1430 +                              profile + (sizeof profile_header), &size, 0);
  1.1431 +
  1.1432 +                           /* Still expect a buffer error because we expect
  1.1433 +                            * there to be some tag data!
  1.1434 +                            */
  1.1435 +                           if (size == 0)
  1.1436 +                           {
  1.1437 +                              if (png_icc_check_tag_table(png_ptr,
  1.1438 +                                 &png_ptr->colorspace, keyword, profile_length,
  1.1439 +                                 profile))
  1.1440 +                              {
  1.1441 +                                 /* The profile has been validated for basic
  1.1442 +                                  * security issues, so read the whole thing in.
  1.1443 +                                  */
  1.1444 +                                 size = profile_length - (sizeof profile_header)
  1.1445 +                                    - 12 * tag_count;
  1.1446 +
  1.1447 +                                 (void)png_inflate_read(png_ptr, local_buffer,
  1.1448 +                                    (sizeof local_buffer), &length,
  1.1449 +                                    profile + (sizeof profile_header) +
  1.1450 +                                    12 * tag_count, &size, 1/*finish*/);
  1.1451 +
  1.1452 +                                 if (length > 0 && !(png_ptr->flags &
  1.1453 +                                       PNG_FLAG_BENIGN_ERRORS_WARN))
  1.1454 +                                    errmsg = "extra compressed data";
  1.1455 +
  1.1456 +                                 /* But otherwise allow extra data: */
  1.1457 +                                 else if (size == 0)
  1.1458 +                                 {
  1.1459 +                                    if (length > 0)
  1.1460 +                                    {
  1.1461 +                                       /* This can be handled completely, so
  1.1462 +                                        * keep going.
  1.1463 +                                        */
  1.1464 +                                       png_chunk_warning(png_ptr,
  1.1465 +                                          "extra compressed data");
  1.1466 +                                    }
  1.1467 +
  1.1468 +                                    png_crc_finish(png_ptr, length);
  1.1469 +                                    finished = 1;
  1.1470 +
  1.1471 +#                                   ifdef PNG_sRGB_SUPPORTED
  1.1472 +                                       /* Check for a match against sRGB */
  1.1473 +                                       png_icc_set_sRGB(png_ptr,
  1.1474 +                                          &png_ptr->colorspace, profile,
  1.1475 +                                          png_ptr->zstream.adler);
  1.1476 +#                                   endif
  1.1477 +
  1.1478 +                                    /* Steal the profile for info_ptr. */
  1.1479 +                                    if (info_ptr != NULL)
  1.1480 +                                    {
  1.1481 +                                       png_free_data(png_ptr, info_ptr,
  1.1482 +                                          PNG_FREE_ICCP, 0);
  1.1483 +
  1.1484 +                                       info_ptr->iccp_name = png_voidcast(char*,
  1.1485 +                                          png_malloc_base(png_ptr,
  1.1486 +                                          keyword_length+1));
  1.1487 +                                       if (info_ptr->iccp_name != NULL)
  1.1488 +                                       {
  1.1489 +                                          memcpy(info_ptr->iccp_name, keyword,
  1.1490 +                                             keyword_length+1);
  1.1491 +                                          info_ptr->iccp_proflen =
  1.1492 +                                             profile_length;
  1.1493 +                                          info_ptr->iccp_profile = profile;
  1.1494 +                                          png_ptr->read_buffer = NULL; /*steal*/
  1.1495 +                                          info_ptr->free_me |= PNG_FREE_ICCP;
  1.1496 +                                          info_ptr->valid |= PNG_INFO_iCCP;
  1.1497 +                                       }
  1.1498 +
  1.1499 +                                       else
  1.1500 +                                       {
  1.1501 +                                          png_ptr->colorspace.flags |=
  1.1502 +                                             PNG_COLORSPACE_INVALID;
  1.1503 +                                          errmsg = "out of memory";
  1.1504 +                                       }
  1.1505 +                                    }
  1.1506 +
  1.1507 +                                    /* else the profile remains in the read
  1.1508 +                                     * buffer which gets reused for subsequent
  1.1509 +                                     * chunks.
  1.1510 +                                     */
  1.1511 +
  1.1512 +                                    if (info_ptr != NULL)
  1.1513 +                                       png_colorspace_sync(png_ptr, info_ptr);
  1.1514 +
  1.1515 +                                    if (errmsg == NULL)
  1.1516 +                                    {
  1.1517 +                                       png_ptr->zowner = 0;
  1.1518 +                                       return;
  1.1519 +                                    }
  1.1520 +                                 }
  1.1521 +
  1.1522 +                                 else if (size > 0)
  1.1523 +                                    errmsg = "truncated";
  1.1524 +
  1.1525 +                                 else
  1.1526 +                                    errmsg = png_ptr->zstream.msg;
  1.1527 +                              }
  1.1528 +
  1.1529 +                              /* else png_icc_check_tag_table output an error */
  1.1530 +                           }
  1.1531 +
  1.1532 +                           else /* profile truncated */
  1.1533 +                              errmsg = png_ptr->zstream.msg;
  1.1534 +                        }
  1.1535 +
  1.1536 +                        else
  1.1537 +                           errmsg = "out of memory";
  1.1538 +                     }
  1.1539 +
  1.1540 +                     /* else png_icc_check_header output an error */
  1.1541 +                  }
  1.1542 +
  1.1543 +                  /* else png_icc_check_length output an error */
  1.1544 +               }
  1.1545 +
  1.1546 +               else /* profile truncated */
  1.1547 +                  errmsg = png_ptr->zstream.msg;
  1.1548 +
  1.1549 +               /* Release the stream */
  1.1550 +               png_ptr->zowner = 0;
  1.1551 +            }
  1.1552 +
  1.1553 +            else /* png_inflate_claim failed */
  1.1554 +               errmsg = png_ptr->zstream.msg;
  1.1555 +         }
  1.1556 +
  1.1557 +         else
  1.1558 +            errmsg = "bad compression method"; /* or missing */
  1.1559 +      }
  1.1560 +
  1.1561 +      else
  1.1562 +         errmsg = "bad keyword";
  1.1563 +   }
  1.1564 +
  1.1565 +   else
  1.1566 +      errmsg = "too many profiles";
  1.1567 +
  1.1568 +   /* Failure: the reason is in 'errmsg' */
  1.1569 +   if (!finished)
  1.1570 +      png_crc_finish(png_ptr, length);
  1.1571 +
  1.1572 +   png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
  1.1573 +   png_colorspace_sync(png_ptr, info_ptr);
  1.1574 +   if (errmsg != NULL) /* else already output */
  1.1575 +      png_chunk_benign_error(png_ptr, errmsg);
  1.1576 +}
  1.1577 +#endif /* PNG_READ_iCCP_SUPPORTED */
  1.1578 +
  1.1579 +#ifdef PNG_READ_sPLT_SUPPORTED
  1.1580 +void /* PRIVATE */
  1.1581 +png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1582 +/* Note: this does not properly handle chunks that are > 64K under DOS */
  1.1583 +{
  1.1584 +   png_bytep entry_start, buffer;
  1.1585 +   png_sPLT_t new_palette;
  1.1586 +   png_sPLT_entryp pp;
  1.1587 +   png_uint_32 data_length;
  1.1588 +   int entry_size, i;
  1.1589 +   png_uint_32 skip = 0;
  1.1590 +   png_uint_32 dl;
  1.1591 +   png_size_t max_dl;
  1.1592 +
  1.1593 +   png_debug(1, "in png_handle_sPLT");
  1.1594 +
  1.1595 +#ifdef PNG_USER_LIMITS_SUPPORTED
  1.1596 +   if (png_ptr->user_chunk_cache_max != 0)
  1.1597 +   {
  1.1598 +      if (png_ptr->user_chunk_cache_max == 1)
  1.1599 +      {
  1.1600 +         png_crc_finish(png_ptr, length);
  1.1601 +         return;
  1.1602 +      }
  1.1603 +
  1.1604 +      if (--png_ptr->user_chunk_cache_max == 1)
  1.1605 +      {
  1.1606 +         png_warning(png_ptr, "No space in chunk cache for sPLT");
  1.1607 +         png_crc_finish(png_ptr, length);
  1.1608 +         return;
  1.1609 +      }
  1.1610 +   }
  1.1611 +#endif
  1.1612 +
  1.1613 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1614 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1615 +
  1.1616 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.1617 +   {
  1.1618 +      png_crc_finish(png_ptr, length);
  1.1619 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1620 +      return;
  1.1621 +   }
  1.1622 +
  1.1623 +#ifdef PNG_MAX_MALLOC_64K
  1.1624 +   if (length > 65535U)
  1.1625 +   {
  1.1626 +      png_crc_finish(png_ptr, length);
  1.1627 +      png_chunk_benign_error(png_ptr, "too large to fit in memory");
  1.1628 +      return;
  1.1629 +   }
  1.1630 +#endif
  1.1631 +
  1.1632 +   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
  1.1633 +   if (buffer == NULL)
  1.1634 +   {
  1.1635 +      png_crc_finish(png_ptr, length);
  1.1636 +      png_chunk_benign_error(png_ptr, "out of memory");
  1.1637 +      return;
  1.1638 +   }
  1.1639 +
  1.1640 +
  1.1641 +   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
  1.1642 +    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
  1.1643 +    * potential breakage point if the types in pngconf.h aren't exactly right.
  1.1644 +    */
  1.1645 +   png_crc_read(png_ptr, buffer, length);
  1.1646 +
  1.1647 +   if (png_crc_finish(png_ptr, skip))
  1.1648 +      return;
  1.1649 +
  1.1650 +   buffer[length] = 0;
  1.1651 +
  1.1652 +   for (entry_start = buffer; *entry_start; entry_start++)
  1.1653 +      /* Empty loop to find end of name */ ;
  1.1654 +
  1.1655 +   ++entry_start;
  1.1656 +
  1.1657 +   /* A sample depth should follow the separator, and we should be on it  */
  1.1658 +   if (entry_start > buffer + length - 2)
  1.1659 +   {
  1.1660 +      png_warning(png_ptr, "malformed sPLT chunk");
  1.1661 +      return;
  1.1662 +   }
  1.1663 +
  1.1664 +   new_palette.depth = *entry_start++;
  1.1665 +   entry_size = (new_palette.depth == 8 ? 6 : 10);
  1.1666 +   /* This must fit in a png_uint_32 because it is derived from the original
  1.1667 +    * chunk data length.
  1.1668 +    */
  1.1669 +   data_length = length - (png_uint_32)(entry_start - buffer);
  1.1670 +
  1.1671 +   /* Integrity-check the data length */
  1.1672 +   if (data_length % entry_size)
  1.1673 +   {
  1.1674 +      png_warning(png_ptr, "sPLT chunk has bad length");
  1.1675 +      return;
  1.1676 +   }
  1.1677 +
  1.1678 +   dl = (png_int_32)(data_length / entry_size);
  1.1679 +   max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
  1.1680 +
  1.1681 +   if (dl > max_dl)
  1.1682 +   {
  1.1683 +       png_warning(png_ptr, "sPLT chunk too long");
  1.1684 +       return;
  1.1685 +   }
  1.1686 +
  1.1687 +   new_palette.nentries = (png_int_32)(data_length / entry_size);
  1.1688 +
  1.1689 +   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
  1.1690 +       png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)));
  1.1691 +
  1.1692 +   if (new_palette.entries == NULL)
  1.1693 +   {
  1.1694 +       png_warning(png_ptr, "sPLT chunk requires too much memory");
  1.1695 +       return;
  1.1696 +   }
  1.1697 +
  1.1698 +#ifdef PNG_POINTER_INDEXING_SUPPORTED
  1.1699 +   for (i = 0; i < new_palette.nentries; i++)
  1.1700 +   {
  1.1701 +      pp = new_palette.entries + i;
  1.1702 +
  1.1703 +      if (new_palette.depth == 8)
  1.1704 +      {
  1.1705 +         pp->red = *entry_start++;
  1.1706 +         pp->green = *entry_start++;
  1.1707 +         pp->blue = *entry_start++;
  1.1708 +         pp->alpha = *entry_start++;
  1.1709 +      }
  1.1710 +
  1.1711 +      else
  1.1712 +      {
  1.1713 +         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
  1.1714 +         pp->green = png_get_uint_16(entry_start); entry_start += 2;
  1.1715 +         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
  1.1716 +         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
  1.1717 +      }
  1.1718 +
  1.1719 +      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
  1.1720 +   }
  1.1721 +#else
  1.1722 +   pp = new_palette.entries;
  1.1723 +
  1.1724 +   for (i = 0; i < new_palette.nentries; i++)
  1.1725 +   {
  1.1726 +
  1.1727 +      if (new_palette.depth == 8)
  1.1728 +      {
  1.1729 +         pp[i].red   = *entry_start++;
  1.1730 +         pp[i].green = *entry_start++;
  1.1731 +         pp[i].blue  = *entry_start++;
  1.1732 +         pp[i].alpha = *entry_start++;
  1.1733 +      }
  1.1734 +
  1.1735 +      else
  1.1736 +      {
  1.1737 +         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
  1.1738 +         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
  1.1739 +         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
  1.1740 +         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
  1.1741 +      }
  1.1742 +
  1.1743 +      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
  1.1744 +   }
  1.1745 +#endif
  1.1746 +
  1.1747 +   /* Discard all chunk data except the name and stash that */
  1.1748 +   new_palette.name = (png_charp)buffer;
  1.1749 +
  1.1750 +   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
  1.1751 +
  1.1752 +   png_free(png_ptr, new_palette.entries);
  1.1753 +}
  1.1754 +#endif /* PNG_READ_sPLT_SUPPORTED */
  1.1755 +
  1.1756 +#ifdef PNG_READ_tRNS_SUPPORTED
  1.1757 +void /* PRIVATE */
  1.1758 +png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1759 +{
  1.1760 +   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
  1.1761 +
  1.1762 +   png_debug(1, "in png_handle_tRNS");
  1.1763 +
  1.1764 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1765 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1766 +
  1.1767 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.1768 +   {
  1.1769 +      png_crc_finish(png_ptr, length);
  1.1770 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1771 +      return;
  1.1772 +   }
  1.1773 +
  1.1774 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  1.1775 +   {
  1.1776 +      png_crc_finish(png_ptr, length);
  1.1777 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.1778 +      return;
  1.1779 +   }
  1.1780 +
  1.1781 +   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  1.1782 +   {
  1.1783 +      png_byte buf[2];
  1.1784 +
  1.1785 +      if (length != 2)
  1.1786 +      {
  1.1787 +         png_crc_finish(png_ptr, length);
  1.1788 +         png_chunk_benign_error(png_ptr, "invalid");
  1.1789 +         return;
  1.1790 +      }
  1.1791 +
  1.1792 +      png_crc_read(png_ptr, buf, 2);
  1.1793 +      png_ptr->num_trans = 1;
  1.1794 +      png_ptr->trans_color.gray = png_get_uint_16(buf);
  1.1795 +   }
  1.1796 +
  1.1797 +   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  1.1798 +   {
  1.1799 +      png_byte buf[6];
  1.1800 +
  1.1801 +      if (length != 6)
  1.1802 +      {
  1.1803 +         png_crc_finish(png_ptr, length);
  1.1804 +         png_chunk_benign_error(png_ptr, "invalid");
  1.1805 +         return;
  1.1806 +      }
  1.1807 +
  1.1808 +      png_crc_read(png_ptr, buf, length);
  1.1809 +      png_ptr->num_trans = 1;
  1.1810 +      png_ptr->trans_color.red = png_get_uint_16(buf);
  1.1811 +      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
  1.1812 +      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
  1.1813 +   }
  1.1814 +
  1.1815 +   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1.1816 +   {
  1.1817 +      if (!(png_ptr->mode & PNG_HAVE_PLTE))
  1.1818 +      {
  1.1819 +         /* TODO: is this actually an error in the ISO spec? */
  1.1820 +         png_crc_finish(png_ptr, length);
  1.1821 +         png_chunk_benign_error(png_ptr, "out of place");
  1.1822 +         return;
  1.1823 +      }
  1.1824 +
  1.1825 +      if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH ||
  1.1826 +         length == 0)
  1.1827 +      {
  1.1828 +         png_crc_finish(png_ptr, length);
  1.1829 +         png_chunk_benign_error(png_ptr, "invalid");
  1.1830 +         return;
  1.1831 +      }
  1.1832 +
  1.1833 +      png_crc_read(png_ptr, readbuf, length);
  1.1834 +      png_ptr->num_trans = (png_uint_16)length;
  1.1835 +   }
  1.1836 +
  1.1837 +   else
  1.1838 +   {
  1.1839 +      png_crc_finish(png_ptr, length);
  1.1840 +      png_chunk_benign_error(png_ptr, "invalid with alpha channel");
  1.1841 +      return;
  1.1842 +   }
  1.1843 +
  1.1844 +   if (png_crc_finish(png_ptr, 0))
  1.1845 +   {
  1.1846 +      png_ptr->num_trans = 0;
  1.1847 +      return;
  1.1848 +   }
  1.1849 +
  1.1850 +   /* TODO: this is a horrible side effect in the palette case because the
  1.1851 +    * png_struct ends up with a pointer to the tRNS buffer owned by the
  1.1852 +    * png_info.  Fix this.
  1.1853 +    */
  1.1854 +   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
  1.1855 +       &(png_ptr->trans_color));
  1.1856 +}
  1.1857 +#endif
  1.1858 +
  1.1859 +#ifdef PNG_READ_bKGD_SUPPORTED
  1.1860 +void /* PRIVATE */
  1.1861 +png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1862 +{
  1.1863 +   unsigned int truelen;
  1.1864 +   png_byte buf[6];
  1.1865 +   png_color_16 background;
  1.1866 +
  1.1867 +   png_debug(1, "in png_handle_bKGD");
  1.1868 +
  1.1869 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1870 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1871 +
  1.1872 +   else if ((png_ptr->mode & PNG_HAVE_IDAT) ||
  1.1873 +      (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  1.1874 +       !(png_ptr->mode & PNG_HAVE_PLTE)))
  1.1875 +   {
  1.1876 +      png_crc_finish(png_ptr, length);
  1.1877 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1878 +      return;
  1.1879 +   }
  1.1880 +
  1.1881 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
  1.1882 +   {
  1.1883 +      png_crc_finish(png_ptr, length);
  1.1884 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.1885 +      return;
  1.1886 +   }
  1.1887 +
  1.1888 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1.1889 +      truelen = 1;
  1.1890 +
  1.1891 +   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1.1892 +      truelen = 6;
  1.1893 +
  1.1894 +   else
  1.1895 +      truelen = 2;
  1.1896 +
  1.1897 +   if (length != truelen)
  1.1898 +   {
  1.1899 +      png_crc_finish(png_ptr, length);
  1.1900 +      png_chunk_benign_error(png_ptr, "invalid");
  1.1901 +      return;
  1.1902 +   }
  1.1903 +
  1.1904 +   png_crc_read(png_ptr, buf, truelen);
  1.1905 +
  1.1906 +   if (png_crc_finish(png_ptr, 0))
  1.1907 +      return;
  1.1908 +
  1.1909 +   /* We convert the index value into RGB components so that we can allow
  1.1910 +    * arbitrary RGB values for background when we have transparency, and
  1.1911 +    * so it is easy to determine the RGB values of the background color
  1.1912 +    * from the info_ptr struct.
  1.1913 +    */
  1.1914 +   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1.1915 +   {
  1.1916 +      background.index = buf[0];
  1.1917 +
  1.1918 +      if (info_ptr && info_ptr->num_palette)
  1.1919 +      {
  1.1920 +         if (buf[0] >= info_ptr->num_palette)
  1.1921 +         {
  1.1922 +            png_chunk_benign_error(png_ptr, "invalid index");
  1.1923 +            return;
  1.1924 +         }
  1.1925 +
  1.1926 +         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
  1.1927 +         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
  1.1928 +         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
  1.1929 +      }
  1.1930 +
  1.1931 +      else
  1.1932 +         background.red = background.green = background.blue = 0;
  1.1933 +
  1.1934 +      background.gray = 0;
  1.1935 +   }
  1.1936 +
  1.1937 +   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
  1.1938 +   {
  1.1939 +      background.index = 0;
  1.1940 +      background.red =
  1.1941 +      background.green =
  1.1942 +      background.blue =
  1.1943 +      background.gray = png_get_uint_16(buf);
  1.1944 +   }
  1.1945 +
  1.1946 +   else
  1.1947 +   {
  1.1948 +      background.index = 0;
  1.1949 +      background.red = png_get_uint_16(buf);
  1.1950 +      background.green = png_get_uint_16(buf + 2);
  1.1951 +      background.blue = png_get_uint_16(buf + 4);
  1.1952 +      background.gray = 0;
  1.1953 +   }
  1.1954 +
  1.1955 +   png_set_bKGD(png_ptr, info_ptr, &background);
  1.1956 +}
  1.1957 +#endif
  1.1958 +
  1.1959 +#ifdef PNG_READ_hIST_SUPPORTED
  1.1960 +void /* PRIVATE */
  1.1961 +png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.1962 +{
  1.1963 +   unsigned int num, i;
  1.1964 +   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
  1.1965 +
  1.1966 +   png_debug(1, "in png_handle_hIST");
  1.1967 +
  1.1968 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.1969 +      png_chunk_error(png_ptr, "missing IHDR");
  1.1970 +
  1.1971 +   else if ((png_ptr->mode & PNG_HAVE_IDAT) || !(png_ptr->mode & PNG_HAVE_PLTE))
  1.1972 +   {
  1.1973 +      png_crc_finish(png_ptr, length);
  1.1974 +      png_chunk_benign_error(png_ptr, "out of place");
  1.1975 +      return;
  1.1976 +   }
  1.1977 +
  1.1978 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
  1.1979 +   {
  1.1980 +      png_crc_finish(png_ptr, length);
  1.1981 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.1982 +      return;
  1.1983 +   }
  1.1984 +
  1.1985 +   num = length / 2 ;
  1.1986 +
  1.1987 +   if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH)
  1.1988 +   {
  1.1989 +      png_crc_finish(png_ptr, length);
  1.1990 +      png_chunk_benign_error(png_ptr, "invalid");
  1.1991 +      return;
  1.1992 +   }
  1.1993 +
  1.1994 +   for (i = 0; i < num; i++)
  1.1995 +   {
  1.1996 +      png_byte buf[2];
  1.1997 +
  1.1998 +      png_crc_read(png_ptr, buf, 2);
  1.1999 +      readbuf[i] = png_get_uint_16(buf);
  1.2000 +   }
  1.2001 +
  1.2002 +   if (png_crc_finish(png_ptr, 0))
  1.2003 +      return;
  1.2004 +
  1.2005 +   png_set_hIST(png_ptr, info_ptr, readbuf);
  1.2006 +}
  1.2007 +#endif
  1.2008 +
  1.2009 +#ifdef PNG_READ_pHYs_SUPPORTED
  1.2010 +void /* PRIVATE */
  1.2011 +png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2012 +{
  1.2013 +   png_byte buf[9];
  1.2014 +   png_uint_32 res_x, res_y;
  1.2015 +   int unit_type;
  1.2016 +
  1.2017 +   png_debug(1, "in png_handle_pHYs");
  1.2018 +
  1.2019 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2020 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2021 +
  1.2022 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2023 +   {
  1.2024 +      png_crc_finish(png_ptr, length);
  1.2025 +      png_chunk_benign_error(png_ptr, "out of place");
  1.2026 +      return;
  1.2027 +   }
  1.2028 +
  1.2029 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  1.2030 +   {
  1.2031 +      png_crc_finish(png_ptr, length);
  1.2032 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.2033 +      return;
  1.2034 +   }
  1.2035 +
  1.2036 +   if (length != 9)
  1.2037 +   {
  1.2038 +      png_crc_finish(png_ptr, length);
  1.2039 +      png_chunk_benign_error(png_ptr, "invalid");
  1.2040 +      return;
  1.2041 +   }
  1.2042 +
  1.2043 +   png_crc_read(png_ptr, buf, 9);
  1.2044 +
  1.2045 +   if (png_crc_finish(png_ptr, 0))
  1.2046 +      return;
  1.2047 +
  1.2048 +   res_x = png_get_uint_32(buf);
  1.2049 +   res_y = png_get_uint_32(buf + 4);
  1.2050 +   unit_type = buf[8];
  1.2051 +   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
  1.2052 +}
  1.2053 +#endif
  1.2054 +
  1.2055 +#ifdef PNG_READ_oFFs_SUPPORTED
  1.2056 +void /* PRIVATE */
  1.2057 +png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2058 +{
  1.2059 +   png_byte buf[9];
  1.2060 +   png_int_32 offset_x, offset_y;
  1.2061 +   int unit_type;
  1.2062 +
  1.2063 +   png_debug(1, "in png_handle_oFFs");
  1.2064 +
  1.2065 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2066 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2067 +
  1.2068 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2069 +   {
  1.2070 +      png_crc_finish(png_ptr, length);
  1.2071 +      png_chunk_benign_error(png_ptr, "out of place");
  1.2072 +      return;
  1.2073 +   }
  1.2074 +
  1.2075 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  1.2076 +   {
  1.2077 +      png_crc_finish(png_ptr, length);
  1.2078 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.2079 +      return;
  1.2080 +   }
  1.2081 +
  1.2082 +   if (length != 9)
  1.2083 +   {
  1.2084 +      png_crc_finish(png_ptr, length);
  1.2085 +      png_chunk_benign_error(png_ptr, "invalid");
  1.2086 +      return;
  1.2087 +   }
  1.2088 +
  1.2089 +   png_crc_read(png_ptr, buf, 9);
  1.2090 +
  1.2091 +   if (png_crc_finish(png_ptr, 0))
  1.2092 +      return;
  1.2093 +
  1.2094 +   offset_x = png_get_int_32(buf);
  1.2095 +   offset_y = png_get_int_32(buf + 4);
  1.2096 +   unit_type = buf[8];
  1.2097 +   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
  1.2098 +}
  1.2099 +#endif
  1.2100 +
  1.2101 +#ifdef PNG_READ_pCAL_SUPPORTED
  1.2102 +/* Read the pCAL chunk (described in the PNG Extensions document) */
  1.2103 +void /* PRIVATE */
  1.2104 +png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2105 +{
  1.2106 +   png_int_32 X0, X1;
  1.2107 +   png_byte type, nparams;
  1.2108 +   png_bytep buffer, buf, units, endptr;
  1.2109 +   png_charpp params;
  1.2110 +   int i;
  1.2111 +
  1.2112 +   png_debug(1, "in png_handle_pCAL");
  1.2113 +
  1.2114 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2115 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2116 +
  1.2117 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2118 +   {
  1.2119 +      png_crc_finish(png_ptr, length);
  1.2120 +      png_chunk_benign_error(png_ptr, "out of place");
  1.2121 +      return;
  1.2122 +   }
  1.2123 +
  1.2124 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
  1.2125 +   {
  1.2126 +      png_crc_finish(png_ptr, length);
  1.2127 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.2128 +      return;
  1.2129 +   }
  1.2130 +
  1.2131 +   png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
  1.2132 +       length + 1);
  1.2133 +
  1.2134 +   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
  1.2135 +
  1.2136 +   if (buffer == NULL)
  1.2137 +   {
  1.2138 +      png_crc_finish(png_ptr, length);
  1.2139 +      png_chunk_benign_error(png_ptr, "out of memory");
  1.2140 +      return;
  1.2141 +   }
  1.2142 +
  1.2143 +   png_crc_read(png_ptr, buffer, length);
  1.2144 +
  1.2145 +   if (png_crc_finish(png_ptr, 0))
  1.2146 +      return;
  1.2147 +
  1.2148 +   buffer[length] = 0; /* Null terminate the last string */
  1.2149 +
  1.2150 +   png_debug(3, "Finding end of pCAL purpose string");
  1.2151 +   for (buf = buffer; *buf; buf++)
  1.2152 +      /* Empty loop */ ;
  1.2153 +
  1.2154 +   endptr = buffer + length;
  1.2155 +
  1.2156 +   /* We need to have at least 12 bytes after the purpose string
  1.2157 +    * in order to get the parameter information.
  1.2158 +    */
  1.2159 +   if (endptr <= buf + 12)
  1.2160 +   {
  1.2161 +      png_chunk_benign_error(png_ptr, "invalid");
  1.2162 +      return;
  1.2163 +   }
  1.2164 +
  1.2165 +   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
  1.2166 +   X0 = png_get_int_32((png_bytep)buf+1);
  1.2167 +   X1 = png_get_int_32((png_bytep)buf+5);
  1.2168 +   type = buf[9];
  1.2169 +   nparams = buf[10];
  1.2170 +   units = buf + 11;
  1.2171 +
  1.2172 +   png_debug(3, "Checking pCAL equation type and number of parameters");
  1.2173 +   /* Check that we have the right number of parameters for known
  1.2174 +    * equation types.
  1.2175 +    */
  1.2176 +   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
  1.2177 +       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
  1.2178 +       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
  1.2179 +       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
  1.2180 +   {
  1.2181 +      png_chunk_benign_error(png_ptr, "invalid parameter count");
  1.2182 +      return;
  1.2183 +   }
  1.2184 +
  1.2185 +   else if (type >= PNG_EQUATION_LAST)
  1.2186 +   {
  1.2187 +      png_chunk_benign_error(png_ptr, "unrecognized equation type");
  1.2188 +   }
  1.2189 +
  1.2190 +   for (buf = units; *buf; buf++)
  1.2191 +      /* Empty loop to move past the units string. */ ;
  1.2192 +
  1.2193 +   png_debug(3, "Allocating pCAL parameters array");
  1.2194 +
  1.2195 +   params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
  1.2196 +       nparams * (sizeof (png_charp))));
  1.2197 +
  1.2198 +   if (params == NULL)
  1.2199 +   {
  1.2200 +      png_chunk_benign_error(png_ptr, "out of memory");
  1.2201 +      return;
  1.2202 +   }
  1.2203 +
  1.2204 +   /* Get pointers to the start of each parameter string. */
  1.2205 +   for (i = 0; i < nparams; i++)
  1.2206 +   {
  1.2207 +      buf++; /* Skip the null string terminator from previous parameter. */
  1.2208 +
  1.2209 +      png_debug1(3, "Reading pCAL parameter %d", i);
  1.2210 +
  1.2211 +      for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++)
  1.2212 +         /* Empty loop to move past each parameter string */ ;
  1.2213 +
  1.2214 +      /* Make sure we haven't run out of data yet */
  1.2215 +      if (buf > endptr)
  1.2216 +      {
  1.2217 +         png_free(png_ptr, params);
  1.2218 +         png_chunk_benign_error(png_ptr, "invalid data");
  1.2219 +         return;
  1.2220 +      }
  1.2221 +   }
  1.2222 +
  1.2223 +   png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
  1.2224 +      (png_charp)units, params);
  1.2225 +
  1.2226 +   png_free(png_ptr, params);
  1.2227 +}
  1.2228 +#endif
  1.2229 +
  1.2230 +#ifdef PNG_READ_sCAL_SUPPORTED
  1.2231 +/* Read the sCAL chunk */
  1.2232 +void /* PRIVATE */
  1.2233 +png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2234 +{
  1.2235 +   png_bytep buffer;
  1.2236 +   png_size_t i;
  1.2237 +   int state;
  1.2238 +
  1.2239 +   png_debug(1, "in png_handle_sCAL");
  1.2240 +
  1.2241 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2242 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2243 +
  1.2244 +   else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2245 +   {
  1.2246 +      png_crc_finish(png_ptr, length);
  1.2247 +      png_chunk_benign_error(png_ptr, "out of place");
  1.2248 +      return;
  1.2249 +   }
  1.2250 +
  1.2251 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
  1.2252 +   {
  1.2253 +      png_crc_finish(png_ptr, length);
  1.2254 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.2255 +      return;
  1.2256 +   }
  1.2257 +
  1.2258 +   /* Need unit type, width, \0, height: minimum 4 bytes */
  1.2259 +   else if (length < 4)
  1.2260 +   {
  1.2261 +      png_crc_finish(png_ptr, length);
  1.2262 +      png_chunk_benign_error(png_ptr, "invalid");
  1.2263 +      return;
  1.2264 +   }
  1.2265 +
  1.2266 +   png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
  1.2267 +      length + 1);
  1.2268 +
  1.2269 +   buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
  1.2270 +
  1.2271 +   if (buffer == NULL)
  1.2272 +   {
  1.2273 +      png_chunk_benign_error(png_ptr, "out of memory");
  1.2274 +      png_crc_finish(png_ptr, length);
  1.2275 +      return;
  1.2276 +   }
  1.2277 +
  1.2278 +   png_crc_read(png_ptr, buffer, length);
  1.2279 +   buffer[length] = 0; /* Null terminate the last string */
  1.2280 +
  1.2281 +   if (png_crc_finish(png_ptr, 0))
  1.2282 +      return;
  1.2283 +
  1.2284 +   /* Validate the unit. */
  1.2285 +   if (buffer[0] != 1 && buffer[0] != 2)
  1.2286 +   {
  1.2287 +      png_chunk_benign_error(png_ptr, "invalid unit");
  1.2288 +      return;
  1.2289 +   }
  1.2290 +
  1.2291 +   /* Validate the ASCII numbers, need two ASCII numbers separated by
  1.2292 +    * a '\0' and they need to fit exactly in the chunk data.
  1.2293 +    */
  1.2294 +   i = 1;
  1.2295 +   state = 0;
  1.2296 +
  1.2297 +   if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) ||
  1.2298 +       i >= length || buffer[i++] != 0)
  1.2299 +      png_chunk_benign_error(png_ptr, "bad width format");
  1.2300 +
  1.2301 +   else if (!PNG_FP_IS_POSITIVE(state))
  1.2302 +      png_chunk_benign_error(png_ptr, "non-positive width");
  1.2303 +
  1.2304 +   else
  1.2305 +   {
  1.2306 +      png_size_t heighti = i;
  1.2307 +
  1.2308 +      state = 0;
  1.2309 +      if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) ||
  1.2310 +         i != length)
  1.2311 +         png_chunk_benign_error(png_ptr, "bad height format");
  1.2312 +
  1.2313 +      else if (!PNG_FP_IS_POSITIVE(state))
  1.2314 +         png_chunk_benign_error(png_ptr, "non-positive height");
  1.2315 +
  1.2316 +      else
  1.2317 +         /* This is the (only) success case. */
  1.2318 +         png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
  1.2319 +            (png_charp)buffer+1, (png_charp)buffer+heighti);
  1.2320 +   }
  1.2321 +}
  1.2322 +#endif
  1.2323 +
  1.2324 +#ifdef PNG_READ_tIME_SUPPORTED
  1.2325 +void /* PRIVATE */
  1.2326 +png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2327 +{
  1.2328 +   png_byte buf[7];
  1.2329 +   png_time mod_time;
  1.2330 +
  1.2331 +   png_debug(1, "in png_handle_tIME");
  1.2332 +
  1.2333 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2334 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2335 +
  1.2336 +   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
  1.2337 +   {
  1.2338 +      png_crc_finish(png_ptr, length);
  1.2339 +      png_chunk_benign_error(png_ptr, "duplicate");
  1.2340 +      return;
  1.2341 +   }
  1.2342 +
  1.2343 +   if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2344 +      png_ptr->mode |= PNG_AFTER_IDAT;
  1.2345 +
  1.2346 +   if (length != 7)
  1.2347 +   {
  1.2348 +      png_crc_finish(png_ptr, length);
  1.2349 +      png_chunk_benign_error(png_ptr, "invalid");
  1.2350 +      return;
  1.2351 +   }
  1.2352 +
  1.2353 +   png_crc_read(png_ptr, buf, 7);
  1.2354 +
  1.2355 +   if (png_crc_finish(png_ptr, 0))
  1.2356 +      return;
  1.2357 +
  1.2358 +   mod_time.second = buf[6];
  1.2359 +   mod_time.minute = buf[5];
  1.2360 +   mod_time.hour = buf[4];
  1.2361 +   mod_time.day = buf[3];
  1.2362 +   mod_time.month = buf[2];
  1.2363 +   mod_time.year = png_get_uint_16(buf);
  1.2364 +
  1.2365 +   png_set_tIME(png_ptr, info_ptr, &mod_time);
  1.2366 +}
  1.2367 +#endif
  1.2368 +
  1.2369 +#ifdef PNG_READ_tEXt_SUPPORTED
  1.2370 +/* Note: this does not properly handle chunks that are > 64K under DOS */
  1.2371 +void /* PRIVATE */
  1.2372 +png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2373 +{
  1.2374 +   png_text  text_info;
  1.2375 +   png_bytep buffer;
  1.2376 +   png_charp key;
  1.2377 +   png_charp text;
  1.2378 +   png_uint_32 skip = 0;
  1.2379 +
  1.2380 +   png_debug(1, "in png_handle_tEXt");
  1.2381 +
  1.2382 +#ifdef PNG_USER_LIMITS_SUPPORTED
  1.2383 +   if (png_ptr->user_chunk_cache_max != 0)
  1.2384 +   {
  1.2385 +      if (png_ptr->user_chunk_cache_max == 1)
  1.2386 +      {
  1.2387 +         png_crc_finish(png_ptr, length);
  1.2388 +         return;
  1.2389 +      }
  1.2390 +
  1.2391 +      if (--png_ptr->user_chunk_cache_max == 1)
  1.2392 +      {
  1.2393 +         png_crc_finish(png_ptr, length);
  1.2394 +         png_chunk_benign_error(png_ptr, "no space in chunk cache");
  1.2395 +         return;
  1.2396 +      }
  1.2397 +   }
  1.2398 +#endif
  1.2399 +
  1.2400 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2401 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2402 +
  1.2403 +   if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2404 +      png_ptr->mode |= PNG_AFTER_IDAT;
  1.2405 +
  1.2406 +#ifdef PNG_MAX_MALLOC_64K
  1.2407 +   if (length > 65535U)
  1.2408 +   {
  1.2409 +      png_crc_finish(png_ptr, length);
  1.2410 +      png_chunk_benign_error(png_ptr, "too large to fit in memory");
  1.2411 +      return;
  1.2412 +   }
  1.2413 +#endif
  1.2414 +
  1.2415 +   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
  1.2416 +
  1.2417 +   if (buffer == NULL)
  1.2418 +   {
  1.2419 +     png_chunk_benign_error(png_ptr, "out of memory");
  1.2420 +     return;
  1.2421 +   }
  1.2422 +
  1.2423 +   png_crc_read(png_ptr, buffer, length);
  1.2424 +
  1.2425 +   if (png_crc_finish(png_ptr, skip))
  1.2426 +      return;
  1.2427 +
  1.2428 +   key = (png_charp)buffer;
  1.2429 +   key[length] = 0;
  1.2430 +
  1.2431 +   for (text = key; *text; text++)
  1.2432 +      /* Empty loop to find end of key */ ;
  1.2433 +
  1.2434 +   if (text != key + length)
  1.2435 +      text++;
  1.2436 +
  1.2437 +   text_info.compression = PNG_TEXT_COMPRESSION_NONE;
  1.2438 +   text_info.key = key;
  1.2439 +   text_info.lang = NULL;
  1.2440 +   text_info.lang_key = NULL;
  1.2441 +   text_info.itxt_length = 0;
  1.2442 +   text_info.text = text;
  1.2443 +   text_info.text_length = strlen(text);
  1.2444 +
  1.2445 +   if (png_set_text_2(png_ptr, info_ptr, &text_info, 1))
  1.2446 +      png_warning(png_ptr, "Insufficient memory to process text chunk");
  1.2447 +}
  1.2448 +#endif
  1.2449 +
  1.2450 +#ifdef PNG_READ_zTXt_SUPPORTED
  1.2451 +/* Note: this does not correctly handle chunks that are > 64K under DOS */
  1.2452 +void /* PRIVATE */
  1.2453 +png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2454 +{
  1.2455 +   png_const_charp errmsg = NULL;
  1.2456 +   png_bytep       buffer;
  1.2457 +   png_uint_32     keyword_length;
  1.2458 +
  1.2459 +   png_debug(1, "in png_handle_zTXt");
  1.2460 +
  1.2461 +#ifdef PNG_USER_LIMITS_SUPPORTED
  1.2462 +   if (png_ptr->user_chunk_cache_max != 0)
  1.2463 +   {
  1.2464 +      if (png_ptr->user_chunk_cache_max == 1)
  1.2465 +      {
  1.2466 +         png_crc_finish(png_ptr, length);
  1.2467 +         return;
  1.2468 +      }
  1.2469 +
  1.2470 +      if (--png_ptr->user_chunk_cache_max == 1)
  1.2471 +      {
  1.2472 +         png_crc_finish(png_ptr, length);
  1.2473 +         png_chunk_benign_error(png_ptr, "no space in chunk cache");
  1.2474 +         return;
  1.2475 +      }
  1.2476 +   }
  1.2477 +#endif
  1.2478 +
  1.2479 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2480 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2481 +
  1.2482 +   if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2483 +      png_ptr->mode |= PNG_AFTER_IDAT;
  1.2484 +
  1.2485 +   buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
  1.2486 +
  1.2487 +   if (buffer == NULL)
  1.2488 +   {
  1.2489 +      png_crc_finish(png_ptr, length);
  1.2490 +      png_chunk_benign_error(png_ptr, "out of memory");
  1.2491 +      return;
  1.2492 +   }
  1.2493 +
  1.2494 +   png_crc_read(png_ptr, buffer, length);
  1.2495 +
  1.2496 +   if (png_crc_finish(png_ptr, 0))
  1.2497 +      return;
  1.2498 +
  1.2499 +   /* TODO: also check that the keyword contents match the spec! */
  1.2500 +   for (keyword_length = 0;
  1.2501 +      keyword_length < length && buffer[keyword_length] != 0;
  1.2502 +      ++keyword_length)
  1.2503 +      /* Empty loop to find end of name */ ;
  1.2504 +
  1.2505 +   if (keyword_length > 79 || keyword_length < 1)
  1.2506 +      errmsg = "bad keyword";
  1.2507 +
  1.2508 +   /* zTXt must have some LZ data after the keyword, although it may expand to
  1.2509 +    * zero bytes; we need a '\0' at the end of the keyword, the compression type
  1.2510 +    * then the LZ data:
  1.2511 +    */
  1.2512 +   else if (keyword_length + 3 > length)
  1.2513 +      errmsg = "truncated";
  1.2514 +
  1.2515 +   else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE)
  1.2516 +      errmsg = "unknown compression type";
  1.2517 +
  1.2518 +   else
  1.2519 +   {
  1.2520 +      png_alloc_size_t uncompressed_length = PNG_SIZE_MAX;
  1.2521 +
  1.2522 +      /* TODO: at present png_decompress_chunk imposes a single application
  1.2523 +       * level memory limit, this should be split to different values for iCCP
  1.2524 +       * and text chunks.
  1.2525 +       */
  1.2526 +      if (png_decompress_chunk(png_ptr, length, keyword_length+2,
  1.2527 +         &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
  1.2528 +      {
  1.2529 +         png_text text;
  1.2530 +
  1.2531 +         /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except
  1.2532 +          * for the extra compression type byte and the fact that it isn't
  1.2533 +          * necessarily '\0' terminated.
  1.2534 +          */
  1.2535 +         buffer = png_ptr->read_buffer;
  1.2536 +         buffer[uncompressed_length+(keyword_length+2)] = 0;
  1.2537 +
  1.2538 +         text.compression = PNG_TEXT_COMPRESSION_zTXt;
  1.2539 +         text.key = (png_charp)buffer;
  1.2540 +         text.text = (png_charp)(buffer + keyword_length+2);
  1.2541 +         text.text_length = uncompressed_length;
  1.2542 +         text.itxt_length = 0;
  1.2543 +         text.lang = NULL;
  1.2544 +         text.lang_key = NULL;
  1.2545 +
  1.2546 +         if (png_set_text_2(png_ptr, info_ptr, &text, 1))
  1.2547 +            errmsg = "insufficient memory";
  1.2548 +      }
  1.2549 +
  1.2550 +      else
  1.2551 +         errmsg = png_ptr->zstream.msg;
  1.2552 +   }
  1.2553 +
  1.2554 +   if (errmsg != NULL)
  1.2555 +      png_chunk_benign_error(png_ptr, errmsg);
  1.2556 +}
  1.2557 +#endif
  1.2558 +
  1.2559 +#ifdef PNG_READ_iTXt_SUPPORTED
  1.2560 +/* Note: this does not correctly handle chunks that are > 64K under DOS */
  1.2561 +void /* PRIVATE */
  1.2562 +png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
  1.2563 +{
  1.2564 +   png_const_charp errmsg = NULL;
  1.2565 +   png_bytep buffer;
  1.2566 +   png_uint_32 prefix_length;
  1.2567 +
  1.2568 +   png_debug(1, "in png_handle_iTXt");
  1.2569 +
  1.2570 +#ifdef PNG_USER_LIMITS_SUPPORTED
  1.2571 +   if (png_ptr->user_chunk_cache_max != 0)
  1.2572 +   {
  1.2573 +      if (png_ptr->user_chunk_cache_max == 1)
  1.2574 +      {
  1.2575 +         png_crc_finish(png_ptr, length);
  1.2576 +         return;
  1.2577 +      }
  1.2578 +
  1.2579 +      if (--png_ptr->user_chunk_cache_max == 1)
  1.2580 +      {
  1.2581 +         png_crc_finish(png_ptr, length);
  1.2582 +         png_chunk_benign_error(png_ptr, "no space in chunk cache");
  1.2583 +         return;
  1.2584 +      }
  1.2585 +   }
  1.2586 +#endif
  1.2587 +
  1.2588 +   if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2589 +      png_chunk_error(png_ptr, "missing IHDR");
  1.2590 +
  1.2591 +   if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2592 +      png_ptr->mode |= PNG_AFTER_IDAT;
  1.2593 +
  1.2594 +   buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
  1.2595 +
  1.2596 +   if (buffer == NULL)
  1.2597 +   {
  1.2598 +      png_crc_finish(png_ptr, length);
  1.2599 +      png_chunk_benign_error(png_ptr, "out of memory");
  1.2600 +      return;
  1.2601 +   }
  1.2602 +
  1.2603 +   png_crc_read(png_ptr, buffer, length);
  1.2604 +
  1.2605 +   if (png_crc_finish(png_ptr, 0))
  1.2606 +      return;
  1.2607 +
  1.2608 +   /* First the keyword. */
  1.2609 +   for (prefix_length=0;
  1.2610 +      prefix_length < length && buffer[prefix_length] != 0;
  1.2611 +      ++prefix_length)
  1.2612 +      /* Empty loop */ ;
  1.2613 +
  1.2614 +   /* Perform a basic check on the keyword length here. */
  1.2615 +   if (prefix_length > 79 || prefix_length < 1)
  1.2616 +      errmsg = "bad keyword";
  1.2617 +
  1.2618 +   /* Expect keyword, compression flag, compression type, language, translated
  1.2619 +    * keyword (both may be empty but are 0 terminated) then the text, which may
  1.2620 +    * be empty.
  1.2621 +    */
  1.2622 +   else if (prefix_length + 5 > length)
  1.2623 +      errmsg = "truncated";
  1.2624 +
  1.2625 +   else if (buffer[prefix_length+1] == 0 ||
  1.2626 +      (buffer[prefix_length+1] == 1 &&
  1.2627 +      buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE))
  1.2628 +   {
  1.2629 +      int compressed = buffer[prefix_length+1] != 0;
  1.2630 +      png_uint_32 language_offset, translated_keyword_offset;
  1.2631 +      png_alloc_size_t uncompressed_length = 0;
  1.2632 +
  1.2633 +      /* Now the language tag */
  1.2634 +      prefix_length += 3;
  1.2635 +      language_offset = prefix_length;
  1.2636 +
  1.2637 +      for (; prefix_length < length && buffer[prefix_length] != 0;
  1.2638 +         ++prefix_length)
  1.2639 +         /* Empty loop */ ;
  1.2640 +
  1.2641 +      /* WARNING: the length may be invalid here, this is checked below. */
  1.2642 +      translated_keyword_offset = ++prefix_length;
  1.2643 +
  1.2644 +      for (; prefix_length < length && buffer[prefix_length] != 0;
  1.2645 +         ++prefix_length)
  1.2646 +         /* Empty loop */ ;
  1.2647 +
  1.2648 +      /* prefix_length should now be at the trailing '\0' of the translated
  1.2649 +       * keyword, but it may already be over the end.  None of this arithmetic
  1.2650 +       * can overflow because chunks are at most 2^31 bytes long, but on 16-bit
  1.2651 +       * systems the available allocaton may overflow.
  1.2652 +       */
  1.2653 +      ++prefix_length;
  1.2654 +
  1.2655 +      if (!compressed && prefix_length <= length)
  1.2656 +         uncompressed_length = length - prefix_length;
  1.2657 +
  1.2658 +      else if (compressed && prefix_length < length)
  1.2659 +      {
  1.2660 +         uncompressed_length = PNG_SIZE_MAX;
  1.2661 +
  1.2662 +         /* TODO: at present png_decompress_chunk imposes a single application
  1.2663 +          * level memory limit, this should be split to different values for
  1.2664 +          * iCCP and text chunks.
  1.2665 +          */
  1.2666 +         if (png_decompress_chunk(png_ptr, length, prefix_length,
  1.2667 +            &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
  1.2668 +            buffer = png_ptr->read_buffer;
  1.2669 +
  1.2670 +         else
  1.2671 +            errmsg = png_ptr->zstream.msg;
  1.2672 +      }
  1.2673 +
  1.2674 +      else
  1.2675 +         errmsg = "truncated";
  1.2676 +
  1.2677 +      if (errmsg == NULL)
  1.2678 +      {
  1.2679 +         png_text text;
  1.2680 +
  1.2681 +         buffer[uncompressed_length+prefix_length] = 0;
  1.2682 +
  1.2683 +         if (compressed)
  1.2684 +            text.compression = PNG_ITXT_COMPRESSION_NONE;
  1.2685 +
  1.2686 +         else
  1.2687 +            text.compression = PNG_ITXT_COMPRESSION_zTXt;
  1.2688 +
  1.2689 +         text.key = (png_charp)buffer;
  1.2690 +         text.lang = (png_charp)buffer + language_offset;
  1.2691 +         text.lang_key = (png_charp)buffer + translated_keyword_offset;
  1.2692 +         text.text = (png_charp)buffer + prefix_length;
  1.2693 +         text.text_length = 0;
  1.2694 +         text.itxt_length = uncompressed_length;
  1.2695 +
  1.2696 +         if (png_set_text_2(png_ptr, info_ptr, &text, 1))
  1.2697 +            errmsg = "insufficient memory";
  1.2698 +      }
  1.2699 +   }
  1.2700 +
  1.2701 +   else
  1.2702 +      errmsg = "bad compression info";
  1.2703 +
  1.2704 +   if (errmsg != NULL)
  1.2705 +      png_chunk_benign_error(png_ptr, errmsg);
  1.2706 +}
  1.2707 +#endif
  1.2708 +
  1.2709 +#ifdef PNG_READ_APNG_SUPPORTED
  1.2710 +void /* PRIVATE */
  1.2711 +png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1.2712 +{
  1.2713 +    png_byte data[8];
  1.2714 +    png_uint_32 num_frames;
  1.2715 +    png_uint_32 num_plays;
  1.2716 +    png_uint_32 didSet;
  1.2717 +
  1.2718 +    png_debug(1, "in png_handle_acTL");
  1.2719 +
  1.2720 +    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2721 +    {
  1.2722 +        png_error(png_ptr, "Missing IHDR before acTL");
  1.2723 +    }
  1.2724 +    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2725 +    {
  1.2726 +        png_warning(png_ptr, "Invalid acTL after IDAT skipped");
  1.2727 +        png_crc_finish(png_ptr, length);
  1.2728 +        return;
  1.2729 +    }
  1.2730 +    else if (png_ptr->mode & PNG_HAVE_acTL)
  1.2731 +    {
  1.2732 +        png_warning(png_ptr, "Duplicate acTL skipped");
  1.2733 +        png_crc_finish(png_ptr, length);
  1.2734 +        return;
  1.2735 +    }
  1.2736 +    else if (length != 8)
  1.2737 +    {
  1.2738 +        png_warning(png_ptr, "acTL with invalid length skipped");
  1.2739 +        png_crc_finish(png_ptr, length);
  1.2740 +        return;
  1.2741 +    }
  1.2742 +
  1.2743 +    png_crc_read(png_ptr, data, 8);
  1.2744 +    png_crc_finish(png_ptr, 0);
  1.2745 +
  1.2746 +    num_frames = png_get_uint_31(png_ptr, data);
  1.2747 +    num_plays = png_get_uint_31(png_ptr, data + 4);
  1.2748 +
  1.2749 +    /* the set function will do error checking on num_frames */
  1.2750 +    didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
  1.2751 +    if(didSet)
  1.2752 +        png_ptr->mode |= PNG_HAVE_acTL;
  1.2753 +}
  1.2754 +
  1.2755 +void /* PRIVATE */
  1.2756 +png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1.2757 +{
  1.2758 +    png_byte data[22];
  1.2759 +    png_uint_32 width;
  1.2760 +    png_uint_32 height;
  1.2761 +    png_uint_32 x_offset;
  1.2762 +    png_uint_32 y_offset;
  1.2763 +    png_uint_16 delay_num;
  1.2764 +    png_uint_16 delay_den;
  1.2765 +    png_byte dispose_op;
  1.2766 +    png_byte blend_op;
  1.2767 +
  1.2768 +    png_debug(1, "in png_handle_fcTL");
  1.2769 +
  1.2770 +    png_ensure_sequence_number(png_ptr, length);
  1.2771 +
  1.2772 +    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1.2773 +    {
  1.2774 +        png_error(png_ptr, "Missing IHDR before fcTL");
  1.2775 +    }
  1.2776 +    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1.2777 +    {
  1.2778 +        /* for any frames other then the first this message may be misleading,
  1.2779 +        * but correct. PNG_HAVE_IDAT is unset before the frame head is read
  1.2780 +        * i can't think of a better message */
  1.2781 +        png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
  1.2782 +        png_crc_finish(png_ptr, length-4);
  1.2783 +        return;
  1.2784 +    }
  1.2785 +    else if (png_ptr->mode & PNG_HAVE_fcTL)
  1.2786 +    {
  1.2787 +        png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
  1.2788 +        png_crc_finish(png_ptr, length-4);
  1.2789 +        return;
  1.2790 +    }
  1.2791 +    else if (length != 26)
  1.2792 +    {
  1.2793 +        png_warning(png_ptr, "fcTL with invalid length skipped");
  1.2794 +        png_crc_finish(png_ptr, length-4);
  1.2795 +        return;
  1.2796 +    }
  1.2797 +
  1.2798 +    png_crc_read(png_ptr, data, 22);
  1.2799 +    png_crc_finish(png_ptr, 0);
  1.2800 +
  1.2801 +    width = png_get_uint_31(png_ptr, data);
  1.2802 +    height = png_get_uint_31(png_ptr, data + 4);
  1.2803 +    x_offset = png_get_uint_31(png_ptr, data + 8);
  1.2804 +    y_offset = png_get_uint_31(png_ptr, data + 12);
  1.2805 +    delay_num = png_get_uint_16(data + 16);
  1.2806 +    delay_den = png_get_uint_16(data + 18);
  1.2807 +    dispose_op = data[20];
  1.2808 +    blend_op = data[21];
  1.2809 +
  1.2810 +    if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
  1.2811 +    {
  1.2812 +        png_warning(png_ptr, "fcTL for the first frame must have zero offset");
  1.2813 +        return;
  1.2814 +    }
  1.2815 +
  1.2816 +    if (info_ptr != NULL)
  1.2817 +    {
  1.2818 +        if (png_ptr->num_frames_read == 0 &&
  1.2819 +            (width != info_ptr->width || height != info_ptr->height))
  1.2820 +        {
  1.2821 +            png_warning(png_ptr, "size in first frame's fcTL must match "
  1.2822 +                               "the size in IHDR");
  1.2823 +            return;
  1.2824 +        }
  1.2825 +
  1.2826 +        /* The set function will do more error checking */
  1.2827 +        png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
  1.2828 +                                x_offset, y_offset, delay_num, delay_den,
  1.2829 +                                dispose_op, blend_op);
  1.2830 +
  1.2831 +        png_read_reinit(png_ptr, info_ptr);
  1.2832 +
  1.2833 +        png_ptr->mode |= PNG_HAVE_fcTL;
  1.2834 +    }
  1.2835 +}
  1.2836 +
  1.2837 +void /* PRIVATE */
  1.2838 +png_have_info(png_structp png_ptr, png_infop info_ptr)
  1.2839 +{
  1.2840 +    if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
  1.2841 +    {
  1.2842 +        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
  1.2843 +        info_ptr->num_frames++;
  1.2844 +    }
  1.2845 +}
  1.2846 +
  1.2847 +void /* PRIVATE */
  1.2848 +png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1.2849 +{
  1.2850 +    png_ensure_sequence_number(png_ptr, length);
  1.2851 +
  1.2852 +    /* This function is only called from png_read_end(), png_read_info(),
  1.2853 +    * and png_push_read_chunk() which means that:
  1.2854 +    * - the user doesn't want to read this frame
  1.2855 +    * - or this is an out-of-place fdAT
  1.2856 +    * in either case it is safe to ignore the chunk with a warning */
  1.2857 +    png_warning(png_ptr, "ignoring fdAT chunk");
  1.2858 +    png_crc_finish(png_ptr, length - 4);
  1.2859 +    PNG_UNUSED(info_ptr)
  1.2860 +}
  1.2861 +
  1.2862 +void /* PRIVATE */
  1.2863 +png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
  1.2864 +{
  1.2865 +    png_byte data[4];
  1.2866 +    png_uint_32 sequence_number;
  1.2867 +
  1.2868 +    if (length < 4)
  1.2869 +        png_error(png_ptr, "invalid fcTL or fdAT chunk found");
  1.2870 +
  1.2871 +    png_crc_read(png_ptr, data, 4);
  1.2872 +    sequence_number = png_get_uint_31(png_ptr, data);
  1.2873 +
  1.2874 +    if (sequence_number != png_ptr->next_seq_num)
  1.2875 +        png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
  1.2876 +                           "number found");
  1.2877 +
  1.2878 +    png_ptr->next_seq_num++;
  1.2879 +}
  1.2880 +#endif /* PNG_READ_APNG_SUPPORTED */
  1.2881 +
  1.2882 +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  1.2883 +/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
  1.2884 +static int
  1.2885 +png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
  1.2886 +{
  1.2887 +   png_alloc_size_t limit = PNG_SIZE_MAX;
  1.2888 +
  1.2889 +   if (png_ptr->unknown_chunk.data != NULL)
  1.2890 +   {
  1.2891 +      png_free(png_ptr, png_ptr->unknown_chunk.data);
  1.2892 +      png_ptr->unknown_chunk.data = NULL;
  1.2893 +   }
  1.2894 +
  1.2895 +#  ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
  1.2896 +      if (png_ptr->user_chunk_malloc_max > 0 &&
  1.2897 +         png_ptr->user_chunk_malloc_max < limit)
  1.2898 +         limit = png_ptr->user_chunk_malloc_max;
  1.2899 +
  1.2900 +#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
  1.2901 +      if (PNG_USER_CHUNK_MALLOC_MAX < limit)
  1.2902 +         limit = PNG_USER_CHUNK_MALLOC_MAX;
  1.2903 +#  endif
  1.2904 +
  1.2905 +   if (length <= limit)
  1.2906 +   {
  1.2907 +      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
  1.2908 +      /* The following is safe because of the PNG_SIZE_MAX init above */
  1.2909 +      png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;
  1.2910 +      /* 'mode' is a flag array, only the bottom four bits matter here */
  1.2911 +      png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
  1.2912 +
  1.2913 +      if (length == 0)
  1.2914 +         png_ptr->unknown_chunk.data = NULL;
  1.2915 +
  1.2916 +      else
  1.2917 +      {
  1.2918 +         /* Do a 'warn' here - it is handled below. */
  1.2919 +         png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
  1.2920 +            png_malloc_warn(png_ptr, length));
  1.2921 +      }
  1.2922 +   }
  1.2923 +
  1.2924 +   if (png_ptr->unknown_chunk.data == NULL && length > 0)
  1.2925 +   {
  1.2926 +      /* This is benign because we clean up correctly */
  1.2927 +      png_crc_finish(png_ptr, length);
  1.2928 +      png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits");
  1.2929 +      return 0;
  1.2930 +   }
  1.2931 +
  1.2932 +   else
  1.2933 +   {
  1.2934 +      if (length > 0)
  1.2935 +         png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
  1.2936 +      png_crc_finish(png_ptr, 0);
  1.2937 +      return 1;
  1.2938 +   }
  1.2939 +}
  1.2940 +#endif /* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
  1.2941 +
  1.2942 +/* Handle an unknown, or known but disabled, chunk */
  1.2943 +void /* PRIVATE */
  1.2944 +png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
  1.2945 +   png_uint_32 length, int keep)
  1.2946 +{
  1.2947 +   int handled = 0; /* the chunk was handled */
  1.2948 +
  1.2949 +   png_debug(1, "in png_handle_unknown");
  1.2950 +
  1.2951 +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  1.2952 +   /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing
  1.2953 +    * the bug which meant that setting a non-default behavior for a specific
  1.2954 +    * chunk would be ignored (the default was always used unless a user
  1.2955 +    * callback was installed).
  1.2956 +    *
  1.2957 +    * 'keep' is the value from the png_chunk_unknown_handling, the setting for
  1.2958 +    * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it
  1.2959 +    * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here.
  1.2960 +    * This is just an optimization to avoid multiple calls to the lookup
  1.2961 +    * function.
  1.2962 +    */
  1.2963 +#  ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  1.2964 +#     ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
  1.2965 +         keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
  1.2966 +#     endif
  1.2967 +#  endif
  1.2968 +
  1.2969 +   /* One of the following methods will read the chunk or skip it (at least one
  1.2970 +    * of these is always defined because this is the only way to switch on
  1.2971 +    * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  1.2972 +    */
  1.2973 +#  ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  1.2974 +      /* The user callback takes precedence over the chunk keep value, but the
  1.2975 +       * keep value is still required to validate a save of a critical chunk.
  1.2976 +       */
  1.2977 +      if (png_ptr->read_user_chunk_fn != NULL)
  1.2978 +      {
  1.2979 +         if (png_cache_unknown_chunk(png_ptr, length))
  1.2980 +         {
  1.2981 +            /* Callback to user unknown chunk handler */
  1.2982 +            int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
  1.2983 +               &png_ptr->unknown_chunk);
  1.2984 +
  1.2985 +            /* ret is:
  1.2986 +             * negative: An error occured, png_chunk_error will be called.
  1.2987 +             *     zero: The chunk was not handled, the chunk will be discarded
  1.2988 +             *           unless png_set_keep_unknown_chunks has been used to set
  1.2989 +             *           a 'keep' behavior for this particular chunk, in which
  1.2990 +             *           case that will be used.  A critical chunk will cause an
  1.2991 +             *           error at this point unless it is to be saved.
  1.2992 +             * positive: The chunk was handled, libpng will ignore/discard it.
  1.2993 +             */
  1.2994 +            if (ret < 0)
  1.2995 +               png_chunk_error(png_ptr, "error in user chunk");
  1.2996 +
  1.2997 +            else if (ret == 0)
  1.2998 +            {
  1.2999 +               /* If the keep value is 'default' or 'never' override it, but
  1.3000 +                * still error out on critical chunks unless the keep value is
  1.3001 +                * 'always'  While this is weird it is the behavior in 1.4.12.
  1.3002 +                * A possible improvement would be to obey the value set for the
  1.3003 +                * chunk, but this would be an API change that would probably
  1.3004 +                * damage some applications.
  1.3005 +                *
  1.3006 +                * The png_app_warning below catches the case that matters, where
  1.3007 +                * the application has not set specific save or ignore for this
  1.3008 +                * chunk or global save or ignore.
  1.3009 +                */
  1.3010 +               if (keep < PNG_HANDLE_CHUNK_IF_SAFE)
  1.3011 +               {
  1.3012 +#                 ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
  1.3013 +                     if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)
  1.3014 +                     {
  1.3015 +                        png_chunk_warning(png_ptr, "Saving unknown chunk:");
  1.3016 +                        png_app_warning(png_ptr,
  1.3017 +                           "forcing save of an unhandled chunk;"
  1.3018 +                           " please call png_set_keep_unknown_chunks");
  1.3019 +                           /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
  1.3020 +                     }
  1.3021 +#                 endif
  1.3022 +                  keep = PNG_HANDLE_CHUNK_IF_SAFE;
  1.3023 +               }
  1.3024 +            }
  1.3025 +
  1.3026 +            else /* chunk was handled */
  1.3027 +            {
  1.3028 +               handled = 1;
  1.3029 +               /* Critical chunks can be safely discarded at this point. */
  1.3030 +               keep = PNG_HANDLE_CHUNK_NEVER;
  1.3031 +            }
  1.3032 +         }
  1.3033 +
  1.3034 +         else
  1.3035 +            keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */
  1.3036 +      }
  1.3037 +
  1.3038 +      else
  1.3039 +         /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */
  1.3040 +#  endif /* PNG_READ_USER_CHUNKS_SUPPORTED */
  1.3041 +
  1.3042 +#  ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
  1.3043 +      {
  1.3044 +         /* keep is currently just the per-chunk setting, if there was no
  1.3045 +          * setting change it to the global default now (not that this may
  1.3046 +          * still be AS_DEFAULT) then obtain the cache of the chunk if required,
  1.3047 +          * if not simply skip the chunk.
  1.3048 +          */
  1.3049 +         if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
  1.3050 +            keep = png_ptr->unknown_default;
  1.3051 +
  1.3052 +         if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
  1.3053 +            (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
  1.3054 +             PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
  1.3055 +         {
  1.3056 +            if (!png_cache_unknown_chunk(png_ptr, length))
  1.3057 +               keep = PNG_HANDLE_CHUNK_NEVER;
  1.3058 +         }
  1.3059 +
  1.3060 +         else
  1.3061 +            png_crc_finish(png_ptr, length);
  1.3062 +      }
  1.3063 +#  else
  1.3064 +#     ifndef PNG_READ_USER_CHUNKS_SUPPORTED
  1.3065 +#        error no method to support READ_UNKNOWN_CHUNKS
  1.3066 +#     endif
  1.3067 +
  1.3068 +      {
  1.3069 +         /* If here there is no read callback pointer set and no support is
  1.3070 +          * compiled in to just save the unknown chunks, so simply skip this
  1.3071 +          * chunk.  If 'keep' is something other than AS_DEFAULT or NEVER then
  1.3072 +          * the app has erroneously asked for unknown chunk saving when there
  1.3073 +          * is no support.
  1.3074 +          */
  1.3075 +         if (keep > PNG_HANDLE_CHUNK_NEVER)
  1.3076 +            png_app_error(png_ptr, "no unknown chunk support available");
  1.3077 +
  1.3078 +         png_crc_finish(png_ptr, length);
  1.3079 +      }
  1.3080 +#  endif
  1.3081 +
  1.3082 +#  ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
  1.3083 +      /* Now store the chunk in the chunk list if appropriate, and if the limits
  1.3084 +       * permit it.
  1.3085 +       */
  1.3086 +      if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
  1.3087 +         (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
  1.3088 +          PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
  1.3089 +      {
  1.3090 +#     ifdef PNG_USER_LIMITS_SUPPORTED
  1.3091 +         switch (png_ptr->user_chunk_cache_max)
  1.3092 +         {
  1.3093 +            case 2:
  1.3094 +               png_ptr->user_chunk_cache_max = 1;
  1.3095 +               png_chunk_benign_error(png_ptr, "no space in chunk cache");
  1.3096 +               /* FALL THROUGH */
  1.3097 +            case 1:
  1.3098 +               /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
  1.3099 +                * chunk being skipped, now there will be a hard error below.
  1.3100 +                */
  1.3101 +               break;
  1.3102 +
  1.3103 +            default: /* not at limit */
  1.3104 +               --(png_ptr->user_chunk_cache_max);
  1.3105 +               /* FALL THROUGH */
  1.3106 +            case 0: /* no limit */
  1.3107 +#     endif /* PNG_USER_LIMITS_SUPPORTED */
  1.3108 +               /* Here when the limit isn't reached or when limits are compiled
  1.3109 +                * out; store the chunk.
  1.3110 +                */
  1.3111 +               png_set_unknown_chunks(png_ptr, info_ptr,
  1.3112 +                  &png_ptr->unknown_chunk, 1);
  1.3113 +               handled = 1;
  1.3114 +#     ifdef PNG_USER_LIMITS_SUPPORTED
  1.3115 +               break;
  1.3116 +         }
  1.3117 +#     endif
  1.3118 +      }
  1.3119 +#  else /* no store support: the chunk must be handled by the user callback */
  1.3120 +      PNG_UNUSED(info_ptr)
  1.3121 +#  endif
  1.3122 +
  1.3123 +   /* Regardless of the error handling below the cached data (if any) can be
  1.3124 +    * freed now.  Notice that the data is not freed if there is a png_error, but
  1.3125 +    * it will be freed by destroy_read_struct.
  1.3126 +    */
  1.3127 +   if (png_ptr->unknown_chunk.data != NULL)
  1.3128 +      png_free(png_ptr, png_ptr->unknown_chunk.data);
  1.3129 +   png_ptr->unknown_chunk.data = NULL;
  1.3130 +
  1.3131 +#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
  1.3132 +   /* There is no support to read an unknown chunk, so just skip it. */
  1.3133 +   png_crc_finish(png_ptr, length);
  1.3134 +   PNG_UNUSED(info_ptr)
  1.3135 +   PNG_UNUSED(keep)
  1.3136 +#endif /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
  1.3137 +
  1.3138 +   /* Check for unhandled critical chunks */
  1.3139 +   if (!handled && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
  1.3140 +      png_chunk_error(png_ptr, "unhandled critical chunk");
  1.3141 +}
  1.3142 +
  1.3143 +/* This function is called to verify that a chunk name is valid.
  1.3144 + * This function can't have the "critical chunk check" incorporated
  1.3145 + * into it, since in the future we will need to be able to call user
  1.3146 + * functions to handle unknown critical chunks after we check that
  1.3147 + * the chunk name itself is valid.
  1.3148 + */
  1.3149 +
  1.3150 +/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
  1.3151 + *
  1.3152 + * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
  1.3153 + */
  1.3154 +
  1.3155 +void /* PRIVATE */
  1.3156 +png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
  1.3157 +{
  1.3158 +   int i;
  1.3159 +
  1.3160 +   png_debug(1, "in png_check_chunk_name");
  1.3161 +
  1.3162 +   for (i=1; i<=4; ++i)
  1.3163 +   {
  1.3164 +      int c = chunk_name & 0xff;
  1.3165 +
  1.3166 +      if (c < 65 || c > 122 || (c > 90 && c < 97))
  1.3167 +         png_chunk_error(png_ptr, "invalid chunk type");
  1.3168 +
  1.3169 +      chunk_name >>= 8;
  1.3170 +   }
  1.3171 +}
  1.3172 +
  1.3173 +/* Combines the row recently read in with the existing pixels in the row.  This
  1.3174 + * routine takes care of alpha and transparency if requested.  This routine also
  1.3175 + * handles the two methods of progressive display of interlaced images,
  1.3176 + * depending on the 'display' value; if 'display' is true then the whole row
  1.3177 + * (dp) is filled from the start by replicating the available pixels.  If
  1.3178 + * 'display' is false only those pixels present in the pass are filled in.
  1.3179 + */
  1.3180 +void /* PRIVATE */
  1.3181 +png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
  1.3182 +{
  1.3183 +   unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
  1.3184 +   png_const_bytep sp = png_ptr->row_buf + 1;
  1.3185 +   png_uint_32 row_width = png_ptr->width;
  1.3186 +   unsigned int pass = png_ptr->pass;
  1.3187 +   png_bytep end_ptr = 0;
  1.3188 +   png_byte end_byte = 0;
  1.3189 +   unsigned int end_mask;
  1.3190 +
  1.3191 +   png_debug(1, "in png_combine_row");
  1.3192 +
  1.3193 +   /* Added in 1.5.6: it should not be possible to enter this routine until at
  1.3194 +    * least one row has been read from the PNG data and transformed.
  1.3195 +    */
  1.3196 +   if (pixel_depth == 0)
  1.3197 +      png_error(png_ptr, "internal row logic error");
  1.3198 +
  1.3199 +   /* Added in 1.5.4: the pixel depth should match the information returned by
  1.3200 +    * any call to png_read_update_info at this point.  Do not continue if we got
  1.3201 +    * this wrong.
  1.3202 +    */
  1.3203 +   if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
  1.3204 +          PNG_ROWBYTES(pixel_depth, row_width))
  1.3205 +      png_error(png_ptr, "internal row size calculation error");
  1.3206 +
  1.3207 +   /* Don't expect this to ever happen: */
  1.3208 +   if (row_width == 0)
  1.3209 +      png_error(png_ptr, "internal row width error");
  1.3210 +
  1.3211 +   /* Preserve the last byte in cases where only part of it will be overwritten,
  1.3212 +    * the multiply below may overflow, we don't care because ANSI-C guarantees
  1.3213 +    * we get the low bits.
  1.3214 +    */
  1.3215 +   end_mask = (pixel_depth * row_width) & 7;
  1.3216 +   if (end_mask != 0)
  1.3217 +   {
  1.3218 +      /* end_ptr == NULL is a flag to say do nothing */
  1.3219 +      end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
  1.3220 +      end_byte = *end_ptr;
  1.3221 +#     ifdef PNG_READ_PACKSWAP_SUPPORTED
  1.3222 +         if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
  1.3223 +            end_mask = 0xff << end_mask;
  1.3224 +
  1.3225 +         else /* big-endian byte */
  1.3226 +#     endif
  1.3227 +         end_mask = 0xff >> end_mask;
  1.3228 +      /* end_mask is now the bits to *keep* from the destination row */
  1.3229 +   }
  1.3230 +
  1.3231 +   /* For non-interlaced images this reduces to a memcpy(). A memcpy()
  1.3232 +    * will also happen if interlacing isn't supported or if the application
  1.3233 +    * does not call png_set_interlace_handling().  In the latter cases the
  1.3234 +    * caller just gets a sequence of the unexpanded rows from each interlace
  1.3235 +    * pass.
  1.3236 +    */
  1.3237 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.3238 +   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
  1.3239 +      pass < 6 && (display == 0 ||
  1.3240 +      /* The following copies everything for 'display' on passes 0, 2 and 4. */
  1.3241 +      (display == 1 && (pass & 1) != 0)))
  1.3242 +   {
  1.3243 +      /* Narrow images may have no bits in a pass; the caller should handle
  1.3244 +       * this, but this test is cheap:
  1.3245 +       */
  1.3246 +      if (row_width <= PNG_PASS_START_COL(pass))
  1.3247 +         return;
  1.3248 +
  1.3249 +      if (pixel_depth < 8)
  1.3250 +      {
  1.3251 +         /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
  1.3252 +          * into 32 bits, then a single loop over the bytes using the four byte
  1.3253 +          * values in the 32-bit mask can be used.  For the 'display' option the
  1.3254 +          * expanded mask may also not require any masking within a byte.  To
  1.3255 +          * make this work the PACKSWAP option must be taken into account - it
  1.3256 +          * simply requires the pixels to be reversed in each byte.
  1.3257 +          *
  1.3258 +          * The 'regular' case requires a mask for each of the first 6 passes,
  1.3259 +          * the 'display' case does a copy for the even passes in the range
  1.3260 +          * 0..6.  This has already been handled in the test above.
  1.3261 +          *
  1.3262 +          * The masks are arranged as four bytes with the first byte to use in
  1.3263 +          * the lowest bits (little-endian) regardless of the order (PACKSWAP or
  1.3264 +          * not) of the pixels in each byte.
  1.3265 +          *
  1.3266 +          * NOTE: the whole of this logic depends on the caller of this function
  1.3267 +          * only calling it on rows appropriate to the pass.  This function only
  1.3268 +          * understands the 'x' logic; the 'y' logic is handled by the caller.
  1.3269 +          *
  1.3270 +          * The following defines allow generation of compile time constant bit
  1.3271 +          * masks for each pixel depth and each possibility of swapped or not
  1.3272 +          * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,
  1.3273 +          * is in the range 0..7; and the result is 1 if the pixel is to be
  1.3274 +          * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'
  1.3275 +          * for the block method.
  1.3276 +          *
  1.3277 +          * With some compilers a compile time expression of the general form:
  1.3278 +          *
  1.3279 +          *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
  1.3280 +          *
  1.3281 +          * Produces warnings with values of 'shift' in the range 33 to 63
  1.3282 +          * because the right hand side of the ?: expression is evaluated by
  1.3283 +          * the compiler even though it isn't used.  Microsoft Visual C (various
  1.3284 +          * versions) and the Intel C compiler are known to do this.  To avoid
  1.3285 +          * this the following macros are used in 1.5.6.  This is a temporary
  1.3286 +          * solution to avoid destabilizing the code during the release process.
  1.3287 +          */
  1.3288 +#        if PNG_USE_COMPILE_TIME_MASKS
  1.3289 +#           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
  1.3290 +#           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
  1.3291 +#        else
  1.3292 +#           define PNG_LSR(x,s) ((x)>>(s))
  1.3293 +#           define PNG_LSL(x,s) ((x)<<(s))
  1.3294 +#        endif
  1.3295 +#        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
  1.3296 +           PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
  1.3297 +#        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
  1.3298 +           PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
  1.3299 +
  1.3300 +         /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is
  1.3301 +          * little endian - the first pixel is at bit 0 - however the extra
  1.3302 +          * parameter 's' can be set to cause the mask position to be swapped
  1.3303 +          * within each byte, to match the PNG format.  This is done by XOR of
  1.3304 +          * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
  1.3305 +          */
  1.3306 +#        define PIXEL_MASK(p,x,d,s) \
  1.3307 +            (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
  1.3308 +
  1.3309 +         /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
  1.3310 +          */
  1.3311 +#        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
  1.3312 +#        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
  1.3313 +
  1.3314 +         /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp
  1.3315 +          * cases the result needs replicating, for the 4-bpp case the above
  1.3316 +          * generates a full 32 bits.
  1.3317 +          */
  1.3318 +#        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
  1.3319 +
  1.3320 +#        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
  1.3321 +            S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
  1.3322 +            S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
  1.3323 +
  1.3324 +#        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
  1.3325 +            B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
  1.3326 +            B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
  1.3327 +
  1.3328 +#if PNG_USE_COMPILE_TIME_MASKS
  1.3329 +         /* Utility macros to construct all the masks for a depth/swap
  1.3330 +          * combination.  The 's' parameter says whether the format is PNG
  1.3331 +          * (big endian bytes) or not.  Only the three odd-numbered passes are
  1.3332 +          * required for the display/block algorithm.
  1.3333 +          */
  1.3334 +#        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
  1.3335 +            S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
  1.3336 +
  1.3337 +#        define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }
  1.3338 +
  1.3339 +#        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
  1.3340 +
  1.3341 +         /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
  1.3342 +          * then pass:
  1.3343 +          */
  1.3344 +         static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
  1.3345 +         {
  1.3346 +            /* Little-endian byte masks for PACKSWAP */
  1.3347 +            { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
  1.3348 +            /* Normal (big-endian byte) masks - PNG format */
  1.3349 +            { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
  1.3350 +         };
  1.3351 +
  1.3352 +         /* display_mask has only three entries for the odd passes, so index by
  1.3353 +          * pass>>1.
  1.3354 +          */
  1.3355 +         static PNG_CONST png_uint_32 display_mask[2][3][3] =
  1.3356 +         {
  1.3357 +            /* Little-endian byte masks for PACKSWAP */
  1.3358 +            { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
  1.3359 +            /* Normal (big-endian byte) masks - PNG format */
  1.3360 +            { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
  1.3361 +         };
  1.3362 +
  1.3363 +#        define MASK(pass,depth,display,png)\
  1.3364 +            ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
  1.3365 +               row_mask[png][DEPTH_INDEX(depth)][pass])
  1.3366 +
  1.3367 +#else /* !PNG_USE_COMPILE_TIME_MASKS */
  1.3368 +         /* This is the runtime alternative: it seems unlikely that this will
  1.3369 +          * ever be either smaller or faster than the compile time approach.
  1.3370 +          */
  1.3371 +#        define MASK(pass,depth,display,png)\
  1.3372 +            ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
  1.3373 +#endif /* !PNG_USE_COMPILE_TIME_MASKS */
  1.3374 +
  1.3375 +         /* Use the appropriate mask to copy the required bits.  In some cases
  1.3376 +          * the byte mask will be 0 or 0xff, optimize these cases.  row_width is
  1.3377 +          * the number of pixels, but the code copies bytes, so it is necessary
  1.3378 +          * to special case the end.
  1.3379 +          */
  1.3380 +         png_uint_32 pixels_per_byte = 8 / pixel_depth;
  1.3381 +         png_uint_32 mask;
  1.3382 +
  1.3383 +#        ifdef PNG_READ_PACKSWAP_SUPPORTED
  1.3384 +            if (png_ptr->transformations & PNG_PACKSWAP)
  1.3385 +               mask = MASK(pass, pixel_depth, display, 0);
  1.3386 +
  1.3387 +            else
  1.3388 +#        endif
  1.3389 +            mask = MASK(pass, pixel_depth, display, 1);
  1.3390 +
  1.3391 +         for (;;)
  1.3392 +         {
  1.3393 +            png_uint_32 m;
  1.3394 +
  1.3395 +            /* It doesn't matter in the following if png_uint_32 has more than
  1.3396 +             * 32 bits because the high bits always match those in m<<24; it is,
  1.3397 +             * however, essential to use OR here, not +, because of this.
  1.3398 +             */
  1.3399 +            m = mask;
  1.3400 +            mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
  1.3401 +            m &= 0xff;
  1.3402 +
  1.3403 +            if (m != 0) /* something to copy */
  1.3404 +            {
  1.3405 +               if (m != 0xff)
  1.3406 +                  *dp = (png_byte)((*dp & ~m) | (*sp & m));
  1.3407 +               else
  1.3408 +                  *dp = *sp;
  1.3409 +            }
  1.3410 +
  1.3411 +            /* NOTE: this may overwrite the last byte with garbage if the image
  1.3412 +             * is not an exact number of bytes wide; libpng has always done
  1.3413 +             * this.
  1.3414 +             */
  1.3415 +            if (row_width <= pixels_per_byte)
  1.3416 +               break; /* May need to restore part of the last byte */
  1.3417 +
  1.3418 +            row_width -= pixels_per_byte;
  1.3419 +            ++dp;
  1.3420 +            ++sp;
  1.3421 +         }
  1.3422 +      }
  1.3423 +
  1.3424 +      else /* pixel_depth >= 8 */
  1.3425 +      {
  1.3426 +         unsigned int bytes_to_copy, bytes_to_jump;
  1.3427 +
  1.3428 +         /* Validate the depth - it must be a multiple of 8 */
  1.3429 +         if (pixel_depth & 7)
  1.3430 +            png_error(png_ptr, "invalid user transform pixel depth");
  1.3431 +
  1.3432 +         pixel_depth >>= 3; /* now in bytes */
  1.3433 +         row_width *= pixel_depth;
  1.3434 +
  1.3435 +         /* Regardless of pass number the Adam 7 interlace always results in a
  1.3436 +          * fixed number of pixels to copy then to skip.  There may be a
  1.3437 +          * different number of pixels to skip at the start though.
  1.3438 +          */
  1.3439 +         {
  1.3440 +            unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
  1.3441 +
  1.3442 +            row_width -= offset;
  1.3443 +            dp += offset;
  1.3444 +            sp += offset;
  1.3445 +         }
  1.3446 +
  1.3447 +         /* Work out the bytes to copy. */
  1.3448 +         if (display)
  1.3449 +         {
  1.3450 +            /* When doing the 'block' algorithm the pixel in the pass gets
  1.3451 +             * replicated to adjacent pixels.  This is why the even (0,2,4,6)
  1.3452 +             * passes are skipped above - the entire expanded row is copied.
  1.3453 +             */
  1.3454 +            bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
  1.3455 +
  1.3456 +            /* But don't allow this number to exceed the actual row width. */
  1.3457 +            if (bytes_to_copy > row_width)
  1.3458 +               bytes_to_copy = row_width;
  1.3459 +         }
  1.3460 +
  1.3461 +         else /* normal row; Adam7 only ever gives us one pixel to copy. */
  1.3462 +            bytes_to_copy = pixel_depth;
  1.3463 +
  1.3464 +         /* In Adam7 there is a constant offset between where the pixels go. */
  1.3465 +         bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
  1.3466 +
  1.3467 +         /* And simply copy these bytes.  Some optimization is possible here,
  1.3468 +          * depending on the value of 'bytes_to_copy'.  Special case the low
  1.3469 +          * byte counts, which we know to be frequent.
  1.3470 +          *
  1.3471 +          * Notice that these cases all 'return' rather than 'break' - this
  1.3472 +          * avoids an unnecessary test on whether to restore the last byte
  1.3473 +          * below.
  1.3474 +          */
  1.3475 +         switch (bytes_to_copy)
  1.3476 +         {
  1.3477 +            case 1:
  1.3478 +               for (;;)
  1.3479 +               {
  1.3480 +                  *dp = *sp;
  1.3481 +
  1.3482 +                  if (row_width <= bytes_to_jump)
  1.3483 +                     return;
  1.3484 +
  1.3485 +                  dp += bytes_to_jump;
  1.3486 +                  sp += bytes_to_jump;
  1.3487 +                  row_width -= bytes_to_jump;
  1.3488 +               }
  1.3489 +
  1.3490 +            case 2:
  1.3491 +               /* There is a possibility of a partial copy at the end here; this
  1.3492 +                * slows the code down somewhat.
  1.3493 +                */
  1.3494 +               do
  1.3495 +               {
  1.3496 +                  dp[0] = sp[0], dp[1] = sp[1];
  1.3497 +
  1.3498 +                  if (row_width <= bytes_to_jump)
  1.3499 +                     return;
  1.3500 +
  1.3501 +                  sp += bytes_to_jump;
  1.3502 +                  dp += bytes_to_jump;
  1.3503 +                  row_width -= bytes_to_jump;
  1.3504 +               }
  1.3505 +               while (row_width > 1);
  1.3506 +
  1.3507 +               /* And there can only be one byte left at this point: */
  1.3508 +               *dp = *sp;
  1.3509 +               return;
  1.3510 +
  1.3511 +            case 3:
  1.3512 +               /* This can only be the RGB case, so each copy is exactly one
  1.3513 +                * pixel and it is not necessary to check for a partial copy.
  1.3514 +                */
  1.3515 +               for(;;)
  1.3516 +               {
  1.3517 +                  dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
  1.3518 +
  1.3519 +                  if (row_width <= bytes_to_jump)
  1.3520 +                     return;
  1.3521 +
  1.3522 +                  sp += bytes_to_jump;
  1.3523 +                  dp += bytes_to_jump;
  1.3524 +                  row_width -= bytes_to_jump;
  1.3525 +               }
  1.3526 +
  1.3527 +            default:
  1.3528 +#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
  1.3529 +               /* Check for double byte alignment and, if possible, use a
  1.3530 +                * 16-bit copy.  Don't attempt this for narrow images - ones that
  1.3531 +                * are less than an interlace panel wide.  Don't attempt it for
  1.3532 +                * wide bytes_to_copy either - use the memcpy there.
  1.3533 +                */
  1.3534 +               if (bytes_to_copy < 16 /*else use memcpy*/ &&
  1.3535 +                  png_isaligned(dp, png_uint_16) &&
  1.3536 +                  png_isaligned(sp, png_uint_16) &&
  1.3537 +                  bytes_to_copy % (sizeof (png_uint_16)) == 0 &&
  1.3538 +                  bytes_to_jump % (sizeof (png_uint_16)) == 0)
  1.3539 +               {
  1.3540 +                  /* Everything is aligned for png_uint_16 copies, but try for
  1.3541 +                   * png_uint_32 first.
  1.3542 +                   */
  1.3543 +                  if (png_isaligned(dp, png_uint_32) &&
  1.3544 +                     png_isaligned(sp, png_uint_32) &&
  1.3545 +                     bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
  1.3546 +                     bytes_to_jump % (sizeof (png_uint_32)) == 0)
  1.3547 +                  {
  1.3548 +                     png_uint_32p dp32 = png_aligncast(png_uint_32p,dp);
  1.3549 +                     png_const_uint_32p sp32 = png_aligncastconst(
  1.3550 +                        png_const_uint_32p, sp);
  1.3551 +                     size_t skip = (bytes_to_jump-bytes_to_copy) /
  1.3552 +                        (sizeof (png_uint_32));
  1.3553 +
  1.3554 +                     do
  1.3555 +                     {
  1.3556 +                        size_t c = bytes_to_copy;
  1.3557 +                        do
  1.3558 +                        {
  1.3559 +                           *dp32++ = *sp32++;
  1.3560 +                           c -= (sizeof (png_uint_32));
  1.3561 +                        }
  1.3562 +                        while (c > 0);
  1.3563 +
  1.3564 +                        if (row_width <= bytes_to_jump)
  1.3565 +                           return;
  1.3566 +
  1.3567 +                        dp32 += skip;
  1.3568 +                        sp32 += skip;
  1.3569 +                        row_width -= bytes_to_jump;
  1.3570 +                     }
  1.3571 +                     while (bytes_to_copy <= row_width);
  1.3572 +
  1.3573 +                     /* Get to here when the row_width truncates the final copy.
  1.3574 +                      * There will be 1-3 bytes left to copy, so don't try the
  1.3575 +                      * 16-bit loop below.
  1.3576 +                      */
  1.3577 +                     dp = (png_bytep)dp32;
  1.3578 +                     sp = (png_const_bytep)sp32;
  1.3579 +                     do
  1.3580 +                        *dp++ = *sp++;
  1.3581 +                     while (--row_width > 0);
  1.3582 +                     return;
  1.3583 +                  }
  1.3584 +
  1.3585 +                  /* Else do it in 16-bit quantities, but only if the size is
  1.3586 +                   * not too large.
  1.3587 +                   */
  1.3588 +                  else
  1.3589 +                  {
  1.3590 +                     png_uint_16p dp16 = png_aligncast(png_uint_16p, dp);
  1.3591 +                     png_const_uint_16p sp16 = png_aligncastconst(
  1.3592 +                        png_const_uint_16p, sp);
  1.3593 +                     size_t skip = (bytes_to_jump-bytes_to_copy) /
  1.3594 +                        (sizeof (png_uint_16));
  1.3595 +
  1.3596 +                     do
  1.3597 +                     {
  1.3598 +                        size_t c = bytes_to_copy;
  1.3599 +                        do
  1.3600 +                        {
  1.3601 +                           *dp16++ = *sp16++;
  1.3602 +                           c -= (sizeof (png_uint_16));
  1.3603 +                        }
  1.3604 +                        while (c > 0);
  1.3605 +
  1.3606 +                        if (row_width <= bytes_to_jump)
  1.3607 +                           return;
  1.3608 +
  1.3609 +                        dp16 += skip;
  1.3610 +                        sp16 += skip;
  1.3611 +                        row_width -= bytes_to_jump;
  1.3612 +                     }
  1.3613 +                     while (bytes_to_copy <= row_width);
  1.3614 +
  1.3615 +                     /* End of row - 1 byte left, bytes_to_copy > row_width: */
  1.3616 +                     dp = (png_bytep)dp16;
  1.3617 +                     sp = (png_const_bytep)sp16;
  1.3618 +                     do
  1.3619 +                        *dp++ = *sp++;
  1.3620 +                     while (--row_width > 0);
  1.3621 +                     return;
  1.3622 +                  }
  1.3623 +               }
  1.3624 +#endif /* PNG_ALIGN_ code */
  1.3625 +
  1.3626 +               /* The true default - use a memcpy: */
  1.3627 +               for (;;)
  1.3628 +               {
  1.3629 +                  memcpy(dp, sp, bytes_to_copy);
  1.3630 +
  1.3631 +                  if (row_width <= bytes_to_jump)
  1.3632 +                     return;
  1.3633 +
  1.3634 +                  sp += bytes_to_jump;
  1.3635 +                  dp += bytes_to_jump;
  1.3636 +                  row_width -= bytes_to_jump;
  1.3637 +                  if (bytes_to_copy > row_width)
  1.3638 +                     bytes_to_copy = row_width;
  1.3639 +               }
  1.3640 +         }
  1.3641 +
  1.3642 +         /* NOT REACHED*/
  1.3643 +      } /* pixel_depth >= 8 */
  1.3644 +
  1.3645 +      /* Here if pixel_depth < 8 to check 'end_ptr' below. */
  1.3646 +   }
  1.3647 +   else
  1.3648 +#endif
  1.3649 +
  1.3650 +   /* If here then the switch above wasn't used so just memcpy the whole row
  1.3651 +    * from the temporary row buffer (notice that this overwrites the end of the
  1.3652 +    * destination row if it is a partial byte.)
  1.3653 +    */
  1.3654 +   memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
  1.3655 +
  1.3656 +   /* Restore the overwritten bits from the last byte if necessary. */
  1.3657 +   if (end_ptr != NULL)
  1.3658 +      *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
  1.3659 +}
  1.3660 +
  1.3661 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.3662 +void /* PRIVATE */
  1.3663 +png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
  1.3664 +   png_uint_32 transformations /* Because these may affect the byte layout */)
  1.3665 +{
  1.3666 +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1.3667 +   /* Offset to next interlace block */
  1.3668 +   static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  1.3669 +
  1.3670 +   png_debug(1, "in png_do_read_interlace");
  1.3671 +   if (row != NULL && row_info != NULL)
  1.3672 +   {
  1.3673 +      png_uint_32 final_width;
  1.3674 +
  1.3675 +      final_width = row_info->width * png_pass_inc[pass];
  1.3676 +
  1.3677 +      switch (row_info->pixel_depth)
  1.3678 +      {
  1.3679 +         case 1:
  1.3680 +         {
  1.3681 +            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
  1.3682 +            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
  1.3683 +            int sshift, dshift;
  1.3684 +            int s_start, s_end, s_inc;
  1.3685 +            int jstop = png_pass_inc[pass];
  1.3686 +            png_byte v;
  1.3687 +            png_uint_32 i;
  1.3688 +            int j;
  1.3689 +
  1.3690 +#ifdef PNG_READ_PACKSWAP_SUPPORTED
  1.3691 +            if (transformations & PNG_PACKSWAP)
  1.3692 +            {
  1.3693 +                sshift = (int)((row_info->width + 7) & 0x07);
  1.3694 +                dshift = (int)((final_width + 7) & 0x07);
  1.3695 +                s_start = 7;
  1.3696 +                s_end = 0;
  1.3697 +                s_inc = -1;
  1.3698 +            }
  1.3699 +
  1.3700 +            else
  1.3701 +#endif
  1.3702 +            {
  1.3703 +                sshift = 7 - (int)((row_info->width + 7) & 0x07);
  1.3704 +                dshift = 7 - (int)((final_width + 7) & 0x07);
  1.3705 +                s_start = 0;
  1.3706 +                s_end = 7;
  1.3707 +                s_inc = 1;
  1.3708 +            }
  1.3709 +
  1.3710 +            for (i = 0; i < row_info->width; i++)
  1.3711 +            {
  1.3712 +               v = (png_byte)((*sp >> sshift) & 0x01);
  1.3713 +               for (j = 0; j < jstop; j++)
  1.3714 +               {
  1.3715 +                  unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
  1.3716 +                  tmp |= v << dshift;
  1.3717 +                  *dp = (png_byte)(tmp & 0xff);
  1.3718 +
  1.3719 +                  if (dshift == s_end)
  1.3720 +                  {
  1.3721 +                     dshift = s_start;
  1.3722 +                     dp--;
  1.3723 +                  }
  1.3724 +
  1.3725 +                  else
  1.3726 +                     dshift += s_inc;
  1.3727 +               }
  1.3728 +
  1.3729 +               if (sshift == s_end)
  1.3730 +               {
  1.3731 +                  sshift = s_start;
  1.3732 +                  sp--;
  1.3733 +               }
  1.3734 +
  1.3735 +               else
  1.3736 +                  sshift += s_inc;
  1.3737 +            }
  1.3738 +            break;
  1.3739 +         }
  1.3740 +
  1.3741 +         case 2:
  1.3742 +         {
  1.3743 +            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
  1.3744 +            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
  1.3745 +            int sshift, dshift;
  1.3746 +            int s_start, s_end, s_inc;
  1.3747 +            int jstop = png_pass_inc[pass];
  1.3748 +            png_uint_32 i;
  1.3749 +
  1.3750 +#ifdef PNG_READ_PACKSWAP_SUPPORTED
  1.3751 +            if (transformations & PNG_PACKSWAP)
  1.3752 +            {
  1.3753 +               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
  1.3754 +               dshift = (int)(((final_width + 3) & 0x03) << 1);
  1.3755 +               s_start = 6;
  1.3756 +               s_end = 0;
  1.3757 +               s_inc = -2;
  1.3758 +            }
  1.3759 +
  1.3760 +            else
  1.3761 +#endif
  1.3762 +            {
  1.3763 +               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
  1.3764 +               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
  1.3765 +               s_start = 0;
  1.3766 +               s_end = 6;
  1.3767 +               s_inc = 2;
  1.3768 +            }
  1.3769 +
  1.3770 +            for (i = 0; i < row_info->width; i++)
  1.3771 +            {
  1.3772 +               png_byte v;
  1.3773 +               int j;
  1.3774 +
  1.3775 +               v = (png_byte)((*sp >> sshift) & 0x03);
  1.3776 +               for (j = 0; j < jstop; j++)
  1.3777 +               {
  1.3778 +                  unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
  1.3779 +                  tmp |= v << dshift;
  1.3780 +                  *dp = (png_byte)(tmp & 0xff);
  1.3781 +
  1.3782 +                  if (dshift == s_end)
  1.3783 +                  {
  1.3784 +                     dshift = s_start;
  1.3785 +                     dp--;
  1.3786 +                  }
  1.3787 +
  1.3788 +                  else
  1.3789 +                     dshift += s_inc;
  1.3790 +               }
  1.3791 +
  1.3792 +               if (sshift == s_end)
  1.3793 +               {
  1.3794 +                  sshift = s_start;
  1.3795 +                  sp--;
  1.3796 +               }
  1.3797 +
  1.3798 +               else
  1.3799 +                  sshift += s_inc;
  1.3800 +            }
  1.3801 +            break;
  1.3802 +         }
  1.3803 +
  1.3804 +         case 4:
  1.3805 +         {
  1.3806 +            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
  1.3807 +            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
  1.3808 +            int sshift, dshift;
  1.3809 +            int s_start, s_end, s_inc;
  1.3810 +            png_uint_32 i;
  1.3811 +            int jstop = png_pass_inc[pass];
  1.3812 +
  1.3813 +#ifdef PNG_READ_PACKSWAP_SUPPORTED
  1.3814 +            if (transformations & PNG_PACKSWAP)
  1.3815 +            {
  1.3816 +               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
  1.3817 +               dshift = (int)(((final_width + 1) & 0x01) << 2);
  1.3818 +               s_start = 4;
  1.3819 +               s_end = 0;
  1.3820 +               s_inc = -4;
  1.3821 +            }
  1.3822 +
  1.3823 +            else
  1.3824 +#endif
  1.3825 +            {
  1.3826 +               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
  1.3827 +               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
  1.3828 +               s_start = 0;
  1.3829 +               s_end = 4;
  1.3830 +               s_inc = 4;
  1.3831 +            }
  1.3832 +
  1.3833 +            for (i = 0; i < row_info->width; i++)
  1.3834 +            {
  1.3835 +               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
  1.3836 +               int j;
  1.3837 +
  1.3838 +               for (j = 0; j < jstop; j++)
  1.3839 +               {
  1.3840 +                  unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
  1.3841 +                  tmp |= v << dshift;
  1.3842 +                  *dp = (png_byte)(tmp & 0xff);
  1.3843 +
  1.3844 +                  if (dshift == s_end)
  1.3845 +                  {
  1.3846 +                     dshift = s_start;
  1.3847 +                     dp--;
  1.3848 +                  }
  1.3849 +
  1.3850 +                  else
  1.3851 +                     dshift += s_inc;
  1.3852 +               }
  1.3853 +
  1.3854 +               if (sshift == s_end)
  1.3855 +               {
  1.3856 +                  sshift = s_start;
  1.3857 +                  sp--;
  1.3858 +               }
  1.3859 +
  1.3860 +               else
  1.3861 +                  sshift += s_inc;
  1.3862 +            }
  1.3863 +            break;
  1.3864 +         }
  1.3865 +
  1.3866 +         default:
  1.3867 +         {
  1.3868 +            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
  1.3869 +
  1.3870 +            png_bytep sp = row + (png_size_t)(row_info->width - 1)
  1.3871 +                * pixel_bytes;
  1.3872 +
  1.3873 +            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
  1.3874 +
  1.3875 +            int jstop = png_pass_inc[pass];
  1.3876 +            png_uint_32 i;
  1.3877 +
  1.3878 +            for (i = 0; i < row_info->width; i++)
  1.3879 +            {
  1.3880 +               png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */
  1.3881 +               int j;
  1.3882 +
  1.3883 +               memcpy(v, sp, pixel_bytes);
  1.3884 +
  1.3885 +               for (j = 0; j < jstop; j++)
  1.3886 +               {
  1.3887 +                  memcpy(dp, v, pixel_bytes);
  1.3888 +                  dp -= pixel_bytes;
  1.3889 +               }
  1.3890 +
  1.3891 +               sp -= pixel_bytes;
  1.3892 +            }
  1.3893 +            break;
  1.3894 +         }
  1.3895 +      }
  1.3896 +
  1.3897 +      row_info->width = final_width;
  1.3898 +      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
  1.3899 +   }
  1.3900 +#ifndef PNG_READ_PACKSWAP_SUPPORTED
  1.3901 +   PNG_UNUSED(transformations)  /* Silence compiler warning */
  1.3902 +#endif
  1.3903 +}
  1.3904 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.3905 +
  1.3906 +static void
  1.3907 +png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
  1.3908 +   png_const_bytep prev_row)
  1.3909 +{
  1.3910 +   png_size_t i;
  1.3911 +   png_size_t istop = row_info->rowbytes;
  1.3912 +   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
  1.3913 +   png_bytep rp = row + bpp;
  1.3914 +
  1.3915 +   PNG_UNUSED(prev_row)
  1.3916 +
  1.3917 +   for (i = bpp; i < istop; i++)
  1.3918 +   {
  1.3919 +      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
  1.3920 +      rp++;
  1.3921 +   }
  1.3922 +}
  1.3923 +
  1.3924 +static void
  1.3925 +png_read_filter_row_up(png_row_infop row_info, png_bytep row,
  1.3926 +   png_const_bytep prev_row)
  1.3927 +{
  1.3928 +   png_size_t i;
  1.3929 +   png_size_t istop = row_info->rowbytes;
  1.3930 +   png_bytep rp = row;
  1.3931 +   png_const_bytep pp = prev_row;
  1.3932 +
  1.3933 +   for (i = 0; i < istop; i++)
  1.3934 +   {
  1.3935 +      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
  1.3936 +      rp++;
  1.3937 +   }
  1.3938 +}
  1.3939 +
  1.3940 +static void
  1.3941 +png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
  1.3942 +   png_const_bytep prev_row)
  1.3943 +{
  1.3944 +   png_size_t i;
  1.3945 +   png_bytep rp = row;
  1.3946 +   png_const_bytep pp = prev_row;
  1.3947 +   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
  1.3948 +   png_size_t istop = row_info->rowbytes - bpp;
  1.3949 +
  1.3950 +   for (i = 0; i < bpp; i++)
  1.3951 +   {
  1.3952 +      *rp = (png_byte)(((int)(*rp) +
  1.3953 +         ((int)(*pp++) / 2 )) & 0xff);
  1.3954 +
  1.3955 +      rp++;
  1.3956 +   }
  1.3957 +
  1.3958 +   for (i = 0; i < istop; i++)
  1.3959 +   {
  1.3960 +      *rp = (png_byte)(((int)(*rp) +
  1.3961 +         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
  1.3962 +
  1.3963 +      rp++;
  1.3964 +   }
  1.3965 +}
  1.3966 +
  1.3967 +static void
  1.3968 +png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
  1.3969 +   png_const_bytep prev_row)
  1.3970 +{
  1.3971 +   png_bytep rp_end = row + row_info->rowbytes;
  1.3972 +   int a, c;
  1.3973 +
  1.3974 +   /* First pixel/byte */
  1.3975 +   c = *prev_row++;
  1.3976 +   a = *row + c;
  1.3977 +   *row++ = (png_byte)a;
  1.3978 +
  1.3979 +   /* Remainder */
  1.3980 +   while (row < rp_end)
  1.3981 +   {
  1.3982 +      int b, pa, pb, pc, p;
  1.3983 +
  1.3984 +      a &= 0xff; /* From previous iteration or start */
  1.3985 +      b = *prev_row++;
  1.3986 +
  1.3987 +      p = b - c;
  1.3988 +      pc = a - c;
  1.3989 +
  1.3990 +#     ifdef PNG_USE_ABS
  1.3991 +         pa = abs(p);
  1.3992 +         pb = abs(pc);
  1.3993 +         pc = abs(p + pc);
  1.3994 +#     else
  1.3995 +         pa = p < 0 ? -p : p;
  1.3996 +         pb = pc < 0 ? -pc : pc;
  1.3997 +         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
  1.3998 +#     endif
  1.3999 +
  1.4000 +      /* Find the best predictor, the least of pa, pb, pc favoring the earlier
  1.4001 +       * ones in the case of a tie.
  1.4002 +       */
  1.4003 +      if (pb < pa) pa = pb, a = b;
  1.4004 +      if (pc < pa) a = c;
  1.4005 +
  1.4006 +      /* Calculate the current pixel in a, and move the previous row pixel to c
  1.4007 +       * for the next time round the loop
  1.4008 +       */
  1.4009 +      c = b;
  1.4010 +      a += *row;
  1.4011 +      *row++ = (png_byte)a;
  1.4012 +   }
  1.4013 +}
  1.4014 +
  1.4015 +static void
  1.4016 +png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
  1.4017 +   png_const_bytep prev_row)
  1.4018 +{
  1.4019 +   int bpp = (row_info->pixel_depth + 7) >> 3;
  1.4020 +   png_bytep rp_end = row + bpp;
  1.4021 +
  1.4022 +   /* Process the first pixel in the row completely (this is the same as 'up'
  1.4023 +    * because there is only one candidate predictor for the first row).
  1.4024 +    */
  1.4025 +   while (row < rp_end)
  1.4026 +   {
  1.4027 +      int a = *row + *prev_row++;
  1.4028 +      *row++ = (png_byte)a;
  1.4029 +   }
  1.4030 +
  1.4031 +   /* Remainder */
  1.4032 +   rp_end += row_info->rowbytes - bpp;
  1.4033 +
  1.4034 +   while (row < rp_end)
  1.4035 +   {
  1.4036 +      int a, b, c, pa, pb, pc, p;
  1.4037 +
  1.4038 +      c = *(prev_row - bpp);
  1.4039 +      a = *(row - bpp);
  1.4040 +      b = *prev_row++;
  1.4041 +
  1.4042 +      p = b - c;
  1.4043 +      pc = a - c;
  1.4044 +
  1.4045 +#     ifdef PNG_USE_ABS
  1.4046 +         pa = abs(p);
  1.4047 +         pb = abs(pc);
  1.4048 +         pc = abs(p + pc);
  1.4049 +#     else
  1.4050 +         pa = p < 0 ? -p : p;
  1.4051 +         pb = pc < 0 ? -pc : pc;
  1.4052 +         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
  1.4053 +#     endif
  1.4054 +
  1.4055 +      if (pb < pa) pa = pb, a = b;
  1.4056 +      if (pc < pa) a = c;
  1.4057 +
  1.4058 +      a += *row;
  1.4059 +      *row++ = (png_byte)a;
  1.4060 +   }
  1.4061 +}
  1.4062 +
  1.4063 +static void
  1.4064 +png_init_filter_functions(png_structrp pp)
  1.4065 +   /* This function is called once for every PNG image (except for PNG images
  1.4066 +    * that only use PNG_FILTER_VALUE_NONE for all rows) to set the
  1.4067 +    * implementations required to reverse the filtering of PNG rows.  Reversing
  1.4068 +    * the filter is the first transformation performed on the row data.  It is
  1.4069 +    * performed in place, therefore an implementation can be selected based on
  1.4070 +    * the image pixel format.  If the implementation depends on image width then
  1.4071 +    * take care to ensure that it works correctly if the image is interlaced -
  1.4072 +    * interlacing causes the actual row width to vary.
  1.4073 +    */
  1.4074 +{
  1.4075 +   unsigned int bpp = (pp->pixel_depth + 7) >> 3;
  1.4076 +
  1.4077 +   pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
  1.4078 +   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
  1.4079 +   pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
  1.4080 +   if (bpp == 1)
  1.4081 +      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
  1.4082 +         png_read_filter_row_paeth_1byte_pixel;
  1.4083 +   else
  1.4084 +      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
  1.4085 +         png_read_filter_row_paeth_multibyte_pixel;
  1.4086 +
  1.4087 +#ifdef PNG_FILTER_OPTIMIZATIONS
  1.4088 +   /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to
  1.4089 +    * call to install hardware optimizations for the above functions; simply
  1.4090 +    * replace whatever elements of the pp->read_filter[] array with a hardware
  1.4091 +    * specific (or, for that matter, generic) optimization.
  1.4092 +    *
  1.4093 +    * To see an example of this examine what configure.ac does when
  1.4094 +    * --enable-arm-neon is specified on the command line.
  1.4095 +    */
  1.4096 +   PNG_FILTER_OPTIMIZATIONS(pp, bpp);
  1.4097 +#endif
  1.4098 +}
  1.4099 +
  1.4100 +void /* PRIVATE */
  1.4101 +png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
  1.4102 +   png_const_bytep prev_row, int filter)
  1.4103 +{
  1.4104 +   /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
  1.4105 +    * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
  1.4106 +    * implementations.  See png_init_filter_functions above.
  1.4107 +    */
  1.4108 +   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
  1.4109 +   {
  1.4110 +      if (pp->read_filter[0] == NULL)
  1.4111 +         png_init_filter_functions(pp);
  1.4112 +
  1.4113 +      pp->read_filter[filter-1](row_info, row, prev_row);
  1.4114 +   }
  1.4115 +}
  1.4116 +
  1.4117 +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  1.4118 +void /* PRIVATE */
  1.4119 +png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
  1.4120 +   png_alloc_size_t avail_out)
  1.4121 +{
  1.4122 +   /* Loop reading IDATs and decompressing the result into output[avail_out] */
  1.4123 +   png_ptr->zstream.next_out = output;
  1.4124 +   png_ptr->zstream.avail_out = 0; /* safety: set below */
  1.4125 +
  1.4126 +   if (output == NULL)
  1.4127 +      avail_out = 0;
  1.4128 +
  1.4129 +   do
  1.4130 +   {
  1.4131 +      int ret;
  1.4132 +      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
  1.4133 +
  1.4134 +      if (png_ptr->zstream.avail_in == 0)
  1.4135 +      {
  1.4136 +         uInt avail_in;
  1.4137 +         png_bytep buffer;
  1.4138 +
  1.4139 +#ifdef PNG_READ_APNG_SUPPORTED
  1.4140 +         png_uint_32 bytes_to_skip = 0;
  1.4141 +
  1.4142 +         while (png_ptr->idat_size == 0 || bytes_to_skip != 0)
  1.4143 +         {
  1.4144 +            png_crc_finish(png_ptr, bytes_to_skip);
  1.4145 +            bytes_to_skip = 0;
  1.4146 +
  1.4147 +            png_ptr->idat_size = png_read_chunk_header(png_ptr);
  1.4148 +            if (png_ptr->num_frames_read == 0)
  1.4149 +            {
  1.4150 +               if (png_ptr->chunk_name != png_IDAT)
  1.4151 +                  png_error(png_ptr, "Not enough image data");
  1.4152 +            }
  1.4153 +            else
  1.4154 +            {
  1.4155 +               if (png_ptr->chunk_name == png_IEND)
  1.4156 +                  png_error(png_ptr, "Not enough image data");
  1.4157 +               if (png_ptr->chunk_name != png_fdAT)
  1.4158 +               {
  1.4159 +                  png_warning(png_ptr, "Skipped (ignored) a chunk "
  1.4160 +                                       "between APNG chunks");
  1.4161 +                  bytes_to_skip = png_ptr->idat_size;
  1.4162 +                  continue;
  1.4163 +               }
  1.4164 +
  1.4165 +               png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
  1.4166 +
  1.4167 +               png_ptr->idat_size -= 4;
  1.4168 +            }
  1.4169 +         }
  1.4170 +#else
  1.4171 +         while (png_ptr->idat_size == 0)
  1.4172 +         {
  1.4173 +            png_crc_finish(png_ptr, 0);
  1.4174 +
  1.4175 +            png_ptr->idat_size = png_read_chunk_header(png_ptr);
  1.4176 +            /* This is an error even in the 'check' case because the code just
  1.4177 +             * consumed a non-IDAT header.
  1.4178 +             */
  1.4179 +            if (png_ptr->chunk_name != png_IDAT)
  1.4180 +               png_error(png_ptr, "Not enough image data");
  1.4181 +         }
  1.4182 +#endif /* PNG_READ_APNG_SUPPORTED */
  1.4183 +
  1.4184 +         avail_in = png_ptr->IDAT_read_size;
  1.4185 +
  1.4186 +         if (avail_in > png_ptr->idat_size)
  1.4187 +            avail_in = (uInt)png_ptr->idat_size;
  1.4188 +
  1.4189 +         /* A PNG with a gradually increasing IDAT size will defeat this attempt
  1.4190 +          * to minimize memory usage by causing lots of re-allocs, but
  1.4191 +          * realistically doing IDAT_read_size re-allocs is not likely to be a
  1.4192 +          * big problem.
  1.4193 +          */
  1.4194 +         buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/);
  1.4195 +
  1.4196 +         png_crc_read(png_ptr, buffer, avail_in);
  1.4197 +         png_ptr->idat_size -= avail_in;
  1.4198 +
  1.4199 +         png_ptr->zstream.next_in = buffer;
  1.4200 +         png_ptr->zstream.avail_in = avail_in;
  1.4201 +      }
  1.4202 +
  1.4203 +      /* And set up the output side. */
  1.4204 +      if (output != NULL) /* standard read */
  1.4205 +      {
  1.4206 +         uInt out = ZLIB_IO_MAX;
  1.4207 +
  1.4208 +         if (out > avail_out)
  1.4209 +            out = (uInt)avail_out;
  1.4210 +
  1.4211 +         avail_out -= out;
  1.4212 +         png_ptr->zstream.avail_out = out;
  1.4213 +      }
  1.4214 +
  1.4215 +      else /* after last row, checking for end */
  1.4216 +      {
  1.4217 +         png_ptr->zstream.next_out = tmpbuf;
  1.4218 +         png_ptr->zstream.avail_out = (sizeof tmpbuf);
  1.4219 +      }
  1.4220 +
  1.4221 +      /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the
  1.4222 +       * process.  If the LZ stream is truncated the sequential reader will
  1.4223 +       * terminally damage the stream, above, by reading the chunk header of the
  1.4224 +       * following chunk (it then exits with png_error).
  1.4225 +       *
  1.4226 +       * TODO: deal more elegantly with truncated IDAT lists.
  1.4227 +       */
  1.4228 +      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
  1.4229 +
  1.4230 +      /* Take the unconsumed output back. */
  1.4231 +      if (output != NULL)
  1.4232 +         avail_out += png_ptr->zstream.avail_out;
  1.4233 +
  1.4234 +      else /* avail_out counts the extra bytes */
  1.4235 +         avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out;
  1.4236 +
  1.4237 +      png_ptr->zstream.avail_out = 0;
  1.4238 +
  1.4239 +      if (ret == Z_STREAM_END)
  1.4240 +      {
  1.4241 +         /* Do this for safety; we won't read any more into this row. */
  1.4242 +         png_ptr->zstream.next_out = NULL;
  1.4243 +
  1.4244 +         png_ptr->mode |= PNG_AFTER_IDAT;
  1.4245 +         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
  1.4246 +#ifdef PNG_READ_APNG_SUPPORTED
  1.4247 +         png_ptr->num_frames_read++;
  1.4248 +#endif
  1.4249 +
  1.4250 +         if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
  1.4251 +            png_chunk_benign_error(png_ptr, "Extra compressed data");
  1.4252 +         break;
  1.4253 +      }
  1.4254 +
  1.4255 +      if (ret != Z_OK)
  1.4256 +      {
  1.4257 +         png_zstream_error(png_ptr, ret);
  1.4258 +
  1.4259 +         if (output != NULL)
  1.4260 +            png_chunk_error(png_ptr, png_ptr->zstream.msg);
  1.4261 +
  1.4262 +         else /* checking */
  1.4263 +         {
  1.4264 +            png_chunk_benign_error(png_ptr, png_ptr->zstream.msg);
  1.4265 +            return;
  1.4266 +         }
  1.4267 +      }
  1.4268 +   } while (avail_out > 0);
  1.4269 +
  1.4270 +   if (avail_out > 0)
  1.4271 +   {
  1.4272 +      /* The stream ended before the image; this is the same as too few IDATs so
  1.4273 +       * should be handled the same way.
  1.4274 +       */
  1.4275 +      if (output != NULL)
  1.4276 +         png_error(png_ptr, "Not enough image data");
  1.4277 +
  1.4278 +      else /* the deflate stream contained extra data */
  1.4279 +         png_chunk_benign_error(png_ptr, "Too much image data");
  1.4280 +   }
  1.4281 +}
  1.4282 +
  1.4283 +void /* PRIVATE */
  1.4284 +png_read_finish_IDAT(png_structrp png_ptr)
  1.4285 +{
  1.4286 +   /* We don't need any more data and the stream should have ended, however the
  1.4287 +    * LZ end code may actually not have been processed.  In this case we must
  1.4288 +    * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk
  1.4289 +    * may still remain to be consumed.
  1.4290 +    */
  1.4291 +   if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
  1.4292 +   {
  1.4293 +      /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in
  1.4294 +       * the compressed stream, but the stream may be damaged too, so even after
  1.4295 +       * this call we may need to terminate the zstream ownership.
  1.4296 +       */
  1.4297 +      png_read_IDAT_data(png_ptr, NULL, 0);
  1.4298 +      png_ptr->zstream.next_out = NULL; /* safety */
  1.4299 +
  1.4300 +      /* Now clear everything out for safety; the following may not have been
  1.4301 +       * done.
  1.4302 +       */
  1.4303 +      if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
  1.4304 +      {
  1.4305 +         png_ptr->mode |= PNG_AFTER_IDAT;
  1.4306 +         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
  1.4307 +      }
  1.4308 +   }
  1.4309 +
  1.4310 +   /* If the zstream has not been released do it now *and* terminate the reading
  1.4311 +    * of the final IDAT chunk.
  1.4312 +    */
  1.4313 +   if (png_ptr->zowner == png_IDAT)
  1.4314 +   {
  1.4315 +      /* Always do this; the pointers otherwise point into the read buffer. */
  1.4316 +      png_ptr->zstream.next_in = NULL;
  1.4317 +      png_ptr->zstream.avail_in = 0;
  1.4318 +
  1.4319 +      /* Now we no longer own the zstream. */
  1.4320 +      png_ptr->zowner = 0;
  1.4321 +
  1.4322 +      /* The slightly weird semantics of the sequential IDAT reading is that we
  1.4323 +       * are always in or at the end of an IDAT chunk, so we always need to do a
  1.4324 +       * crc_finish here.  If idat_size is non-zero we also need to read the
  1.4325 +       * spurious bytes at the end of the chunk now.
  1.4326 +       */
  1.4327 +      (void)png_crc_finish(png_ptr, png_ptr->idat_size);
  1.4328 +   }
  1.4329 +}
  1.4330 +
  1.4331 +void /* PRIVATE */
  1.4332 +png_read_finish_row(png_structrp png_ptr)
  1.4333 +{
  1.4334 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.4335 +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1.4336 +
  1.4337 +   /* Start of interlace block */
  1.4338 +   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  1.4339 +
  1.4340 +   /* Offset to next interlace block */
  1.4341 +   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  1.4342 +
  1.4343 +   /* Start of interlace block in the y direction */
  1.4344 +   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  1.4345 +
  1.4346 +   /* Offset to next interlace block in the y direction */
  1.4347 +   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  1.4348 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.4349 +
  1.4350 +   png_debug(1, "in png_read_finish_row");
  1.4351 +   png_ptr->row_number++;
  1.4352 +   if (png_ptr->row_number < png_ptr->num_rows)
  1.4353 +      return;
  1.4354 +
  1.4355 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.4356 +   if (png_ptr->interlaced)
  1.4357 +   {
  1.4358 +      png_ptr->row_number = 0;
  1.4359 +
  1.4360 +      /* TO DO: don't do this if prev_row isn't needed (requires
  1.4361 +       * read-ahead of the next row's filter byte.
  1.4362 +       */
  1.4363 +      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  1.4364 +
  1.4365 +      do
  1.4366 +      {
  1.4367 +         png_ptr->pass++;
  1.4368 +
  1.4369 +         if (png_ptr->pass >= 7)
  1.4370 +            break;
  1.4371 +
  1.4372 +         png_ptr->iwidth = (png_ptr->width +
  1.4373 +            png_pass_inc[png_ptr->pass] - 1 -
  1.4374 +            png_pass_start[png_ptr->pass]) /
  1.4375 +            png_pass_inc[png_ptr->pass];
  1.4376 +
  1.4377 +         if (!(png_ptr->transformations & PNG_INTERLACE))
  1.4378 +         {
  1.4379 +            png_ptr->num_rows = (png_ptr->height +
  1.4380 +                png_pass_yinc[png_ptr->pass] - 1 -
  1.4381 +                png_pass_ystart[png_ptr->pass]) /
  1.4382 +                png_pass_yinc[png_ptr->pass];
  1.4383 +         }
  1.4384 +
  1.4385 +         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
  1.4386 +            break; /* libpng deinterlacing sees every row */
  1.4387 +
  1.4388 +      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
  1.4389 +
  1.4390 +      if (png_ptr->pass < 7)
  1.4391 +         return;
  1.4392 +   }
  1.4393 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.4394 +
  1.4395 +   /* Here after at the end of the last row of the last pass. */
  1.4396 +   png_read_finish_IDAT(png_ptr);
  1.4397 +}
  1.4398 +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  1.4399 +
  1.4400 +void /* PRIVATE */
  1.4401 +png_read_start_row(png_structrp png_ptr)
  1.4402 +{
  1.4403 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.4404 +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1.4405 +
  1.4406 +   /* Start of interlace block */
  1.4407 +   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  1.4408 +
  1.4409 +   /* Offset to next interlace block */
  1.4410 +   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  1.4411 +
  1.4412 +   /* Start of interlace block in the y direction */
  1.4413 +   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  1.4414 +
  1.4415 +   /* Offset to next interlace block in the y direction */
  1.4416 +   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  1.4417 +#endif
  1.4418 +
  1.4419 +   int max_pixel_depth;
  1.4420 +   png_size_t row_bytes;
  1.4421 +
  1.4422 +   png_debug(1, "in png_read_start_row");
  1.4423 +
  1.4424 +#ifdef PNG_READ_TRANSFORMS_SUPPORTED
  1.4425 +   png_init_read_transformations(png_ptr);
  1.4426 +#endif
  1.4427 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.4428 +   if (png_ptr->interlaced)
  1.4429 +   {
  1.4430 +      if (!(png_ptr->transformations & PNG_INTERLACE))
  1.4431 +         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  1.4432 +             png_pass_ystart[0]) / png_pass_yinc[0];
  1.4433 +
  1.4434 +      else
  1.4435 +         png_ptr->num_rows = png_ptr->height;
  1.4436 +
  1.4437 +      png_ptr->iwidth = (png_ptr->width +
  1.4438 +          png_pass_inc[png_ptr->pass] - 1 -
  1.4439 +          png_pass_start[png_ptr->pass]) /
  1.4440 +          png_pass_inc[png_ptr->pass];
  1.4441 +   }
  1.4442 +
  1.4443 +   else
  1.4444 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.4445 +   {
  1.4446 +      png_ptr->num_rows = png_ptr->height;
  1.4447 +      png_ptr->iwidth = png_ptr->width;
  1.4448 +   }
  1.4449 +
  1.4450 +   max_pixel_depth = png_ptr->pixel_depth;
  1.4451 +
  1.4452 +   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
  1.4453 +    * calculations to calculate the final pixel depth, then
  1.4454 +    * png_do_read_transforms actually does the transforms.  This means that the
  1.4455 +    * code which effectively calculates this value is actually repeated in three
  1.4456 +    * separate places.  They must all match.  Innocent changes to the order of
  1.4457 +    * transformations can and will break libpng in a way that causes memory
  1.4458 +    * overwrites.
  1.4459 +    *
  1.4460 +    * TODO: fix this.
  1.4461 +    */
  1.4462 +#ifdef PNG_READ_PACK_SUPPORTED
  1.4463 +   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
  1.4464 +      max_pixel_depth = 8;
  1.4465 +#endif
  1.4466 +
  1.4467 +#ifdef PNG_READ_EXPAND_SUPPORTED
  1.4468 +   if (png_ptr->transformations & PNG_EXPAND)
  1.4469 +   {
  1.4470 +      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1.4471 +      {
  1.4472 +         if (png_ptr->num_trans)
  1.4473 +            max_pixel_depth = 32;
  1.4474 +
  1.4475 +         else
  1.4476 +            max_pixel_depth = 24;
  1.4477 +      }
  1.4478 +
  1.4479 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  1.4480 +      {
  1.4481 +         if (max_pixel_depth < 8)
  1.4482 +            max_pixel_depth = 8;
  1.4483 +
  1.4484 +         if (png_ptr->num_trans)
  1.4485 +            max_pixel_depth *= 2;
  1.4486 +      }
  1.4487 +
  1.4488 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  1.4489 +      {
  1.4490 +         if (png_ptr->num_trans)
  1.4491 +         {
  1.4492 +            max_pixel_depth *= 4;
  1.4493 +            max_pixel_depth /= 3;
  1.4494 +         }
  1.4495 +      }
  1.4496 +   }
  1.4497 +#endif
  1.4498 +
  1.4499 +#ifdef PNG_READ_EXPAND_16_SUPPORTED
  1.4500 +   if (png_ptr->transformations & PNG_EXPAND_16)
  1.4501 +   {
  1.4502 +#     ifdef PNG_READ_EXPAND_SUPPORTED
  1.4503 +         /* In fact it is an error if it isn't supported, but checking is
  1.4504 +          * the safe way.
  1.4505 +          */
  1.4506 +         if (png_ptr->transformations & PNG_EXPAND)
  1.4507 +         {
  1.4508 +            if (png_ptr->bit_depth < 16)
  1.4509 +               max_pixel_depth *= 2;
  1.4510 +         }
  1.4511 +         else
  1.4512 +#     endif
  1.4513 +         png_ptr->transformations &= ~PNG_EXPAND_16;
  1.4514 +   }
  1.4515 +#endif
  1.4516 +
  1.4517 +#ifdef PNG_READ_FILLER_SUPPORTED
  1.4518 +   if (png_ptr->transformations & (PNG_FILLER))
  1.4519 +   {
  1.4520 +      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  1.4521 +      {
  1.4522 +         if (max_pixel_depth <= 8)
  1.4523 +            max_pixel_depth = 16;
  1.4524 +
  1.4525 +         else
  1.4526 +            max_pixel_depth = 32;
  1.4527 +      }
  1.4528 +
  1.4529 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
  1.4530 +         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1.4531 +      {
  1.4532 +         if (max_pixel_depth <= 32)
  1.4533 +            max_pixel_depth = 32;
  1.4534 +
  1.4535 +         else
  1.4536 +            max_pixel_depth = 64;
  1.4537 +      }
  1.4538 +   }
  1.4539 +#endif
  1.4540 +
  1.4541 +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
  1.4542 +   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  1.4543 +   {
  1.4544 +      if (
  1.4545 +#ifdef PNG_READ_EXPAND_SUPPORTED
  1.4546 +          (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
  1.4547 +#endif
  1.4548 +#ifdef PNG_READ_FILLER_SUPPORTED
  1.4549 +          (png_ptr->transformations & (PNG_FILLER)) ||
  1.4550 +#endif
  1.4551 +          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1.4552 +      {
  1.4553 +         if (max_pixel_depth <= 16)
  1.4554 +            max_pixel_depth = 32;
  1.4555 +
  1.4556 +         else
  1.4557 +            max_pixel_depth = 64;
  1.4558 +      }
  1.4559 +
  1.4560 +      else
  1.4561 +      {
  1.4562 +         if (max_pixel_depth <= 8)
  1.4563 +         {
  1.4564 +            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1.4565 +               max_pixel_depth = 32;
  1.4566 +
  1.4567 +            else
  1.4568 +               max_pixel_depth = 24;
  1.4569 +         }
  1.4570 +
  1.4571 +         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1.4572 +            max_pixel_depth = 64;
  1.4573 +
  1.4574 +         else
  1.4575 +            max_pixel_depth = 48;
  1.4576 +      }
  1.4577 +   }
  1.4578 +#endif
  1.4579 +
  1.4580 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
  1.4581 +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
  1.4582 +   if (png_ptr->transformations & PNG_USER_TRANSFORM)
  1.4583 +   {
  1.4584 +      int user_pixel_depth = png_ptr->user_transform_depth *
  1.4585 +         png_ptr->user_transform_channels;
  1.4586 +
  1.4587 +      if (user_pixel_depth > max_pixel_depth)
  1.4588 +         max_pixel_depth = user_pixel_depth;
  1.4589 +   }
  1.4590 +#endif
  1.4591 +
  1.4592 +   /* This value is stored in png_struct and double checked in the row read
  1.4593 +    * code.
  1.4594 +    */
  1.4595 +   png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
  1.4596 +   png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
  1.4597 +
  1.4598 +   /* Align the width on the next larger 8 pixels.  Mainly used
  1.4599 +    * for interlacing
  1.4600 +    */
  1.4601 +   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
  1.4602 +   /* Calculate the maximum bytes needed, adding a byte and a pixel
  1.4603 +    * for safety's sake
  1.4604 +    */
  1.4605 +   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
  1.4606 +       1 + ((max_pixel_depth + 7) >> 3);
  1.4607 +
  1.4608 +#ifdef PNG_MAX_MALLOC_64K
  1.4609 +   if (row_bytes > (png_uint_32)65536L)
  1.4610 +      png_error(png_ptr, "This image requires a row greater than 64KB");
  1.4611 +#endif
  1.4612 +
  1.4613 +   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
  1.4614 +   {
  1.4615 +     png_free(png_ptr, png_ptr->big_row_buf);
  1.4616 +     png_free(png_ptr, png_ptr->big_prev_row);
  1.4617 +
  1.4618 +     if (png_ptr->interlaced)
  1.4619 +        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
  1.4620 +            row_bytes + 48);
  1.4621 +
  1.4622 +     else
  1.4623 +        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
  1.4624 +
  1.4625 +     png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
  1.4626 +
  1.4627 +#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
  1.4628 +     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
  1.4629 +      * of padding before and after row_buf; treat prev_row similarly.
  1.4630 +      * NOTE: the alignment is to the start of the pixels, one beyond the start
  1.4631 +      * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
  1.4632 +      * was incorrect; the filter byte was aligned, which had the exact
  1.4633 +      * opposite effect of that intended.
  1.4634 +      */
  1.4635 +     {
  1.4636 +        png_bytep temp = png_ptr->big_row_buf + 32;
  1.4637 +        int extra = (int)((temp - (png_bytep)0) & 0x0f);
  1.4638 +        png_ptr->row_buf = temp - extra - 1/*filter byte*/;
  1.4639 +
  1.4640 +        temp = png_ptr->big_prev_row + 32;
  1.4641 +        extra = (int)((temp - (png_bytep)0) & 0x0f);
  1.4642 +        png_ptr->prev_row = temp - extra - 1/*filter byte*/;
  1.4643 +     }
  1.4644 +
  1.4645 +#else
  1.4646 +     /* Use 31 bytes of padding before and 17 bytes after row_buf. */
  1.4647 +     png_ptr->row_buf = png_ptr->big_row_buf + 31;
  1.4648 +     png_ptr->prev_row = png_ptr->big_prev_row + 31;
  1.4649 +#endif
  1.4650 +     png_ptr->old_big_row_buf_size = row_bytes + 48;
  1.4651 +   }
  1.4652 +
  1.4653 +#ifdef PNG_MAX_MALLOC_64K
  1.4654 +   if (png_ptr->rowbytes > 65535)
  1.4655 +      png_error(png_ptr, "This image requires a row greater than 64KB");
  1.4656 +
  1.4657 +#endif
  1.4658 +   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
  1.4659 +      png_error(png_ptr, "Row has too many bytes to allocate in memory");
  1.4660 +
  1.4661 +   memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  1.4662 +
  1.4663 +   png_debug1(3, "width = %u,", png_ptr->width);
  1.4664 +   png_debug1(3, "height = %u,", png_ptr->height);
  1.4665 +   png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
  1.4666 +   png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
  1.4667 +   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
  1.4668 +   png_debug1(3, "irowbytes = %lu",
  1.4669 +       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
  1.4670 +
  1.4671 +   /* The sequential reader needs a buffer for IDAT, but the progressive reader
  1.4672 +    * does not, so free the read buffer now regardless; the sequential reader
  1.4673 +    * reallocates it on demand.
  1.4674 +    */
  1.4675 +   if (png_ptr->read_buffer)
  1.4676 +   {
  1.4677 +      png_bytep buffer = png_ptr->read_buffer;
  1.4678 +
  1.4679 +      png_ptr->read_buffer_size = 0;
  1.4680 +      png_ptr->read_buffer = NULL;
  1.4681 +      png_free(png_ptr, buffer);
  1.4682 +   }
  1.4683 +
  1.4684 +   /* Finally claim the zstream for the inflate of the IDAT data, use the bits
  1.4685 +    * value from the stream (note that this will result in a fatal error if the
  1.4686 +    * IDAT stream has a bogus deflate header window_bits value, but this should
  1.4687 +    * not be happening any longer!)
  1.4688 +    */
  1.4689 +   if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)
  1.4690 +      png_error(png_ptr, png_ptr->zstream.msg);
  1.4691 +
  1.4692 +   png_ptr->flags |= PNG_FLAG_ROW_INIT;
  1.4693 +}
  1.4694 +
  1.4695 +#ifdef PNG_READ_APNG_SUPPORTED
  1.4696 +/* This function is to be called after the main IDAT set has been read and
  1.4697 + * before a new IDAT is read. It resets some parts of png_ptr
  1.4698 + * to make them usable by the read functions again */
  1.4699 +void /* PRIVATE */
  1.4700 +png_read_reset(png_structp png_ptr)
  1.4701 +{
  1.4702 +    png_ptr->mode &= ~PNG_HAVE_IDAT;
  1.4703 +    png_ptr->mode &= ~PNG_AFTER_IDAT;
  1.4704 +    png_ptr->row_number = 0;
  1.4705 +    png_ptr->pass = 0;
  1.4706 +}
  1.4707 +
  1.4708 +void /* PRIVATE */
  1.4709 +png_read_reinit(png_structp png_ptr, png_infop info_ptr)
  1.4710 +{
  1.4711 +    png_ptr->width = info_ptr->next_frame_width;
  1.4712 +    png_ptr->height = info_ptr->next_frame_height;
  1.4713 +    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
  1.4714 +    png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,
  1.4715 +        png_ptr->width);
  1.4716 +    if (png_ptr->prev_row)
  1.4717 +        memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  1.4718 +}
  1.4719 +
  1.4720 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  1.4721 +/* same as png_read_reset() but for the progressive reader */
  1.4722 +void /* PRIVATE */
  1.4723 +png_progressive_read_reset(png_structp png_ptr)
  1.4724 +{
  1.4725 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.4726 +    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1.4727 +
  1.4728 +    /* Start of interlace block */
  1.4729 +    static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
  1.4730 +
  1.4731 +    /* Offset to next interlace block */
  1.4732 +    static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  1.4733 +
  1.4734 +    /* Start of interlace block in the y direction */
  1.4735 +    static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  1.4736 +
  1.4737 +    /* Offset to next interlace block in the y direction */
  1.4738 +    static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  1.4739 +
  1.4740 +    if (png_ptr->interlaced)
  1.4741 +    {
  1.4742 +        if (!(png_ptr->transformations & PNG_INTERLACE))
  1.4743 +            png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  1.4744 +                                png_pass_ystart[0]) / png_pass_yinc[0];
  1.4745 +        else
  1.4746 +            png_ptr->num_rows = png_ptr->height;
  1.4747 +
  1.4748 +        png_ptr->iwidth = (png_ptr->width +
  1.4749 +                           png_pass_inc[png_ptr->pass] - 1 -
  1.4750 +                           png_pass_start[png_ptr->pass]) /
  1.4751 +                           png_pass_inc[png_ptr->pass];
  1.4752 +    }
  1.4753 +    else
  1.4754 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.4755 +    {
  1.4756 +        png_ptr->num_rows = png_ptr->height;
  1.4757 +        png_ptr->iwidth = png_ptr->width;
  1.4758 +    }
  1.4759 +    png_ptr->flags &= ~PNG_FLAG_ZSTREAM_ENDED;
  1.4760 +    if (inflateReset(&(png_ptr->zstream)) != Z_OK)
  1.4761 +        png_error(png_ptr, "inflateReset failed");
  1.4762 +    png_ptr->zstream.avail_in = 0;
  1.4763 +    png_ptr->zstream.next_in = 0;
  1.4764 +    png_ptr->zstream.next_out = png_ptr->row_buf;
  1.4765 +    png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
  1.4766 +        png_ptr->iwidth) + 1;
  1.4767 +}
  1.4768 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  1.4769 +#endif /* PNG_READ_APNG_SUPPORTED */
  1.4770 +#endif /* PNG_READ_SUPPORTED */

mercurial