media/libpng/png.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libpng/png.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,4375 @@
     1.4 +
     1.5 +/* png.c - location for general purpose libpng functions
     1.6 + *
     1.7 + * Last changed in libpng 1.6.9 [February 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 +
    1.17 +#include "pngpriv.h"
    1.18 +
    1.19 +/* Generate a compiler error if there is an old png.h in the search path. */
    1.20 +typedef png_libpng_version_1_6_10 Your_png_h_is_not_version_1_6_10;
    1.21 +
    1.22 +/* Tells libpng that we have already handled the first "num_bytes" bytes
    1.23 + * of the PNG file signature.  If the PNG data is embedded into another
    1.24 + * stream we can set num_bytes = 8 so that libpng will not attempt to read
    1.25 + * or write any of the magic bytes before it starts on the IHDR.
    1.26 + */
    1.27 +
    1.28 +#ifdef PNG_READ_SUPPORTED
    1.29 +void PNGAPI
    1.30 +png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
    1.31 +{
    1.32 +   png_debug(1, "in png_set_sig_bytes");
    1.33 +
    1.34 +   if (png_ptr == NULL)
    1.35 +      return;
    1.36 +
    1.37 +   if (num_bytes > 8)
    1.38 +      png_error(png_ptr, "Too many bytes for PNG signature");
    1.39 +
    1.40 +   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
    1.41 +}
    1.42 +
    1.43 +/* Checks whether the supplied bytes match the PNG signature.  We allow
    1.44 + * checking less than the full 8-byte signature so that those apps that
    1.45 + * already read the first few bytes of a file to determine the file type
    1.46 + * can simply check the remaining bytes for extra assurance.  Returns
    1.47 + * an integer less than, equal to, or greater than zero if sig is found,
    1.48 + * respectively, to be less than, to match, or be greater than the correct
    1.49 + * PNG signature (this is the same behavior as strcmp, memcmp, etc).
    1.50 + */
    1.51 +int PNGAPI
    1.52 +png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
    1.53 +{
    1.54 +   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    1.55 +
    1.56 +   if (num_to_check > 8)
    1.57 +      num_to_check = 8;
    1.58 +
    1.59 +   else if (num_to_check < 1)
    1.60 +      return (-1);
    1.61 +
    1.62 +   if (start > 7)
    1.63 +      return (-1);
    1.64 +
    1.65 +   if (start + num_to_check > 8)
    1.66 +      num_to_check = 8 - start;
    1.67 +
    1.68 +   return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
    1.69 +}
    1.70 +
    1.71 +#endif /* PNG_READ_SUPPORTED */
    1.72 +
    1.73 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    1.74 +/* Function to allocate memory for zlib */
    1.75 +PNG_FUNCTION(voidpf /* PRIVATE */,
    1.76 +png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
    1.77 +{
    1.78 +   png_alloc_size_t num_bytes = size;
    1.79 +
    1.80 +   if (png_ptr == NULL)
    1.81 +      return NULL;
    1.82 +
    1.83 +   if (items >= (~(png_alloc_size_t)0)/size)
    1.84 +   {
    1.85 +      png_warning (png_voidcast(png_structrp, png_ptr),
    1.86 +         "Potential overflow in png_zalloc()");
    1.87 +      return NULL;
    1.88 +   }
    1.89 +
    1.90 +   num_bytes *= items;
    1.91 +   return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
    1.92 +}
    1.93 +
    1.94 +/* Function to free memory for zlib */
    1.95 +void /* PRIVATE */
    1.96 +png_zfree(voidpf png_ptr, voidpf ptr)
    1.97 +{
    1.98 +   png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
    1.99 +}
   1.100 +
   1.101 +/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
   1.102 + * in case CRC is > 32 bits to leave the top bits 0.
   1.103 + */
   1.104 +void /* PRIVATE */
   1.105 +png_reset_crc(png_structrp png_ptr)
   1.106 +{
   1.107 +   /* The cast is safe because the crc is a 32 bit value. */
   1.108 +   png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
   1.109 +}
   1.110 +
   1.111 +/* Calculate the CRC over a section of data.  We can only pass as
   1.112 + * much data to this routine as the largest single buffer size.  We
   1.113 + * also check that this data will actually be used before going to the
   1.114 + * trouble of calculating it.
   1.115 + */
   1.116 +void /* PRIVATE */
   1.117 +png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
   1.118 +{
   1.119 +   int need_crc = 1;
   1.120 +
   1.121 +   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
   1.122 +   {
   1.123 +      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
   1.124 +          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
   1.125 +         need_crc = 0;
   1.126 +   }
   1.127 +
   1.128 +   else /* critical */
   1.129 +   {
   1.130 +      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
   1.131 +         need_crc = 0;
   1.132 +   }
   1.133 +
   1.134 +   /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
   1.135 +    * systems it is a 64 bit value.  crc32, however, returns 32 bits so the
   1.136 +    * following cast is safe.  'uInt' may be no more than 16 bits, so it is
   1.137 +    * necessary to perform a loop here.
   1.138 +    */
   1.139 +   if (need_crc && length > 0)
   1.140 +   {
   1.141 +      uLong crc = png_ptr->crc; /* Should never issue a warning */
   1.142 +
   1.143 +      do
   1.144 +      {
   1.145 +         uInt safe_length = (uInt)length;
   1.146 +         if (safe_length == 0)
   1.147 +            safe_length = (uInt)-1; /* evil, but safe */
   1.148 +
   1.149 +         crc = crc32(crc, ptr, safe_length);
   1.150 +
   1.151 +         /* The following should never issue compiler warnings; if they do the
   1.152 +          * target system has characteristics that will probably violate other
   1.153 +          * assumptions within the libpng code.
   1.154 +          */
   1.155 +         ptr += safe_length;
   1.156 +         length -= safe_length;
   1.157 +      }
   1.158 +      while (length > 0);
   1.159 +
   1.160 +      /* And the following is always safe because the crc is only 32 bits. */
   1.161 +      png_ptr->crc = (png_uint_32)crc;
   1.162 +   }
   1.163 +}
   1.164 +
   1.165 +/* Check a user supplied version number, called from both read and write
   1.166 + * functions that create a png_struct.
   1.167 + */
   1.168 +int
   1.169 +png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
   1.170 +{
   1.171 +   if (user_png_ver)
   1.172 +   {
   1.173 +      int i = 0;
   1.174 +
   1.175 +      do
   1.176 +      {
   1.177 +         if (user_png_ver[i] != png_libpng_ver[i])
   1.178 +            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
   1.179 +      } while (png_libpng_ver[i++]);
   1.180 +   }
   1.181 +
   1.182 +   else
   1.183 +      png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
   1.184 +
   1.185 +   if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
   1.186 +   {
   1.187 +     /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
   1.188 +      * we must recompile any applications that use any older library version.
   1.189 +      * For versions after libpng 1.0, we will be compatible, so we need
   1.190 +      * only check the first and third digits (note that when we reach version
   1.191 +      * 1.10 we will need to check the fourth symbol, namely user_png_ver[3]).
   1.192 +      */
   1.193 +      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
   1.194 +          (user_png_ver[0] == '1' && (user_png_ver[2] != png_libpng_ver[2] ||
   1.195 +          user_png_ver[3] != png_libpng_ver[3])) ||
   1.196 +          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
   1.197 +      {
   1.198 +#ifdef PNG_WARNINGS_SUPPORTED
   1.199 +         size_t pos = 0;
   1.200 +         char m[128];
   1.201 +
   1.202 +         pos = png_safecat(m, (sizeof m), pos,
   1.203 +             "Application built with libpng-");
   1.204 +         pos = png_safecat(m, (sizeof m), pos, user_png_ver);
   1.205 +         pos = png_safecat(m, (sizeof m), pos, " but running with ");
   1.206 +         pos = png_safecat(m, (sizeof m), pos, png_libpng_ver);
   1.207 +         PNG_UNUSED(pos)
   1.208 +
   1.209 +         png_warning(png_ptr, m);
   1.210 +#endif
   1.211 +
   1.212 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED
   1.213 +         png_ptr->flags = 0;
   1.214 +#endif
   1.215 +
   1.216 +         return 0;
   1.217 +      }
   1.218 +   }
   1.219 +
   1.220 +   /* Success return. */
   1.221 +   return 1;
   1.222 +}
   1.223 +
   1.224 +/* Generic function to create a png_struct for either read or write - this
   1.225 + * contains the common initialization.
   1.226 + */
   1.227 +PNG_FUNCTION(png_structp /* PRIVATE */,
   1.228 +png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
   1.229 +    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
   1.230 +    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
   1.231 +{
   1.232 +   png_struct create_struct;
   1.233 +#  ifdef PNG_SETJMP_SUPPORTED
   1.234 +      jmp_buf create_jmp_buf;
   1.235 +#  endif
   1.236 +
   1.237 +   /* This temporary stack-allocated structure is used to provide a place to
   1.238 +    * build enough context to allow the user provided memory allocator (if any)
   1.239 +    * to be called.
   1.240 +    */
   1.241 +   memset(&create_struct, 0, (sizeof create_struct));
   1.242 +
   1.243 +   /* Added at libpng-1.2.6 */
   1.244 +#  ifdef PNG_USER_LIMITS_SUPPORTED
   1.245 +      create_struct.user_width_max = PNG_USER_WIDTH_MAX;
   1.246 +      create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
   1.247 +
   1.248 +#     ifdef PNG_USER_CHUNK_CACHE_MAX
   1.249 +         /* Added at libpng-1.2.43 and 1.4.0 */
   1.250 +         create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
   1.251 +#     endif
   1.252 +
   1.253 +#     ifdef PNG_USER_CHUNK_MALLOC_MAX
   1.254 +         /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
   1.255 +          * in png_struct regardless.
   1.256 +          */
   1.257 +         create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
   1.258 +#     endif
   1.259 +#  endif
   1.260 +
   1.261 +   /* The following two API calls simply set fields in png_struct, so it is safe
   1.262 +    * to do them now even though error handling is not yet set up.
   1.263 +    */
   1.264 +#  ifdef PNG_USER_MEM_SUPPORTED
   1.265 +      png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
   1.266 +#  else
   1.267 +      PNG_UNUSED(mem_ptr)
   1.268 +      PNG_UNUSED(malloc_fn)
   1.269 +      PNG_UNUSED(free_fn)
   1.270 +#  endif
   1.271 +
   1.272 +   /* (*error_fn) can return control to the caller after the error_ptr is set,
   1.273 +    * this will result in a memory leak unless the error_fn does something
   1.274 +    * extremely sophisticated.  The design lacks merit but is implicit in the
   1.275 +    * API.
   1.276 +    */
   1.277 +   png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
   1.278 +
   1.279 +#  ifdef PNG_SETJMP_SUPPORTED
   1.280 +      if (!setjmp(create_jmp_buf))
   1.281 +      {
   1.282 +         /* Temporarily fake out the longjmp information until we have
   1.283 +          * successfully completed this function.  This only works if we have
   1.284 +          * setjmp() support compiled in, but it is safe - this stuff should
   1.285 +          * never happen.
   1.286 +          */
   1.287 +         create_struct.jmp_buf_ptr = &create_jmp_buf;
   1.288 +         create_struct.jmp_buf_size = 0; /*stack allocation*/
   1.289 +         create_struct.longjmp_fn = longjmp;
   1.290 +#  else
   1.291 +      {
   1.292 +#  endif
   1.293 +         /* Call the general version checker (shared with read and write code):
   1.294 +          */
   1.295 +         if (png_user_version_check(&create_struct, user_png_ver))
   1.296 +         {
   1.297 +            png_structrp png_ptr = png_voidcast(png_structrp,
   1.298 +               png_malloc_warn(&create_struct, (sizeof *png_ptr)));
   1.299 +
   1.300 +            if (png_ptr != NULL)
   1.301 +            {
   1.302 +               /* png_ptr->zstream holds a back-pointer to the png_struct, so
   1.303 +                * this can only be done now:
   1.304 +                */
   1.305 +               create_struct.zstream.zalloc = png_zalloc;
   1.306 +               create_struct.zstream.zfree = png_zfree;
   1.307 +               create_struct.zstream.opaque = png_ptr;
   1.308 +
   1.309 +#              ifdef PNG_SETJMP_SUPPORTED
   1.310 +                  /* Eliminate the local error handling: */
   1.311 +                  create_struct.jmp_buf_ptr = NULL;
   1.312 +                  create_struct.jmp_buf_size = 0;
   1.313 +                  create_struct.longjmp_fn = 0;
   1.314 +#              endif
   1.315 +
   1.316 +               *png_ptr = create_struct;
   1.317 +
   1.318 +               /* This is the successful return point */
   1.319 +               return png_ptr;
   1.320 +            }
   1.321 +         }
   1.322 +      }
   1.323 +
   1.324 +   /* A longjmp because of a bug in the application storage allocator or a
   1.325 +    * simple failure to allocate the png_struct.
   1.326 +    */
   1.327 +   return NULL;
   1.328 +}
   1.329 +
   1.330 +/* Allocate the memory for an info_struct for the application. */
   1.331 +PNG_FUNCTION(png_infop,PNGAPI
   1.332 +png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
   1.333 +{
   1.334 +   png_inforp info_ptr;
   1.335 +
   1.336 +   png_debug(1, "in png_create_info_struct");
   1.337 +
   1.338 +   if (png_ptr == NULL)
   1.339 +      return NULL;
   1.340 +
   1.341 +   /* Use the internal API that does not (or at least should not) error out, so
   1.342 +    * that this call always returns ok.  The application typically sets up the
   1.343 +    * error handling *after* creating the info_struct because this is the way it
   1.344 +    * has always been done in 'example.c'.
   1.345 +    */
   1.346 +   info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
   1.347 +      (sizeof *info_ptr)));
   1.348 +
   1.349 +   if (info_ptr != NULL)
   1.350 +      memset(info_ptr, 0, (sizeof *info_ptr));
   1.351 +
   1.352 +   return info_ptr;
   1.353 +}
   1.354 +
   1.355 +/* This function frees the memory associated with a single info struct.
   1.356 + * Normally, one would use either png_destroy_read_struct() or
   1.357 + * png_destroy_write_struct() to free an info struct, but this may be
   1.358 + * useful for some applications.  From libpng 1.6.0 this function is also used
   1.359 + * internally to implement the png_info release part of the 'struct' destroy
   1.360 + * APIs.  This ensures that all possible approaches free the same data (all of
   1.361 + * it).
   1.362 + */
   1.363 +void PNGAPI
   1.364 +png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
   1.365 +{
   1.366 +   png_inforp info_ptr = NULL;
   1.367 +
   1.368 +   png_debug(1, "in png_destroy_info_struct");
   1.369 +
   1.370 +   if (png_ptr == NULL)
   1.371 +      return;
   1.372 +
   1.373 +   if (info_ptr_ptr != NULL)
   1.374 +      info_ptr = *info_ptr_ptr;
   1.375 +
   1.376 +   if (info_ptr != NULL)
   1.377 +   {
   1.378 +      /* Do this first in case of an error below; if the app implements its own
   1.379 +       * memory management this can lead to png_free calling png_error, which
   1.380 +       * will abort this routine and return control to the app error handler.
   1.381 +       * An infinite loop may result if it then tries to free the same info
   1.382 +       * ptr.
   1.383 +       */
   1.384 +      *info_ptr_ptr = NULL;
   1.385 +
   1.386 +      png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
   1.387 +      memset(info_ptr, 0, (sizeof *info_ptr));
   1.388 +      png_free(png_ptr, info_ptr);
   1.389 +   }
   1.390 +}
   1.391 +
   1.392 +/* Initialize the info structure.  This is now an internal function (0.89)
   1.393 + * and applications using it are urged to use png_create_info_struct()
   1.394 + * instead.  Use deprecated in 1.6.0, internal use removed (used internally it
   1.395 + * is just a memset).
   1.396 + *
   1.397 + * NOTE: it is almost inconceivable that this API is used because it bypasses
   1.398 + * the user-memory mechanism and the user error handling/warning mechanisms in
   1.399 + * those cases where it does anything other than a memset.
   1.400 + */
   1.401 +PNG_FUNCTION(void,PNGAPI
   1.402 +png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
   1.403 +   PNG_DEPRECATED)
   1.404 +{
   1.405 +   png_inforp info_ptr = *ptr_ptr;
   1.406 +
   1.407 +   png_debug(1, "in png_info_init_3");
   1.408 +
   1.409 +   if (info_ptr == NULL)
   1.410 +      return;
   1.411 +
   1.412 +   if ((sizeof (png_info)) > png_info_struct_size)
   1.413 +   {
   1.414 +      *ptr_ptr = NULL;
   1.415 +      /* The following line is why this API should not be used: */
   1.416 +      free(info_ptr);
   1.417 +      info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
   1.418 +         (sizeof *info_ptr)));
   1.419 +      *ptr_ptr = info_ptr;
   1.420 +   }
   1.421 +
   1.422 +   /* Set everything to 0 */
   1.423 +   memset(info_ptr, 0, (sizeof *info_ptr));
   1.424 +}
   1.425 +
   1.426 +/* The following API is not called internally */
   1.427 +void PNGAPI
   1.428 +png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
   1.429 +   int freer, png_uint_32 mask)
   1.430 +{
   1.431 +   png_debug(1, "in png_data_freer");
   1.432 +
   1.433 +   if (png_ptr == NULL || info_ptr == NULL)
   1.434 +      return;
   1.435 +
   1.436 +   if (freer == PNG_DESTROY_WILL_FREE_DATA)
   1.437 +      info_ptr->free_me |= mask;
   1.438 +
   1.439 +   else if (freer == PNG_USER_WILL_FREE_DATA)
   1.440 +      info_ptr->free_me &= ~mask;
   1.441 +
   1.442 +   else
   1.443 +      png_error(png_ptr, "Unknown freer parameter in png_data_freer");
   1.444 +}
   1.445 +
   1.446 +void PNGAPI
   1.447 +png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
   1.448 +   int num)
   1.449 +{
   1.450 +   png_debug(1, "in png_free_data");
   1.451 +
   1.452 +   if (png_ptr == NULL || info_ptr == NULL)
   1.453 +      return;
   1.454 +
   1.455 +#ifdef PNG_TEXT_SUPPORTED
   1.456 +   /* Free text item num or (if num == -1) all text items */
   1.457 +   if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
   1.458 +   {
   1.459 +      if (num != -1)
   1.460 +      {
   1.461 +         if (info_ptr->text && info_ptr->text[num].key)
   1.462 +         {
   1.463 +            png_free(png_ptr, info_ptr->text[num].key);
   1.464 +            info_ptr->text[num].key = NULL;
   1.465 +         }
   1.466 +      }
   1.467 +
   1.468 +      else
   1.469 +      {
   1.470 +         int i;
   1.471 +         for (i = 0; i < info_ptr->num_text; i++)
   1.472 +             png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
   1.473 +         png_free(png_ptr, info_ptr->text);
   1.474 +         info_ptr->text = NULL;
   1.475 +         info_ptr->num_text=0;
   1.476 +      }
   1.477 +   }
   1.478 +#endif
   1.479 +
   1.480 +#ifdef PNG_tRNS_SUPPORTED
   1.481 +   /* Free any tRNS entry */
   1.482 +   if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
   1.483 +   {
   1.484 +      png_free(png_ptr, info_ptr->trans_alpha);
   1.485 +      info_ptr->trans_alpha = NULL;
   1.486 +      info_ptr->valid &= ~PNG_INFO_tRNS;
   1.487 +   }
   1.488 +#endif
   1.489 +
   1.490 +#ifdef PNG_sCAL_SUPPORTED
   1.491 +   /* Free any sCAL entry */
   1.492 +   if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
   1.493 +   {
   1.494 +      png_free(png_ptr, info_ptr->scal_s_width);
   1.495 +      png_free(png_ptr, info_ptr->scal_s_height);
   1.496 +      info_ptr->scal_s_width = NULL;
   1.497 +      info_ptr->scal_s_height = NULL;
   1.498 +      info_ptr->valid &= ~PNG_INFO_sCAL;
   1.499 +   }
   1.500 +#endif
   1.501 +
   1.502 +#ifdef PNG_pCAL_SUPPORTED
   1.503 +   /* Free any pCAL entry */
   1.504 +   if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
   1.505 +   {
   1.506 +      png_free(png_ptr, info_ptr->pcal_purpose);
   1.507 +      png_free(png_ptr, info_ptr->pcal_units);
   1.508 +      info_ptr->pcal_purpose = NULL;
   1.509 +      info_ptr->pcal_units = NULL;
   1.510 +      if (info_ptr->pcal_params != NULL)
   1.511 +         {
   1.512 +            unsigned int i;
   1.513 +            for (i = 0; i < info_ptr->pcal_nparams; i++)
   1.514 +            {
   1.515 +               png_free(png_ptr, info_ptr->pcal_params[i]);
   1.516 +               info_ptr->pcal_params[i] = NULL;
   1.517 +            }
   1.518 +            png_free(png_ptr, info_ptr->pcal_params);
   1.519 +            info_ptr->pcal_params = NULL;
   1.520 +         }
   1.521 +      info_ptr->valid &= ~PNG_INFO_pCAL;
   1.522 +   }
   1.523 +#endif
   1.524 +
   1.525 +#ifdef PNG_iCCP_SUPPORTED
   1.526 +   /* Free any profile entry */
   1.527 +   if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
   1.528 +   {
   1.529 +      png_free(png_ptr, info_ptr->iccp_name);
   1.530 +      png_free(png_ptr, info_ptr->iccp_profile);
   1.531 +      info_ptr->iccp_name = NULL;
   1.532 +      info_ptr->iccp_profile = NULL;
   1.533 +      info_ptr->valid &= ~PNG_INFO_iCCP;
   1.534 +   }
   1.535 +#endif
   1.536 +
   1.537 +#ifdef PNG_sPLT_SUPPORTED
   1.538 +   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
   1.539 +   if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
   1.540 +   {
   1.541 +      if (num != -1)
   1.542 +      {
   1.543 +         if (info_ptr->splt_palettes)
   1.544 +         {
   1.545 +            png_free(png_ptr, info_ptr->splt_palettes[num].name);
   1.546 +            png_free(png_ptr, info_ptr->splt_palettes[num].entries);
   1.547 +            info_ptr->splt_palettes[num].name = NULL;
   1.548 +            info_ptr->splt_palettes[num].entries = NULL;
   1.549 +         }
   1.550 +      }
   1.551 +
   1.552 +      else
   1.553 +      {
   1.554 +         if (info_ptr->splt_palettes_num)
   1.555 +         {
   1.556 +            int i;
   1.557 +            for (i = 0; i < info_ptr->splt_palettes_num; i++)
   1.558 +               png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, (int)i);
   1.559 +
   1.560 +            png_free(png_ptr, info_ptr->splt_palettes);
   1.561 +            info_ptr->splt_palettes = NULL;
   1.562 +            info_ptr->splt_palettes_num = 0;
   1.563 +         }
   1.564 +         info_ptr->valid &= ~PNG_INFO_sPLT;
   1.565 +      }
   1.566 +   }
   1.567 +#endif
   1.568 +
   1.569 +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
   1.570 +   if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
   1.571 +   {
   1.572 +      if (num != -1)
   1.573 +      {
   1.574 +          if (info_ptr->unknown_chunks)
   1.575 +          {
   1.576 +             png_free(png_ptr, info_ptr->unknown_chunks[num].data);
   1.577 +             info_ptr->unknown_chunks[num].data = NULL;
   1.578 +          }
   1.579 +      }
   1.580 +
   1.581 +      else
   1.582 +      {
   1.583 +         int i;
   1.584 +
   1.585 +         if (info_ptr->unknown_chunks_num)
   1.586 +         {
   1.587 +            for (i = 0; i < info_ptr->unknown_chunks_num; i++)
   1.588 +               png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, (int)i);
   1.589 +
   1.590 +            png_free(png_ptr, info_ptr->unknown_chunks);
   1.591 +            info_ptr->unknown_chunks = NULL;
   1.592 +            info_ptr->unknown_chunks_num = 0;
   1.593 +         }
   1.594 +      }
   1.595 +   }
   1.596 +#endif
   1.597 +
   1.598 +#ifdef PNG_hIST_SUPPORTED
   1.599 +   /* Free any hIST entry */
   1.600 +   if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
   1.601 +   {
   1.602 +      png_free(png_ptr, info_ptr->hist);
   1.603 +      info_ptr->hist = NULL;
   1.604 +      info_ptr->valid &= ~PNG_INFO_hIST;
   1.605 +   }
   1.606 +#endif
   1.607 +
   1.608 +   /* Free any PLTE entry that was internally allocated */
   1.609 +   if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
   1.610 +   {
   1.611 +      png_free(png_ptr, info_ptr->palette);
   1.612 +      info_ptr->palette = NULL;
   1.613 +      info_ptr->valid &= ~PNG_INFO_PLTE;
   1.614 +      info_ptr->num_palette = 0;
   1.615 +   }
   1.616 +
   1.617 +#ifdef PNG_INFO_IMAGE_SUPPORTED
   1.618 +   /* Free any image bits attached to the info structure */
   1.619 +   if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
   1.620 +   {
   1.621 +      if (info_ptr->row_pointers)
   1.622 +      {
   1.623 +         png_uint_32 row;
   1.624 +         for (row = 0; row < info_ptr->height; row++)
   1.625 +         {
   1.626 +            png_free(png_ptr, info_ptr->row_pointers[row]);
   1.627 +            info_ptr->row_pointers[row] = NULL;
   1.628 +         }
   1.629 +         png_free(png_ptr, info_ptr->row_pointers);
   1.630 +         info_ptr->row_pointers = NULL;
   1.631 +      }
   1.632 +      info_ptr->valid &= ~PNG_INFO_IDAT;
   1.633 +   }
   1.634 +#endif
   1.635 +
   1.636 +   if (num != -1)
   1.637 +      mask &= ~PNG_FREE_MUL;
   1.638 +
   1.639 +   info_ptr->free_me &= ~mask;
   1.640 +}
   1.641 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
   1.642 +
   1.643 +/* This function returns a pointer to the io_ptr associated with the user
   1.644 + * functions.  The application should free any memory associated with this
   1.645 + * pointer before png_write_destroy() or png_read_destroy() are called.
   1.646 + */
   1.647 +png_voidp PNGAPI
   1.648 +png_get_io_ptr(png_const_structrp png_ptr)
   1.649 +{
   1.650 +   if (png_ptr == NULL)
   1.651 +      return (NULL);
   1.652 +
   1.653 +   return (png_ptr->io_ptr);
   1.654 +}
   1.655 +
   1.656 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
   1.657 +#  ifdef PNG_STDIO_SUPPORTED
   1.658 +/* Initialize the default input/output functions for the PNG file.  If you
   1.659 + * use your own read or write routines, you can call either png_set_read_fn()
   1.660 + * or png_set_write_fn() instead of png_init_io().  If you have defined
   1.661 + * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
   1.662 + * function of your own because "FILE *" isn't necessarily available.
   1.663 + */
   1.664 +void PNGAPI
   1.665 +png_init_io(png_structrp png_ptr, png_FILE_p fp)
   1.666 +{
   1.667 +   png_debug(1, "in png_init_io");
   1.668 +
   1.669 +   if (png_ptr == NULL)
   1.670 +      return;
   1.671 +
   1.672 +   png_ptr->io_ptr = (png_voidp)fp;
   1.673 +}
   1.674 +#  endif
   1.675 +
   1.676 +#ifdef PNG_SAVE_INT_32_SUPPORTED
   1.677 +/* The png_save_int_32 function assumes integers are stored in two's
   1.678 + * complement format.  If this isn't the case, then this routine needs to
   1.679 + * be modified to write data in two's complement format.  Note that,
   1.680 + * the following works correctly even if png_int_32 has more than 32 bits
   1.681 + * (compare the more complex code required on read for sign extension.)
   1.682 + */
   1.683 +void PNGAPI
   1.684 +png_save_int_32(png_bytep buf, png_int_32 i)
   1.685 +{
   1.686 +   buf[0] = (png_byte)((i >> 24) & 0xff);
   1.687 +   buf[1] = (png_byte)((i >> 16) & 0xff);
   1.688 +   buf[2] = (png_byte)((i >> 8) & 0xff);
   1.689 +   buf[3] = (png_byte)(i & 0xff);
   1.690 +}
   1.691 +#endif
   1.692 +
   1.693 +#  ifdef PNG_TIME_RFC1123_SUPPORTED
   1.694 +/* Convert the supplied time into an RFC 1123 string suitable for use in
   1.695 + * a "Creation Time" or other text-based time string.
   1.696 + */
   1.697 +int PNGAPI
   1.698 +png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
   1.699 +{
   1.700 +   static PNG_CONST char short_months[12][4] =
   1.701 +        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
   1.702 +         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
   1.703 +
   1.704 +   if (out == NULL)
   1.705 +      return 0;
   1.706 +
   1.707 +   if (ptime->year > 9999 /* RFC1123 limitation */ ||
   1.708 +       ptime->month == 0    ||  ptime->month > 12  ||
   1.709 +       ptime->day   == 0    ||  ptime->day   > 31  ||
   1.710 +       ptime->hour  > 23    ||  ptime->minute > 59 ||
   1.711 +       ptime->second > 60)
   1.712 +      return 0;
   1.713 +
   1.714 +   {
   1.715 +      size_t pos = 0;
   1.716 +      char number_buf[5]; /* enough for a four-digit year */
   1.717 +
   1.718 +#     define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
   1.719 +#     define APPEND_NUMBER(format, value)\
   1.720 +         APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
   1.721 +#     define APPEND(ch) if (pos < 28) out[pos++] = (ch)
   1.722 +
   1.723 +      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
   1.724 +      APPEND(' ');
   1.725 +      APPEND_STRING(short_months[(ptime->month - 1)]);
   1.726 +      APPEND(' ');
   1.727 +      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
   1.728 +      APPEND(' ');
   1.729 +      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
   1.730 +      APPEND(':');
   1.731 +      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
   1.732 +      APPEND(':');
   1.733 +      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
   1.734 +      APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
   1.735 +
   1.736 +#     undef APPEND
   1.737 +#     undef APPEND_NUMBER
   1.738 +#     undef APPEND_STRING
   1.739 +   }
   1.740 +
   1.741 +   return 1;
   1.742 +}
   1.743 +
   1.744 +#     if PNG_LIBPNG_VER < 10700
   1.745 +/* To do: remove the following from libpng-1.7 */
   1.746 +/* Original API that uses a private buffer in png_struct.
   1.747 + * Deprecated because it causes png_struct to carry a spurious temporary
   1.748 + * buffer (png_struct::time_buffer), better to have the caller pass this in.
   1.749 + */
   1.750 +png_const_charp PNGAPI
   1.751 +png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
   1.752 +{
   1.753 +   if (png_ptr != NULL)
   1.754 +   {
   1.755 +      /* The only failure above if png_ptr != NULL is from an invalid ptime */
   1.756 +      if (!png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime))
   1.757 +         png_warning(png_ptr, "Ignoring invalid time value");
   1.758 +
   1.759 +      else
   1.760 +         return png_ptr->time_buffer;
   1.761 +   }
   1.762 +
   1.763 +   return NULL;
   1.764 +}
   1.765 +#     endif
   1.766 +#  endif /* PNG_TIME_RFC1123_SUPPORTED */
   1.767 +
   1.768 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
   1.769 +
   1.770 +png_const_charp PNGAPI
   1.771 +png_get_copyright(png_const_structrp png_ptr)
   1.772 +{
   1.773 +   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
   1.774 +#ifdef PNG_STRING_COPYRIGHT
   1.775 +   return PNG_STRING_COPYRIGHT
   1.776 +#else
   1.777 +#  ifdef __STDC__
   1.778 +   return PNG_STRING_NEWLINE \
   1.779 +     "libpng version 1.6.10 - March 6, 2014" PNG_STRING_NEWLINE \
   1.780 +     "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
   1.781 +     "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
   1.782 +     "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
   1.783 +     PNG_STRING_NEWLINE;
   1.784 +#  else
   1.785 +      return "libpng version 1.6.10 - March 6, 2014\
   1.786 +      Copyright (c) 1998-2014 Glenn Randers-Pehrson\
   1.787 +      Copyright (c) 1996-1997 Andreas Dilger\
   1.788 +      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
   1.789 +#  endif
   1.790 +#endif
   1.791 +}
   1.792 +
   1.793 +/* The following return the library version as a short string in the
   1.794 + * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
   1.795 + * used with your application, print out PNG_LIBPNG_VER_STRING, which
   1.796 + * is defined in png.h.
   1.797 + * Note: now there is no difference between png_get_libpng_ver() and
   1.798 + * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
   1.799 + * it is guaranteed that png.c uses the correct version of png.h.
   1.800 + */
   1.801 +png_const_charp PNGAPI
   1.802 +png_get_libpng_ver(png_const_structrp png_ptr)
   1.803 +{
   1.804 +   /* Version of *.c files used when building libpng */
   1.805 +   return png_get_header_ver(png_ptr);
   1.806 +}
   1.807 +
   1.808 +png_const_charp PNGAPI
   1.809 +png_get_header_ver(png_const_structrp png_ptr)
   1.810 +{
   1.811 +   /* Version of *.h files used when building libpng */
   1.812 +   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
   1.813 +   return PNG_LIBPNG_VER_STRING;
   1.814 +}
   1.815 +
   1.816 +png_const_charp PNGAPI
   1.817 +png_get_header_version(png_const_structrp png_ptr)
   1.818 +{
   1.819 +   /* Returns longer string containing both version and date */
   1.820 +   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
   1.821 +#ifdef __STDC__
   1.822 +   return PNG_HEADER_VERSION_STRING
   1.823 +#  ifndef PNG_READ_SUPPORTED
   1.824 +   "     (NO READ SUPPORT)"
   1.825 +#  endif
   1.826 +   PNG_STRING_NEWLINE;
   1.827 +#else
   1.828 +   return PNG_HEADER_VERSION_STRING;
   1.829 +#endif
   1.830 +}
   1.831 +
   1.832 +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
   1.833 +/* NOTE: this routine is not used internally! */
   1.834 +/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
   1.835 + * large of png_color.  This lets grayscale images be treated as
   1.836 + * paletted.  Most useful for gamma correction and simplification
   1.837 + * of code.  This API is not used internally.
   1.838 + */
   1.839 +void PNGAPI
   1.840 +png_build_grayscale_palette(int bit_depth, png_colorp palette)
   1.841 +{
   1.842 +   int num_palette;
   1.843 +   int color_inc;
   1.844 +   int i;
   1.845 +   int v;
   1.846 +
   1.847 +   png_debug(1, "in png_do_build_grayscale_palette");
   1.848 +
   1.849 +   if (palette == NULL)
   1.850 +      return;
   1.851 +
   1.852 +   switch (bit_depth)
   1.853 +   {
   1.854 +      case 1:
   1.855 +         num_palette = 2;
   1.856 +         color_inc = 0xff;
   1.857 +         break;
   1.858 +
   1.859 +      case 2:
   1.860 +         num_palette = 4;
   1.861 +         color_inc = 0x55;
   1.862 +         break;
   1.863 +
   1.864 +      case 4:
   1.865 +         num_palette = 16;
   1.866 +         color_inc = 0x11;
   1.867 +         break;
   1.868 +
   1.869 +      case 8:
   1.870 +         num_palette = 256;
   1.871 +         color_inc = 1;
   1.872 +         break;
   1.873 +
   1.874 +      default:
   1.875 +         num_palette = 0;
   1.876 +         color_inc = 0;
   1.877 +         break;
   1.878 +   }
   1.879 +
   1.880 +   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
   1.881 +   {
   1.882 +      palette[i].red = (png_byte)v;
   1.883 +      palette[i].green = (png_byte)v;
   1.884 +      palette[i].blue = (png_byte)v;
   1.885 +   }
   1.886 +}
   1.887 +#endif
   1.888 +
   1.889 +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
   1.890 +int PNGAPI
   1.891 +png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
   1.892 +{
   1.893 +   /* Check chunk_name and return "keep" value if it's on the list, else 0 */
   1.894 +   png_const_bytep p, p_end;
   1.895 +
   1.896 +   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
   1.897 +      return PNG_HANDLE_CHUNK_AS_DEFAULT;
   1.898 +
   1.899 +   p_end = png_ptr->chunk_list;
   1.900 +   p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
   1.901 +
   1.902 +   /* The code is the fifth byte after each four byte string.  Historically this
   1.903 +    * code was always searched from the end of the list, this is no longer
   1.904 +    * necessary because the 'set' routine handles duplicate entries correcty.
   1.905 +    */
   1.906 +   do /* num_chunk_list > 0, so at least one */
   1.907 +   {
   1.908 +      p -= 5;
   1.909 +
   1.910 +      if (!memcmp(chunk_name, p, 4))
   1.911 +         return p[4];
   1.912 +   }
   1.913 +   while (p > p_end);
   1.914 +
   1.915 +   /* This means that known chunks should be processed and unknown chunks should
   1.916 +    * be handled according to the value of png_ptr->unknown_default; this can be
   1.917 +    * confusing because, as a result, there are two levels of defaulting for
   1.918 +    * unknown chunks.
   1.919 +    */
   1.920 +   return PNG_HANDLE_CHUNK_AS_DEFAULT;
   1.921 +}
   1.922 +
   1.923 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
   1.924 +   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
   1.925 +int /* PRIVATE */
   1.926 +png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
   1.927 +{
   1.928 +   png_byte chunk_string[5];
   1.929 +
   1.930 +   PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
   1.931 +   return png_handle_as_unknown(png_ptr, chunk_string);
   1.932 +}
   1.933 +#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
   1.934 +#endif /* SET_UNKNOWN_CHUNKS */
   1.935 +
   1.936 +#ifdef PNG_READ_SUPPORTED
   1.937 +/* This function, added to libpng-1.0.6g, is untested. */
   1.938 +int PNGAPI
   1.939 +png_reset_zstream(png_structrp png_ptr)
   1.940 +{
   1.941 +   if (png_ptr == NULL)
   1.942 +      return Z_STREAM_ERROR;
   1.943 +
   1.944 +   /* WARNING: this resets the window bits to the maximum! */
   1.945 +   return (inflateReset(&png_ptr->zstream));
   1.946 +}
   1.947 +#endif /* PNG_READ_SUPPORTED */
   1.948 +
   1.949 +/* This function was added to libpng-1.0.7 */
   1.950 +png_uint_32 PNGAPI
   1.951 +png_access_version_number(void)
   1.952 +{
   1.953 +   /* Version of *.c files used when building libpng */
   1.954 +   return((png_uint_32)PNG_LIBPNG_VER);
   1.955 +}
   1.956 +
   1.957 +
   1.958 +
   1.959 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
   1.960 +/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
   1.961 + * If it doesn't 'ret' is used to set it to something appropriate, even in cases
   1.962 + * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
   1.963 + */
   1.964 +void /* PRIVATE */
   1.965 +png_zstream_error(png_structrp png_ptr, int ret)
   1.966 +{
   1.967 +   /* Translate 'ret' into an appropriate error string, priority is given to the
   1.968 +    * one in zstream if set.  This always returns a string, even in cases like
   1.969 +    * Z_OK or Z_STREAM_END where the error code is a success code.
   1.970 +    */
   1.971 +   if (png_ptr->zstream.msg == NULL) switch (ret)
   1.972 +   {
   1.973 +      default:
   1.974 +      case Z_OK:
   1.975 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
   1.976 +         break;
   1.977 +
   1.978 +      case Z_STREAM_END:
   1.979 +         /* Normal exit */
   1.980 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
   1.981 +         break;
   1.982 +
   1.983 +      case Z_NEED_DICT:
   1.984 +         /* This means the deflate stream did not have a dictionary; this
   1.985 +          * indicates a bogus PNG.
   1.986 +          */
   1.987 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
   1.988 +         break;
   1.989 +
   1.990 +      case Z_ERRNO:
   1.991 +         /* gz APIs only: should not happen */
   1.992 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
   1.993 +         break;
   1.994 +
   1.995 +      case Z_STREAM_ERROR:
   1.996 +         /* internal libpng error */
   1.997 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
   1.998 +         break;
   1.999 +
  1.1000 +      case Z_DATA_ERROR:
  1.1001 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
  1.1002 +         break;
  1.1003 +
  1.1004 +      case Z_MEM_ERROR:
  1.1005 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
  1.1006 +         break;
  1.1007 +
  1.1008 +      case Z_BUF_ERROR:
  1.1009 +         /* End of input or output; not a problem if the caller is doing
  1.1010 +          * incremental read or write.
  1.1011 +          */
  1.1012 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
  1.1013 +         break;
  1.1014 +
  1.1015 +      case Z_VERSION_ERROR:
  1.1016 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
  1.1017 +         break;
  1.1018 +
  1.1019 +      case PNG_UNEXPECTED_ZLIB_RETURN:
  1.1020 +         /* Compile errors here mean that zlib now uses the value co-opted in
  1.1021 +          * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
  1.1022 +          * and change pngpriv.h.  Note that this message is "... return",
  1.1023 +          * whereas the default/Z_OK one is "... return code".
  1.1024 +          */
  1.1025 +         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
  1.1026 +         break;
  1.1027 +   }
  1.1028 +}
  1.1029 +
  1.1030 +/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
  1.1031 + * at libpng 1.5.5!
  1.1032 + */
  1.1033 +
  1.1034 +/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
  1.1035 +#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
  1.1036 +static int
  1.1037 +png_colorspace_check_gamma(png_const_structrp png_ptr,
  1.1038 +   png_colorspacerp colorspace, png_fixed_point gAMA, int from)
  1.1039 +   /* This is called to check a new gamma value against an existing one.  The
  1.1040 +    * routine returns false if the new gamma value should not be written.
  1.1041 +    *
  1.1042 +    * 'from' says where the new gamma value comes from:
  1.1043 +    *
  1.1044 +    *    0: the new gamma value is the libpng estimate for an ICC profile
  1.1045 +    *    1: the new gamma value comes from a gAMA chunk
  1.1046 +    *    2: the new gamma value comes from an sRGB chunk
  1.1047 +    */
  1.1048 +{
  1.1049 +   png_fixed_point gtest;
  1.1050 +
  1.1051 +   if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
  1.1052 +      (!png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) ||
  1.1053 +      png_gamma_significant(gtest)))
  1.1054 +   {
  1.1055 +      /* Either this is an sRGB image, in which case the calculated gamma
  1.1056 +       * approximation should match, or this is an image with a profile and the
  1.1057 +       * value libpng calculates for the gamma of the profile does not match the
  1.1058 +       * value recorded in the file.  The former, sRGB, case is an error, the
  1.1059 +       * latter is just a warning.
  1.1060 +       */
  1.1061 +      if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
  1.1062 +      {
  1.1063 +         png_chunk_report(png_ptr, "gamma value does not match sRGB",
  1.1064 +            PNG_CHUNK_ERROR);
  1.1065 +         /* Do not overwrite an sRGB value */
  1.1066 +         return from == 2;
  1.1067 +      }
  1.1068 +
  1.1069 +      else /* sRGB tag not involved */
  1.1070 +      {
  1.1071 +         png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
  1.1072 +            PNG_CHUNK_WARNING);
  1.1073 +         return from == 1;
  1.1074 +      }
  1.1075 +   }
  1.1076 +
  1.1077 +   return 1;
  1.1078 +}
  1.1079 +
  1.1080 +void /* PRIVATE */
  1.1081 +png_colorspace_set_gamma(png_const_structrp png_ptr,
  1.1082 +   png_colorspacerp colorspace, png_fixed_point gAMA)
  1.1083 +{
  1.1084 +   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
  1.1085 +    * occur.  Since the fixed point representation is assymetrical it is
  1.1086 +    * possible for 1/gamma to overflow the limit of 21474 and this means the
  1.1087 +    * gamma value must be at least 5/100000 and hence at most 20000.0.  For
  1.1088 +    * safety the limits here are a little narrower.  The values are 0.00016 to
  1.1089 +    * 6250.0, which are truly ridiculous gamma values (and will produce
  1.1090 +    * displays that are all black or all white.)
  1.1091 +    *
  1.1092 +    * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
  1.1093 +    * handling code, which only required the value to be >0.
  1.1094 +    */
  1.1095 +   png_const_charp errmsg;
  1.1096 +
  1.1097 +   if (gAMA < 16 || gAMA > 625000000)
  1.1098 +      errmsg = "gamma value out of range";
  1.1099 +
  1.1100 +#  ifdef PNG_READ_gAMA_SUPPORTED
  1.1101 +      /* Allow the application to set the gamma value more than once */
  1.1102 +      else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
  1.1103 +         (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
  1.1104 +         errmsg = "duplicate";
  1.1105 +#  endif
  1.1106 +
  1.1107 +   /* Do nothing if the colorspace is already invalid */
  1.1108 +   else if (colorspace->flags & PNG_COLORSPACE_INVALID)
  1.1109 +      return;
  1.1110 +
  1.1111 +   else
  1.1112 +   {
  1.1113 +      if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, 1/*from gAMA*/))
  1.1114 +      {
  1.1115 +         /* Store this gamma value. */
  1.1116 +         colorspace->gamma = gAMA;
  1.1117 +         colorspace->flags |=
  1.1118 +            (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
  1.1119 +      }
  1.1120 +
  1.1121 +      /* At present if the check_gamma test fails the gamma of the colorspace is
  1.1122 +       * not updated however the colorspace is not invalidated.  This
  1.1123 +       * corresponds to the case where the existing gamma comes from an sRGB
  1.1124 +       * chunk or profile.  An error message has already been output.
  1.1125 +       */
  1.1126 +      return;
  1.1127 +   }
  1.1128 +
  1.1129 +   /* Error exit - errmsg has been set. */
  1.1130 +   colorspace->flags |= PNG_COLORSPACE_INVALID;
  1.1131 +   png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
  1.1132 +}
  1.1133 +
  1.1134 +void /* PRIVATE */
  1.1135 +png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
  1.1136 +{
  1.1137 +   if (info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
  1.1138 +   {
  1.1139 +      /* Everything is invalid */
  1.1140 +      info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
  1.1141 +         PNG_INFO_iCCP);
  1.1142 +
  1.1143 +#     ifdef PNG_COLORSPACE_SUPPORTED
  1.1144 +         /* Clean up the iCCP profile now if it won't be used. */
  1.1145 +         png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
  1.1146 +#     else
  1.1147 +         PNG_UNUSED(png_ptr)
  1.1148 +#     endif
  1.1149 +   }
  1.1150 +
  1.1151 +   else
  1.1152 +   {
  1.1153 +#     ifdef PNG_COLORSPACE_SUPPORTED
  1.1154 +         /* Leave the INFO_iCCP flag set if the pngset.c code has already set
  1.1155 +          * it; this allows a PNG to contain a profile which matches sRGB and
  1.1156 +          * yet still have that profile retrievable by the application.
  1.1157 +          */
  1.1158 +         if (info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB)
  1.1159 +            info_ptr->valid |= PNG_INFO_sRGB;
  1.1160 +
  1.1161 +         else
  1.1162 +            info_ptr->valid &= ~PNG_INFO_sRGB;
  1.1163 +
  1.1164 +         if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)
  1.1165 +            info_ptr->valid |= PNG_INFO_cHRM;
  1.1166 +
  1.1167 +         else
  1.1168 +            info_ptr->valid &= ~PNG_INFO_cHRM;
  1.1169 +#     endif
  1.1170 +
  1.1171 +      if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA)
  1.1172 +         info_ptr->valid |= PNG_INFO_gAMA;
  1.1173 +
  1.1174 +      else
  1.1175 +         info_ptr->valid &= ~PNG_INFO_gAMA;
  1.1176 +   }
  1.1177 +}
  1.1178 +
  1.1179 +#ifdef PNG_READ_SUPPORTED
  1.1180 +void /* PRIVATE */
  1.1181 +png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
  1.1182 +{
  1.1183 +   if (info_ptr == NULL) /* reduce code size; check here not in the caller */
  1.1184 +      return;
  1.1185 +
  1.1186 +   info_ptr->colorspace = png_ptr->colorspace;
  1.1187 +   png_colorspace_sync_info(png_ptr, info_ptr);
  1.1188 +}
  1.1189 +#endif
  1.1190 +#endif
  1.1191 +
  1.1192 +#ifdef PNG_COLORSPACE_SUPPORTED
  1.1193 +/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
  1.1194 + * cHRM, as opposed to using chromaticities.  These internal APIs return
  1.1195 + * non-zero on a parameter error.  The X, Y and Z values are required to be
  1.1196 + * positive and less than 1.0.
  1.1197 + */
  1.1198 +static int
  1.1199 +png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
  1.1200 +{
  1.1201 +   png_int_32 d, dwhite, whiteX, whiteY;
  1.1202 +
  1.1203 +   d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
  1.1204 +   if (!png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d)) return 1;
  1.1205 +   if (!png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d)) return 1;
  1.1206 +   dwhite = d;
  1.1207 +   whiteX = XYZ->red_X;
  1.1208 +   whiteY = XYZ->red_Y;
  1.1209 +
  1.1210 +   d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
  1.1211 +   if (!png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d)) return 1;
  1.1212 +   if (!png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d)) return 1;
  1.1213 +   dwhite += d;
  1.1214 +   whiteX += XYZ->green_X;
  1.1215 +   whiteY += XYZ->green_Y;
  1.1216 +
  1.1217 +   d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
  1.1218 +   if (!png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d)) return 1;
  1.1219 +   if (!png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d)) return 1;
  1.1220 +   dwhite += d;
  1.1221 +   whiteX += XYZ->blue_X;
  1.1222 +   whiteY += XYZ->blue_Y;
  1.1223 +
  1.1224 +   /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
  1.1225 +    * thus:
  1.1226 +    */
  1.1227 +   if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1;
  1.1228 +   if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1;
  1.1229 +
  1.1230 +   return 0;
  1.1231 +}
  1.1232 +
  1.1233 +static int
  1.1234 +png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
  1.1235 +{
  1.1236 +   png_fixed_point red_inverse, green_inverse, blue_scale;
  1.1237 +   png_fixed_point left, right, denominator;
  1.1238 +
  1.1239 +   /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically
  1.1240 +    * have end points with 0 tristimulus values (these are impossible end
  1.1241 +    * points, but they are used to cover the possible colors.)
  1.1242 +    */
  1.1243 +   if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
  1.1244 +   if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
  1.1245 +   if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
  1.1246 +   if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
  1.1247 +   if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
  1.1248 +   if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
  1.1249 +   if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
  1.1250 +   if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
  1.1251 +
  1.1252 +   /* The reverse calculation is more difficult because the original tristimulus
  1.1253 +    * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
  1.1254 +    * derived values were recorded in the cHRM chunk;
  1.1255 +    * (red,green,blue,white)x(x,y).  This loses one degree of freedom and
  1.1256 +    * therefore an arbitrary ninth value has to be introduced to undo the
  1.1257 +    * original transformations.
  1.1258 +    *
  1.1259 +    * Think of the original end-points as points in (X,Y,Z) space.  The
  1.1260 +    * chromaticity values (c) have the property:
  1.1261 +    *
  1.1262 +    *           C
  1.1263 +    *   c = ---------
  1.1264 +    *       X + Y + Z
  1.1265 +    *
  1.1266 +    * For each c (x,y,z) from the corresponding original C (X,Y,Z).  Thus the
  1.1267 +    * three chromaticity values (x,y,z) for each end-point obey the
  1.1268 +    * relationship:
  1.1269 +    *
  1.1270 +    *   x + y + z = 1
  1.1271 +    *
  1.1272 +    * This describes the plane in (X,Y,Z) space that intersects each axis at the
  1.1273 +    * value 1.0; call this the chromaticity plane.  Thus the chromaticity
  1.1274 +    * calculation has scaled each end-point so that it is on the x+y+z=1 plane
  1.1275 +    * and chromaticity is the intersection of the vector from the origin to the
  1.1276 +    * (X,Y,Z) value with the chromaticity plane.
  1.1277 +    *
  1.1278 +    * To fully invert the chromaticity calculation we would need the three
  1.1279 +    * end-point scale factors, (red-scale, green-scale, blue-scale), but these
  1.1280 +    * were not recorded.  Instead we calculated the reference white (X,Y,Z) and
  1.1281 +    * recorded the chromaticity of this.  The reference white (X,Y,Z) would have
  1.1282 +    * given all three of the scale factors since:
  1.1283 +    *
  1.1284 +    *    color-C = color-c * color-scale
  1.1285 +    *    white-C = red-C + green-C + blue-C
  1.1286 +    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
  1.1287 +    *
  1.1288 +    * But cHRM records only white-x and white-y, so we have lost the white scale
  1.1289 +    * factor:
  1.1290 +    *
  1.1291 +    *    white-C = white-c*white-scale
  1.1292 +    *
  1.1293 +    * To handle this the inverse transformation makes an arbitrary assumption
  1.1294 +    * about white-scale:
  1.1295 +    *
  1.1296 +    *    Assume: white-Y = 1.0
  1.1297 +    *    Hence:  white-scale = 1/white-y
  1.1298 +    *    Or:     red-Y + green-Y + blue-Y = 1.0
  1.1299 +    *
  1.1300 +    * Notice the last statement of the assumption gives an equation in three of
  1.1301 +    * the nine values we want to calculate.  8 more equations come from the
  1.1302 +    * above routine as summarised at the top above (the chromaticity
  1.1303 +    * calculation):
  1.1304 +    *
  1.1305 +    *    Given: color-x = color-X / (color-X + color-Y + color-Z)
  1.1306 +    *    Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
  1.1307 +    *
  1.1308 +    * This is 9 simultaneous equations in the 9 variables "color-C" and can be
  1.1309 +    * solved by Cramer's rule.  Cramer's rule requires calculating 10 9x9 matrix
  1.1310 +    * determinants, however this is not as bad as it seems because only 28 of
  1.1311 +    * the total of 90 terms in the various matrices are non-zero.  Nevertheless
  1.1312 +    * Cramer's rule is notoriously numerically unstable because the determinant
  1.1313 +    * calculation involves the difference of large, but similar, numbers.  It is
  1.1314 +    * difficult to be sure that the calculation is stable for real world values
  1.1315 +    * and it is certain that it becomes unstable where the end points are close
  1.1316 +    * together.
  1.1317 +    *
  1.1318 +    * So this code uses the perhaps slightly less optimal but more
  1.1319 +    * understandable and totally obvious approach of calculating color-scale.
  1.1320 +    *
  1.1321 +    * This algorithm depends on the precision in white-scale and that is
  1.1322 +    * (1/white-y), so we can immediately see that as white-y approaches 0 the
  1.1323 +    * accuracy inherent in the cHRM chunk drops off substantially.
  1.1324 +    *
  1.1325 +    * libpng arithmetic: a simple invertion of the above equations
  1.1326 +    * ------------------------------------------------------------
  1.1327 +    *
  1.1328 +    *    white_scale = 1/white-y
  1.1329 +    *    white-X = white-x * white-scale
  1.1330 +    *    white-Y = 1.0
  1.1331 +    *    white-Z = (1 - white-x - white-y) * white_scale
  1.1332 +    *
  1.1333 +    *    white-C = red-C + green-C + blue-C
  1.1334 +    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
  1.1335 +    *
  1.1336 +    * This gives us three equations in (red-scale,green-scale,blue-scale) where
  1.1337 +    * all the coefficients are now known:
  1.1338 +    *
  1.1339 +    *    red-x*red-scale + green-x*green-scale + blue-x*blue-scale
  1.1340 +    *       = white-x/white-y
  1.1341 +    *    red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
  1.1342 +    *    red-z*red-scale + green-z*green-scale + blue-z*blue-scale
  1.1343 +    *       = (1 - white-x - white-y)/white-y
  1.1344 +    *
  1.1345 +    * In the last equation color-z is (1 - color-x - color-y) so we can add all
  1.1346 +    * three equations together to get an alternative third:
  1.1347 +    *
  1.1348 +    *    red-scale + green-scale + blue-scale = 1/white-y = white-scale
  1.1349 +    *
  1.1350 +    * So now we have a Cramer's rule solution where the determinants are just
  1.1351 +    * 3x3 - far more tractible.  Unfortunately 3x3 determinants still involve
  1.1352 +    * multiplication of three coefficients so we can't guarantee to avoid
  1.1353 +    * overflow in the libpng fixed point representation.  Using Cramer's rule in
  1.1354 +    * floating point is probably a good choice here, but it's not an option for
  1.1355 +    * fixed point.  Instead proceed to simplify the first two equations by
  1.1356 +    * eliminating what is likely to be the largest value, blue-scale:
  1.1357 +    *
  1.1358 +    *    blue-scale = white-scale - red-scale - green-scale
  1.1359 +    *
  1.1360 +    * Hence:
  1.1361 +    *
  1.1362 +    *    (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
  1.1363 +    *                (white-x - blue-x)*white-scale
  1.1364 +    *
  1.1365 +    *    (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
  1.1366 +    *                1 - blue-y*white-scale
  1.1367 +    *
  1.1368 +    * And now we can trivially solve for (red-scale,green-scale):
  1.1369 +    *
  1.1370 +    *    green-scale =
  1.1371 +    *                (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
  1.1372 +    *                -----------------------------------------------------------
  1.1373 +    *                                  green-x - blue-x
  1.1374 +    *
  1.1375 +    *    red-scale =
  1.1376 +    *                1 - blue-y*white-scale - (green-y - blue-y) * green-scale
  1.1377 +    *                ---------------------------------------------------------
  1.1378 +    *                                  red-y - blue-y
  1.1379 +    *
  1.1380 +    * Hence:
  1.1381 +    *
  1.1382 +    *    red-scale =
  1.1383 +    *          ( (green-x - blue-x) * (white-y - blue-y) -
  1.1384 +    *            (green-y - blue-y) * (white-x - blue-x) ) / white-y
  1.1385 +    * -------------------------------------------------------------------------
  1.1386 +    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
  1.1387 +    *
  1.1388 +    *    green-scale =
  1.1389 +    *          ( (red-y - blue-y) * (white-x - blue-x) -
  1.1390 +    *            (red-x - blue-x) * (white-y - blue-y) ) / white-y
  1.1391 +    * -------------------------------------------------------------------------
  1.1392 +    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
  1.1393 +    *
  1.1394 +    * Accuracy:
  1.1395 +    * The input values have 5 decimal digits of accuracy.  The values are all in
  1.1396 +    * the range 0 < value < 1, so simple products are in the same range but may
  1.1397 +    * need up to 10 decimal digits to preserve the original precision and avoid
  1.1398 +    * underflow.  Because we are using a 32-bit signed representation we cannot
  1.1399 +    * match this; the best is a little over 9 decimal digits, less than 10.
  1.1400 +    *
  1.1401 +    * The approach used here is to preserve the maximum precision within the
  1.1402 +    * signed representation.  Because the red-scale calculation above uses the
  1.1403 +    * difference between two products of values that must be in the range -1..+1
  1.1404 +    * it is sufficient to divide the product by 7; ceil(100,000/32767*2).  The
  1.1405 +    * factor is irrelevant in the calculation because it is applied to both
  1.1406 +    * numerator and denominator.
  1.1407 +    *
  1.1408 +    * Note that the values of the differences of the products of the
  1.1409 +    * chromaticities in the above equations tend to be small, for example for
  1.1410 +    * the sRGB chromaticities they are:
  1.1411 +    *
  1.1412 +    * red numerator:    -0.04751
  1.1413 +    * green numerator:  -0.08788
  1.1414 +    * denominator:      -0.2241 (without white-y multiplication)
  1.1415 +    *
  1.1416 +    *  The resultant Y coefficients from the chromaticities of some widely used
  1.1417 +    *  color space definitions are (to 15 decimal places):
  1.1418 +    *
  1.1419 +    *  sRGB
  1.1420 +    *    0.212639005871510 0.715168678767756 0.072192315360734
  1.1421 +    *  Kodak ProPhoto
  1.1422 +    *    0.288071128229293 0.711843217810102 0.000085653960605
  1.1423 +    *  Adobe RGB
  1.1424 +    *    0.297344975250536 0.627363566255466 0.075291458493998
  1.1425 +    *  Adobe Wide Gamut RGB
  1.1426 +    *    0.258728243040113 0.724682314948566 0.016589442011321
  1.1427 +    */
  1.1428 +   /* By the argument, above overflow should be impossible here. The return
  1.1429 +    * value of 2 indicates an internal error to the caller.
  1.1430 +    */
  1.1431 +   if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7))
  1.1432 +      return 2;
  1.1433 +   if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7))
  1.1434 +      return 2;
  1.1435 +   denominator = left - right;
  1.1436 +
  1.1437 +   /* Now find the red numerator. */
  1.1438 +   if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7))
  1.1439 +      return 2;
  1.1440 +   if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7))
  1.1441 +      return 2;
  1.1442 +
  1.1443 +   /* Overflow is possible here and it indicates an extreme set of PNG cHRM
  1.1444 +    * chunk values.  This calculation actually returns the reciprocal of the
  1.1445 +    * scale value because this allows us to delay the multiplication of white-y
  1.1446 +    * into the denominator, which tends to produce a small number.
  1.1447 +    */
  1.1448 +   if (!png_muldiv(&red_inverse, xy->whitey, denominator, left-right) ||
  1.1449 +       red_inverse <= xy->whitey /* r+g+b scales = white scale */)
  1.1450 +      return 1;
  1.1451 +
  1.1452 +   /* Similarly for green_inverse: */
  1.1453 +   if (!png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7))
  1.1454 +      return 2;
  1.1455 +   if (!png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7))
  1.1456 +      return 2;
  1.1457 +   if (!png_muldiv(&green_inverse, xy->whitey, denominator, left-right) ||
  1.1458 +       green_inverse <= xy->whitey)
  1.1459 +      return 1;
  1.1460 +
  1.1461 +   /* And the blue scale, the checks above guarantee this can't overflow but it
  1.1462 +    * can still produce 0 for extreme cHRM values.
  1.1463 +    */
  1.1464 +   blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
  1.1465 +      png_reciprocal(green_inverse);
  1.1466 +   if (blue_scale <= 0) return 1;
  1.1467 +
  1.1468 +
  1.1469 +   /* And fill in the png_XYZ: */
  1.1470 +   if (!png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse)) return 1;
  1.1471 +   if (!png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse)) return 1;
  1.1472 +   if (!png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
  1.1473 +      red_inverse))
  1.1474 +      return 1;
  1.1475 +
  1.1476 +   if (!png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse))
  1.1477 +      return 1;
  1.1478 +   if (!png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse))
  1.1479 +      return 1;
  1.1480 +   if (!png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
  1.1481 +      green_inverse))
  1.1482 +      return 1;
  1.1483 +
  1.1484 +   if (!png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1)) return 1;
  1.1485 +   if (!png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1)) return 1;
  1.1486 +   if (!png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
  1.1487 +      PNG_FP_1))
  1.1488 +      return 1;
  1.1489 +
  1.1490 +   return 0; /*success*/
  1.1491 +}
  1.1492 +
  1.1493 +static int
  1.1494 +png_XYZ_normalize(png_XYZ *XYZ)
  1.1495 +{
  1.1496 +   png_int_32 Y;
  1.1497 +
  1.1498 +   if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
  1.1499 +      XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
  1.1500 +      XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
  1.1501 +      return 1;
  1.1502 +
  1.1503 +   /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
  1.1504 +    * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
  1.1505 +    * relying on addition of two positive values producing a negative one is not
  1.1506 +    * safe.
  1.1507 +    */
  1.1508 +   Y = XYZ->red_Y;
  1.1509 +   if (0x7fffffff - Y < XYZ->green_X) return 1;
  1.1510 +   Y += XYZ->green_Y;
  1.1511 +   if (0x7fffffff - Y < XYZ->blue_X) return 1;
  1.1512 +   Y += XYZ->blue_Y;
  1.1513 +
  1.1514 +   if (Y != PNG_FP_1)
  1.1515 +   {
  1.1516 +      if (!png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y)) return 1;
  1.1517 +      if (!png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y)) return 1;
  1.1518 +      if (!png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y)) return 1;
  1.1519 +
  1.1520 +      if (!png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y)) return 1;
  1.1521 +      if (!png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y)) return 1;
  1.1522 +      if (!png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y)) return 1;
  1.1523 +
  1.1524 +      if (!png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y)) return 1;
  1.1525 +      if (!png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y)) return 1;
  1.1526 +      if (!png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y)) return 1;
  1.1527 +   }
  1.1528 +
  1.1529 +   return 0;
  1.1530 +}
  1.1531 +
  1.1532 +static int
  1.1533 +png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
  1.1534 +{
  1.1535 +   /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
  1.1536 +   return !(PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
  1.1537 +      PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
  1.1538 +      PNG_OUT_OF_RANGE(xy1->redx,   xy2->redx,  delta) ||
  1.1539 +      PNG_OUT_OF_RANGE(xy1->redy,   xy2->redy,  delta) ||
  1.1540 +      PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
  1.1541 +      PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
  1.1542 +      PNG_OUT_OF_RANGE(xy1->bluex,  xy2->bluex, delta) ||
  1.1543 +      PNG_OUT_OF_RANGE(xy1->bluey,  xy2->bluey, delta));
  1.1544 +}
  1.1545 +
  1.1546 +/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
  1.1547 + * chunk chromaticities.  Earlier checks used to simply look for the overflow
  1.1548 + * condition (where the determinant of the matrix to solve for XYZ ends up zero
  1.1549 + * because the chromaticity values are not all distinct.)  Despite this it is
  1.1550 + * theoretically possible to produce chromaticities that are apparently valid
  1.1551 + * but that rapidly degrade to invalid, potentially crashing, sets because of
  1.1552 + * arithmetic inaccuracies when calculations are performed on them.  The new
  1.1553 + * check is to round-trip xy -> XYZ -> xy and then check that the result is
  1.1554 + * within a small percentage of the original.
  1.1555 + */
  1.1556 +static int
  1.1557 +png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
  1.1558 +{
  1.1559 +   int result;
  1.1560 +   png_xy xy_test;
  1.1561 +
  1.1562 +   /* As a side-effect this routine also returns the XYZ endpoints. */
  1.1563 +   result = png_XYZ_from_xy(XYZ, xy);
  1.1564 +   if (result) return result;
  1.1565 +
  1.1566 +   result = png_xy_from_XYZ(&xy_test, XYZ);
  1.1567 +   if (result) return result;
  1.1568 +
  1.1569 +   if (png_colorspace_endpoints_match(xy, &xy_test,
  1.1570 +      5/*actually, the math is pretty accurate*/))
  1.1571 +      return 0;
  1.1572 +
  1.1573 +   /* Too much slip */
  1.1574 +   return 1;
  1.1575 +}
  1.1576 +
  1.1577 +/* This is the check going the other way.  The XYZ is modified to normalize it
  1.1578 + * (another side-effect) and the xy chromaticities are returned.
  1.1579 + */
  1.1580 +static int
  1.1581 +png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
  1.1582 +{
  1.1583 +   int result;
  1.1584 +   png_XYZ XYZtemp;
  1.1585 +
  1.1586 +   result = png_XYZ_normalize(XYZ);
  1.1587 +   if (result) return result;
  1.1588 +
  1.1589 +   result = png_xy_from_XYZ(xy, XYZ);
  1.1590 +   if (result) return result;
  1.1591 +
  1.1592 +   XYZtemp = *XYZ;
  1.1593 +   return png_colorspace_check_xy(&XYZtemp, xy);
  1.1594 +}
  1.1595 +
  1.1596 +/* Used to check for an endpoint match against sRGB */
  1.1597 +static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
  1.1598 +{
  1.1599 +   /* color      x       y */
  1.1600 +   /* red   */ 64000, 33000,
  1.1601 +   /* green */ 30000, 60000,
  1.1602 +   /* blue  */ 15000,  6000,
  1.1603 +   /* white */ 31270, 32900
  1.1604 +};
  1.1605 +
  1.1606 +static int
  1.1607 +png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
  1.1608 +   png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
  1.1609 +   int preferred)
  1.1610 +{
  1.1611 +   if (colorspace->flags & PNG_COLORSPACE_INVALID)
  1.1612 +      return 0;
  1.1613 +
  1.1614 +   /* The consistency check is performed on the chromaticities; this factors out
  1.1615 +    * variations because of the normalization (or not) of the end point Y
  1.1616 +    * values.
  1.1617 +    */
  1.1618 +   if (preferred < 2 && (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
  1.1619 +   {
  1.1620 +      /* The end points must be reasonably close to any we already have.  The
  1.1621 +       * following allows an error of up to +/-.001
  1.1622 +       */
  1.1623 +      if (!png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, 100))
  1.1624 +      {
  1.1625 +         colorspace->flags |= PNG_COLORSPACE_INVALID;
  1.1626 +         png_benign_error(png_ptr, "inconsistent chromaticities");
  1.1627 +         return 0; /* failed */
  1.1628 +      }
  1.1629 +
  1.1630 +      /* Only overwrite with preferred values */
  1.1631 +      if (!preferred)
  1.1632 +         return 1; /* ok, but no change */
  1.1633 +   }
  1.1634 +
  1.1635 +   colorspace->end_points_xy = *xy;
  1.1636 +   colorspace->end_points_XYZ = *XYZ;
  1.1637 +   colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
  1.1638 +
  1.1639 +   /* The end points are normally quoted to two decimal digits, so allow +/-0.01
  1.1640 +    * on this test.
  1.1641 +    */
  1.1642 +   if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000))
  1.1643 +      colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
  1.1644 +
  1.1645 +   else
  1.1646 +      colorspace->flags &= PNG_COLORSPACE_CANCEL(
  1.1647 +         PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
  1.1648 +
  1.1649 +   return 2; /* ok and changed */
  1.1650 +}
  1.1651 +
  1.1652 +int /* PRIVATE */
  1.1653 +png_colorspace_set_chromaticities(png_const_structrp png_ptr,
  1.1654 +   png_colorspacerp colorspace, const png_xy *xy, int preferred)
  1.1655 +{
  1.1656 +   /* We must check the end points to ensure they are reasonable - in the past
  1.1657 +    * color management systems have crashed as a result of getting bogus
  1.1658 +    * colorant values, while this isn't the fault of libpng it is the
  1.1659 +    * responsibility of libpng because PNG carries the bomb and libpng is in a
  1.1660 +    * position to protect against it.
  1.1661 +    */
  1.1662 +   png_XYZ XYZ;
  1.1663 +
  1.1664 +   switch (png_colorspace_check_xy(&XYZ, xy))
  1.1665 +   {
  1.1666 +      case 0: /* success */
  1.1667 +         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
  1.1668 +            preferred);
  1.1669 +
  1.1670 +      case 1:
  1.1671 +         /* We can't invert the chromaticities so we can't produce value XYZ
  1.1672 +          * values.  Likely as not a color management system will fail too.
  1.1673 +          */
  1.1674 +         colorspace->flags |= PNG_COLORSPACE_INVALID;
  1.1675 +         png_benign_error(png_ptr, "invalid chromaticities");
  1.1676 +         break;
  1.1677 +
  1.1678 +      default:
  1.1679 +         /* libpng is broken; this should be a warning but if it happens we
  1.1680 +          * want error reports so for the moment it is an error.
  1.1681 +          */
  1.1682 +         colorspace->flags |= PNG_COLORSPACE_INVALID;
  1.1683 +         png_error(png_ptr, "internal error checking chromaticities");
  1.1684 +         break;
  1.1685 +   }
  1.1686 +
  1.1687 +   return 0; /* failed */
  1.1688 +}
  1.1689 +
  1.1690 +int /* PRIVATE */
  1.1691 +png_colorspace_set_endpoints(png_const_structrp png_ptr,
  1.1692 +   png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
  1.1693 +{
  1.1694 +   png_XYZ XYZ = *XYZ_in;
  1.1695 +   png_xy xy;
  1.1696 +
  1.1697 +   switch (png_colorspace_check_XYZ(&xy, &XYZ))
  1.1698 +   {
  1.1699 +      case 0:
  1.1700 +         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
  1.1701 +            preferred);
  1.1702 +
  1.1703 +      case 1:
  1.1704 +         /* End points are invalid. */
  1.1705 +         colorspace->flags |= PNG_COLORSPACE_INVALID;
  1.1706 +         png_benign_error(png_ptr, "invalid end points");
  1.1707 +         break;
  1.1708 +
  1.1709 +      default:
  1.1710 +         colorspace->flags |= PNG_COLORSPACE_INVALID;
  1.1711 +         png_error(png_ptr, "internal error checking chromaticities");
  1.1712 +         break;
  1.1713 +   }
  1.1714 +
  1.1715 +   return 0; /* failed */
  1.1716 +}
  1.1717 +
  1.1718 +#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
  1.1719 +/* Error message generation */
  1.1720 +static char
  1.1721 +png_icc_tag_char(png_uint_32 byte)
  1.1722 +{
  1.1723 +   byte &= 0xff;
  1.1724 +   if (byte >= 32 && byte <= 126)
  1.1725 +      return (char)byte;
  1.1726 +   else
  1.1727 +      return '?';
  1.1728 +}
  1.1729 +
  1.1730 +static void
  1.1731 +png_icc_tag_name(char *name, png_uint_32 tag)
  1.1732 +{
  1.1733 +   name[0] = '\'';
  1.1734 +   name[1] = png_icc_tag_char(tag >> 24);
  1.1735 +   name[2] = png_icc_tag_char(tag >> 16);
  1.1736 +   name[3] = png_icc_tag_char(tag >>  8);
  1.1737 +   name[4] = png_icc_tag_char(tag      );
  1.1738 +   name[5] = '\'';
  1.1739 +}
  1.1740 +
  1.1741 +static int
  1.1742 +is_ICC_signature_char(png_alloc_size_t it)
  1.1743 +{
  1.1744 +   return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
  1.1745 +      (it >= 97 && it <= 122);
  1.1746 +}
  1.1747 +
  1.1748 +static int
  1.1749 +is_ICC_signature(png_alloc_size_t it)
  1.1750 +{
  1.1751 +   return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
  1.1752 +      is_ICC_signature_char((it >> 16) & 0xff) &&
  1.1753 +      is_ICC_signature_char((it >> 8) & 0xff) &&
  1.1754 +      is_ICC_signature_char(it & 0xff);
  1.1755 +}
  1.1756 +
  1.1757 +static int
  1.1758 +png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
  1.1759 +   png_const_charp name, png_alloc_size_t value, png_const_charp reason)
  1.1760 +{
  1.1761 +   size_t pos;
  1.1762 +   char message[196]; /* see below for calculation */
  1.1763 +
  1.1764 +   if (colorspace != NULL)
  1.1765 +      colorspace->flags |= PNG_COLORSPACE_INVALID;
  1.1766 +
  1.1767 +   pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
  1.1768 +   pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
  1.1769 +   pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
  1.1770 +   if (is_ICC_signature(value))
  1.1771 +   {
  1.1772 +      /* So 'value' is at most 4 bytes and the following cast is safe */
  1.1773 +      png_icc_tag_name(message+pos, (png_uint_32)value);
  1.1774 +      pos += 6; /* total +8; less than the else clause */
  1.1775 +      message[pos++] = ':';
  1.1776 +      message[pos++] = ' ';
  1.1777 +   }
  1.1778 +#  ifdef PNG_WARNINGS_SUPPORTED
  1.1779 +   else
  1.1780 +      {
  1.1781 +         char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
  1.1782 +
  1.1783 +         pos = png_safecat(message, (sizeof message), pos,
  1.1784 +            png_format_number(number, number+(sizeof number),
  1.1785 +               PNG_NUMBER_FORMAT_x, value));
  1.1786 +         pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
  1.1787 +      }
  1.1788 +#  endif
  1.1789 +   /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
  1.1790 +   pos = png_safecat(message, (sizeof message), pos, reason);
  1.1791 +   PNG_UNUSED(pos)
  1.1792 +
  1.1793 +   /* This is recoverable, but make it unconditionally an app_error on write to
  1.1794 +    * avoid writing invalid ICC profiles into PNG files.  (I.e.  we handle them
  1.1795 +    * on read, with a warning, but on write unless the app turns off
  1.1796 +    * application errors the PNG won't be written.)
  1.1797 +    */
  1.1798 +   png_chunk_report(png_ptr, message,
  1.1799 +      (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
  1.1800 +
  1.1801 +   return 0;
  1.1802 +}
  1.1803 +#endif /* sRGB || iCCP */
  1.1804 +
  1.1805 +#ifdef PNG_sRGB_SUPPORTED
  1.1806 +int /* PRIVATE */
  1.1807 +png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
  1.1808 +   int intent)
  1.1809 +{
  1.1810 +   /* sRGB sets known gamma, end points and (from the chunk) intent. */
  1.1811 +   /* IMPORTANT: these are not necessarily the values found in an ICC profile
  1.1812 +    * because ICC profiles store values adapted to a D50 environment; it is
  1.1813 +    * expected that the ICC profile mediaWhitePointTag will be D50, see the
  1.1814 +    * checks and code elsewhere to understand this better.
  1.1815 +    *
  1.1816 +    * These XYZ values, which are accurate to 5dp, produce rgb to gray
  1.1817 +    * coefficients of (6968,23435,2366), which are reduced (because they add up
  1.1818 +    * to 32769 not 32768) to (6968,23434,2366).  These are the values that
  1.1819 +    * libpng has traditionally used (and are the best values given the 15bit
  1.1820 +    * algorithm used by the rgb to gray code.)
  1.1821 +    */
  1.1822 +   static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
  1.1823 +   {
  1.1824 +      /* color      X      Y      Z */
  1.1825 +      /* red   */ 41239, 21264,  1933,
  1.1826 +      /* green */ 35758, 71517, 11919,
  1.1827 +      /* blue  */ 18048,  7219, 95053
  1.1828 +   };
  1.1829 +
  1.1830 +   /* Do nothing if the colorspace is already invalidated. */
  1.1831 +   if (colorspace->flags & PNG_COLORSPACE_INVALID)
  1.1832 +      return 0;
  1.1833 +
  1.1834 +   /* Check the intent, then check for existing settings.  It is valid for the
  1.1835 +    * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
  1.1836 +    * be consistent with the correct values.  If, however, this function is
  1.1837 +    * called below because an iCCP chunk matches sRGB then it is quite
  1.1838 +    * conceivable that an older app recorded incorrect gAMA and cHRM because of
  1.1839 +    * an incorrect calculation based on the values in the profile - this does
  1.1840 +    * *not* invalidate the profile (though it still produces an error, which can
  1.1841 +    * be ignored.)
  1.1842 +    */
  1.1843 +   if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
  1.1844 +      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
  1.1845 +         (unsigned)intent, "invalid sRGB rendering intent");
  1.1846 +
  1.1847 +   if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
  1.1848 +      colorspace->rendering_intent != intent)
  1.1849 +      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
  1.1850 +         (unsigned)intent, "inconsistent rendering intents");
  1.1851 +
  1.1852 +   if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
  1.1853 +   {
  1.1854 +      png_benign_error(png_ptr, "duplicate sRGB information ignored");
  1.1855 +      return 0;
  1.1856 +   }
  1.1857 +
  1.1858 +   /* If the standard sRGB cHRM chunk does not match the one from the PNG file
  1.1859 +    * warn but overwrite the value with the correct one.
  1.1860 +    */
  1.1861 +   if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
  1.1862 +      !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
  1.1863 +         100))
  1.1864 +      png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
  1.1865 +         PNG_CHUNK_ERROR);
  1.1866 +
  1.1867 +   /* This check is just done for the error reporting - the routine always
  1.1868 +    * returns true when the 'from' argument corresponds to sRGB (2).
  1.1869 +    */
  1.1870 +   (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
  1.1871 +      2/*from sRGB*/);
  1.1872 +
  1.1873 +   /* intent: bugs in GCC force 'int' to be used as the parameter type. */
  1.1874 +   colorspace->rendering_intent = (png_uint_16)intent;
  1.1875 +   colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
  1.1876 +
  1.1877 +   /* endpoints */
  1.1878 +   colorspace->end_points_xy = sRGB_xy;
  1.1879 +   colorspace->end_points_XYZ = sRGB_XYZ;
  1.1880 +   colorspace->flags |=
  1.1881 +      (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
  1.1882 +
  1.1883 +   /* gamma */
  1.1884 +   colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
  1.1885 +   colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
  1.1886 +
  1.1887 +   /* Finally record that we have an sRGB profile */
  1.1888 +   colorspace->flags |=
  1.1889 +      (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
  1.1890 +
  1.1891 +   return 1; /* set */
  1.1892 +}
  1.1893 +#endif /* sRGB */
  1.1894 +
  1.1895 +#ifdef PNG_iCCP_SUPPORTED
  1.1896 +/* Encoded value of D50 as an ICC XYZNumber.  From the ICC 2010 spec the value
  1.1897 + * is XYZ(0.9642,1.0,0.8249), which scales to:
  1.1898 + *
  1.1899 + *    (63189.8112, 65536, 54060.6464)
  1.1900 + */
  1.1901 +static const png_byte D50_nCIEXYZ[12] =
  1.1902 +   { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
  1.1903 +
  1.1904 +int /* PRIVATE */
  1.1905 +png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
  1.1906 +   png_const_charp name, png_uint_32 profile_length)
  1.1907 +{
  1.1908 +   if (profile_length < 132)
  1.1909 +      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
  1.1910 +         "too short");
  1.1911 +
  1.1912 +   if (profile_length & 3)
  1.1913 +      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
  1.1914 +         "invalid length");
  1.1915 +
  1.1916 +   return 1;
  1.1917 +}
  1.1918 +
  1.1919 +int /* PRIVATE */
  1.1920 +png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
  1.1921 +   png_const_charp name, png_uint_32 profile_length,
  1.1922 +   png_const_bytep profile/* first 132 bytes only */, int color_type)
  1.1923 +{
  1.1924 +   png_uint_32 temp;
  1.1925 +
  1.1926 +   /* Length check; this cannot be ignored in this code because profile_length
  1.1927 +    * is used later to check the tag table, so even if the profile seems over
  1.1928 +    * long profile_length from the caller must be correct.  The caller can fix
  1.1929 +    * this up on read or write by just passing in the profile header length.
  1.1930 +    */
  1.1931 +   temp = png_get_uint_32(profile);
  1.1932 +   if (temp != profile_length)
  1.1933 +      return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.1934 +         "length does not match profile");
  1.1935 +
  1.1936 +   temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
  1.1937 +   if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
  1.1938 +      profile_length < 132+12*temp) /* truncated tag table */
  1.1939 +      return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.1940 +         "tag count too large");
  1.1941 +
  1.1942 +   /* The 'intent' must be valid or we can't store it, ICC limits the intent to
  1.1943 +    * 16 bits.
  1.1944 +    */
  1.1945 +   temp = png_get_uint_32(profile+64);
  1.1946 +   if (temp >= 0xffff) /* The ICC limit */
  1.1947 +      return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.1948 +         "invalid rendering intent");
  1.1949 +
  1.1950 +   /* This is just a warning because the profile may be valid in future
  1.1951 +    * versions.
  1.1952 +    */
  1.1953 +   if (temp >= PNG_sRGB_INTENT_LAST)
  1.1954 +      (void)png_icc_profile_error(png_ptr, NULL, name, temp,
  1.1955 +         "intent outside defined range");
  1.1956 +
  1.1957 +   /* At this point the tag table can't be checked because it hasn't necessarily
  1.1958 +    * been loaded; however, various header fields can be checked.  These checks
  1.1959 +    * are for values permitted by the PNG spec in an ICC profile; the PNG spec
  1.1960 +    * restricts the profiles that can be passed in an iCCP chunk (they must be
  1.1961 +    * appropriate to processing PNG data!)
  1.1962 +    */
  1.1963 +
  1.1964 +   /* Data checks (could be skipped).  These checks must be independent of the
  1.1965 +    * version number; however, the version number doesn't accomodate changes in
  1.1966 +    * the header fields (just the known tags and the interpretation of the
  1.1967 +    * data.)
  1.1968 +    */
  1.1969 +   temp = png_get_uint_32(profile+36); /* signature 'ascp' */
  1.1970 +   if (temp != 0x61637370)
  1.1971 +      return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.1972 +         "invalid signature");
  1.1973 +
  1.1974 +   /* Currently the PCS illuminant/adopted white point (the computational
  1.1975 +    * white point) are required to be D50,
  1.1976 +    * however the profile contains a record of the illuminant so perhaps ICC
  1.1977 +    * expects to be able to change this in the future (despite the rationale in
  1.1978 +    * the introduction for using a fixed PCS adopted white.)  Consequently the
  1.1979 +    * following is just a warning.
  1.1980 +    */
  1.1981 +   if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
  1.1982 +      (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
  1.1983 +         "PCS illuminant is not D50");
  1.1984 +
  1.1985 +   /* The PNG spec requires this:
  1.1986 +    * "If the iCCP chunk is present, the image samples conform to the colour
  1.1987 +    * space represented by the embedded ICC profile as defined by the
  1.1988 +    * International Color Consortium [ICC]. The colour space of the ICC profile
  1.1989 +    * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
  1.1990 +    * 6), or a greyscale colour space for greyscale images (PNG colour types 0
  1.1991 +    * and 4)."
  1.1992 +    *
  1.1993 +    * This checking code ensures the embedded profile (on either read or write)
  1.1994 +    * conforms to the specification requirements.  Notice that an ICC 'gray'
  1.1995 +    * color-space profile contains the information to transform the monochrome
  1.1996 +    * data to XYZ or L*a*b (according to which PCS the profile uses) and this
  1.1997 +    * should be used in preference to the standard libpng K channel replication
  1.1998 +    * into R, G and B channels.
  1.1999 +    *
  1.2000 +    * Previously it was suggested that an RGB profile on grayscale data could be
  1.2001 +    * handled.  However it it is clear that using an RGB profile in this context
  1.2002 +    * must be an error - there is no specification of what it means.  Thus it is
  1.2003 +    * almost certainly more correct to ignore the profile.
  1.2004 +    */
  1.2005 +   temp = png_get_uint_32(profile+16); /* data colour space field */
  1.2006 +   switch (temp)
  1.2007 +   {
  1.2008 +      case 0x52474220: /* 'RGB ' */
  1.2009 +         if (!(color_type & PNG_COLOR_MASK_COLOR))
  1.2010 +            return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.2011 +               "RGB color space not permitted on grayscale PNG");
  1.2012 +         break;
  1.2013 +
  1.2014 +      case 0x47524159: /* 'GRAY' */
  1.2015 +         if (color_type & PNG_COLOR_MASK_COLOR)
  1.2016 +            return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.2017 +               "Gray color space not permitted on RGB PNG");
  1.2018 +         break;
  1.2019 +
  1.2020 +      default:
  1.2021 +         return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.2022 +            "invalid ICC profile color space");
  1.2023 +   }
  1.2024 +
  1.2025 +   /* It is up to the application to check that the profile class matches the
  1.2026 +    * application requirements; the spec provides no guidance, but it's pretty
  1.2027 +    * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
  1.2028 +    * ('prtr') or 'spac' (for generic color spaces).  Issue a warning in these
  1.2029 +    * cases.  Issue an error for device link or abstract profiles - these don't
  1.2030 +    * contain the records necessary to transform the color-space to anything
  1.2031 +    * other than the target device (and not even that for an abstract profile).
  1.2032 +    * Profiles of these classes may not be embedded in images.
  1.2033 +    */
  1.2034 +   temp = png_get_uint_32(profile+12); /* profile/device class */
  1.2035 +   switch (temp)
  1.2036 +   {
  1.2037 +      case 0x73636E72: /* 'scnr' */
  1.2038 +      case 0x6D6E7472: /* 'mntr' */
  1.2039 +      case 0x70727472: /* 'prtr' */
  1.2040 +      case 0x73706163: /* 'spac' */
  1.2041 +         /* All supported */
  1.2042 +         break;
  1.2043 +
  1.2044 +      case 0x61627374: /* 'abst' */
  1.2045 +         /* May not be embedded in an image */
  1.2046 +         return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.2047 +            "invalid embedded Abstract ICC profile");
  1.2048 +
  1.2049 +      case 0x6C696E6B: /* 'link' */
  1.2050 +         /* DeviceLink profiles cannnot be interpreted in a non-device specific
  1.2051 +          * fashion, if an app uses the AToB0Tag in the profile the results are
  1.2052 +          * undefined unless the result is sent to the intended device,
  1.2053 +          * therefore a DeviceLink profile should not be found embedded in a
  1.2054 +          * PNG.
  1.2055 +          */
  1.2056 +         return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.2057 +            "unexpected DeviceLink ICC profile class");
  1.2058 +
  1.2059 +      case 0x6E6D636C: /* 'nmcl' */
  1.2060 +         /* A NamedColor profile is also device specific, however it doesn't
  1.2061 +          * contain an AToB0 tag that is open to misintrepretation.  Almost
  1.2062 +          * certainly it will fail the tests below.
  1.2063 +          */
  1.2064 +         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
  1.2065 +            "unexpected NamedColor ICC profile class");
  1.2066 +         break;
  1.2067 +
  1.2068 +      default:
  1.2069 +         /* To allow for future enhancements to the profile accept unrecognized
  1.2070 +          * profile classes with a warning, these then hit the test below on the
  1.2071 +          * tag content to ensure they are backward compatible with one of the
  1.2072 +          * understood profiles.
  1.2073 +          */
  1.2074 +         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
  1.2075 +            "unrecognized ICC profile class");
  1.2076 +         break;
  1.2077 +   }
  1.2078 +
  1.2079 +   /* For any profile other than a device link one the PCS must be encoded
  1.2080 +    * either in XYZ or Lab.
  1.2081 +    */
  1.2082 +   temp = png_get_uint_32(profile+20);
  1.2083 +   switch (temp)
  1.2084 +   {
  1.2085 +      case 0x58595A20: /* 'XYZ ' */
  1.2086 +      case 0x4C616220: /* 'Lab ' */
  1.2087 +         break;
  1.2088 +
  1.2089 +      default:
  1.2090 +         return png_icc_profile_error(png_ptr, colorspace, name, temp,
  1.2091 +            "unexpected ICC PCS encoding");
  1.2092 +   }
  1.2093 +
  1.2094 +   return 1;
  1.2095 +}
  1.2096 +
  1.2097 +int /* PRIVATE */
  1.2098 +png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
  1.2099 +   png_const_charp name, png_uint_32 profile_length,
  1.2100 +   png_const_bytep profile /* header plus whole tag table */)
  1.2101 +{
  1.2102 +   png_uint_32 tag_count = png_get_uint_32(profile+128);
  1.2103 +   png_uint_32 itag;
  1.2104 +   png_const_bytep tag = profile+132; /* The first tag */
  1.2105 +
  1.2106 +   /* First scan all the tags in the table and add bits to the icc_info value
  1.2107 +    * (temporarily in 'tags').
  1.2108 +    */
  1.2109 +   for (itag=0; itag < tag_count; ++itag, tag += 12)
  1.2110 +   {
  1.2111 +      png_uint_32 tag_id = png_get_uint_32(tag+0);
  1.2112 +      png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
  1.2113 +      png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
  1.2114 +
  1.2115 +      /* The ICC specification does not exclude zero length tags, therefore the
  1.2116 +       * start might actually be anywhere if there is no data, but this would be
  1.2117 +       * a clear abuse of the intent of the standard so the start is checked for
  1.2118 +       * being in range.  All defined tag types have an 8 byte header - a 4 byte
  1.2119 +       * type signature then 0.
  1.2120 +       */
  1.2121 +      if ((tag_start & 3) != 0)
  1.2122 +      {
  1.2123 +         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
  1.2124 +          * only a warning here because libpng does not care about the
  1.2125 +          * alignment.
  1.2126 +          */
  1.2127 +         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
  1.2128 +            "ICC profile tag start not a multiple of 4");
  1.2129 +      }
  1.2130 +
  1.2131 +      /* This is a hard error; potentially it can cause read outside the
  1.2132 +       * profile.
  1.2133 +       */
  1.2134 +      if (tag_start > profile_length || tag_length > profile_length - tag_start)
  1.2135 +         return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
  1.2136 +            "ICC profile tag outside profile");
  1.2137 +   }
  1.2138 +
  1.2139 +   return 1; /* success, maybe with warnings */
  1.2140 +}
  1.2141 +
  1.2142 +#ifdef PNG_sRGB_SUPPORTED
  1.2143 +/* Information about the known ICC sRGB profiles */
  1.2144 +static const struct
  1.2145 +{
  1.2146 +   png_uint_32 adler, crc, length;
  1.2147 +   png_uint_32 md5[4];
  1.2148 +   png_byte    have_md5;
  1.2149 +   png_byte    is_broken;
  1.2150 +   png_uint_16 intent;
  1.2151 +
  1.2152 +#  define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
  1.2153 +#  define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
  1.2154 +      { adler, crc, length, md5, broke, intent },
  1.2155 +
  1.2156 +} png_sRGB_checks[] =
  1.2157 +{
  1.2158 +   /* This data comes from contrib/tools/checksum-icc run on downloads of
  1.2159 +    * all four ICC sRGB profiles from www.color.org.
  1.2160 +    */
  1.2161 +   /* adler32, crc32, MD5[4], intent, date, length, file-name */
  1.2162 +   PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
  1.2163 +      PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
  1.2164 +      "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
  1.2165 +
  1.2166 +   /* ICC sRGB v2 perceptual no black-compensation: */
  1.2167 +   PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
  1.2168 +      PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
  1.2169 +      "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
  1.2170 +
  1.2171 +   PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
  1.2172 +      PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
  1.2173 +      "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
  1.2174 +
  1.2175 +   /* ICC sRGB v4 perceptual */
  1.2176 +   PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
  1.2177 +      PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
  1.2178 +      "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
  1.2179 +
  1.2180 +   /* The following profiles have no known MD5 checksum. If there is a match
  1.2181 +    * on the (empty) MD5 the other fields are used to attempt a match and
  1.2182 +    * a warning is produced.  The first two of these profiles have a 'cprt' tag
  1.2183 +    * which suggests that they were also made by Hewlett Packard.
  1.2184 +    */
  1.2185 +   PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
  1.2186 +      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
  1.2187 +      "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
  1.2188 +
  1.2189 +   /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
  1.2190 +    * match the D50 PCS illuminant in the header (it is in fact the D65 values,
  1.2191 +    * so the white point is recorded as the un-adapted value.)  The profiles
  1.2192 +    * below only differ in one byte - the intent - and are basically the same as
  1.2193 +    * the previous profile except for the mediaWhitePointTag error and a missing
  1.2194 +    * chromaticAdaptationTag.
  1.2195 +    */
  1.2196 +   PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
  1.2197 +      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
  1.2198 +      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
  1.2199 +
  1.2200 +   PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
  1.2201 +      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
  1.2202 +      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
  1.2203 +};
  1.2204 +
  1.2205 +static int
  1.2206 +png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
  1.2207 +   png_const_bytep profile, uLong adler)
  1.2208 +{
  1.2209 +   /* The quick check is to verify just the MD5 signature and trust the
  1.2210 +    * rest of the data.  Because the profile has already been verified for
  1.2211 +    * correctness this is safe.  png_colorspace_set_sRGB will check the 'intent'
  1.2212 +    * field too, so if the profile has been edited with an intent not defined
  1.2213 +    * by sRGB (but maybe defined by a later ICC specification) the read of
  1.2214 +    * the profile will fail at that point.
  1.2215 +    */
  1.2216 +   png_uint_32 length = 0;
  1.2217 +   png_uint_32 intent = 0x10000; /* invalid */
  1.2218 +#if PNG_sRGB_PROFILE_CHECKS > 1
  1.2219 +   uLong crc = 0; /* the value for 0 length data */
  1.2220 +#endif
  1.2221 +   unsigned int i;
  1.2222 +
  1.2223 +   for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
  1.2224 +   {
  1.2225 +      if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
  1.2226 +         png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
  1.2227 +         png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
  1.2228 +         png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
  1.2229 +      {
  1.2230 +         /* This may be one of the old HP profiles without an MD5, in that
  1.2231 +          * case we can only use the length and Adler32 (note that these
  1.2232 +          * are not used by default if there is an MD5!)
  1.2233 +          */
  1.2234 +#        if PNG_sRGB_PROFILE_CHECKS == 0
  1.2235 +            if (png_sRGB_checks[i].have_md5)
  1.2236 +               return 1+png_sRGB_checks[i].is_broken;
  1.2237 +#        endif
  1.2238 +
  1.2239 +         /* Profile is unsigned or more checks have been configured in. */
  1.2240 +         if (length == 0)
  1.2241 +         {
  1.2242 +            length = png_get_uint_32(profile);
  1.2243 +            intent = png_get_uint_32(profile+64);
  1.2244 +         }
  1.2245 +
  1.2246 +         /* Length *and* intent must match */
  1.2247 +         if (length == png_sRGB_checks[i].length &&
  1.2248 +            intent == png_sRGB_checks[i].intent)
  1.2249 +         {
  1.2250 +            /* Now calculate the adler32 if not done already. */
  1.2251 +            if (adler == 0)
  1.2252 +            {
  1.2253 +               adler = adler32(0, NULL, 0);
  1.2254 +               adler = adler32(adler, profile, length);
  1.2255 +            }
  1.2256 +
  1.2257 +            if (adler == png_sRGB_checks[i].adler)
  1.2258 +            {
  1.2259 +               /* These basic checks suggest that the data has not been
  1.2260 +                * modified, but if the check level is more than 1 perform
  1.2261 +                * our own crc32 checksum on the data.
  1.2262 +                */
  1.2263 +#              if PNG_sRGB_PROFILE_CHECKS > 1
  1.2264 +                  if (crc == 0)
  1.2265 +                  {
  1.2266 +                     crc = crc32(0, NULL, 0);
  1.2267 +                     crc = crc32(crc, profile, length);
  1.2268 +                  }
  1.2269 +
  1.2270 +                  /* So this check must pass for the 'return' below to happen.
  1.2271 +                   */
  1.2272 +                  if (crc == png_sRGB_checks[i].crc)
  1.2273 +#              endif
  1.2274 +               {
  1.2275 +                  if (png_sRGB_checks[i].is_broken)
  1.2276 +                  {
  1.2277 +                     /* These profiles are known to have bad data that may cause
  1.2278 +                      * problems if they are used, therefore attempt to
  1.2279 +                      * discourage their use, skip the 'have_md5' warning below,
  1.2280 +                      * which is made irrelevant by this error.
  1.2281 +                      */
  1.2282 +                     png_chunk_report(png_ptr, "known incorrect sRGB profile",
  1.2283 +                        PNG_CHUNK_ERROR);
  1.2284 +                  }
  1.2285 +
  1.2286 +                  /* Warn that this being done; this isn't even an error since
  1.2287 +                   * the profile is perfectly valid, but it would be nice if
  1.2288 +                   * people used the up-to-date ones.
  1.2289 +                   */
  1.2290 +                  else if (!png_sRGB_checks[i].have_md5)
  1.2291 +                  {
  1.2292 +                     png_chunk_report(png_ptr,
  1.2293 +                        "out-of-date sRGB profile with no signature",
  1.2294 +                        PNG_CHUNK_WARNING);
  1.2295 +                  }
  1.2296 +
  1.2297 +                  return 1+png_sRGB_checks[i].is_broken;
  1.2298 +               }
  1.2299 +            }
  1.2300 +         }
  1.2301 +
  1.2302 +# if PNG_sRGB_PROFILE_CHECKS > 0
  1.2303 +         /* The signature matched, but the profile had been changed in some
  1.2304 +          * way.  This probably indicates a data error or uninformed hacking.
  1.2305 +          * Fall through to "no match".
  1.2306 +          */
  1.2307 +         png_chunk_report(png_ptr,
  1.2308 +             "Not recognizing known sRGB profile that has been edited", 
  1.2309 +             PNG_CHUNK_WARNING);
  1.2310 +         break;
  1.2311 +# endif
  1.2312 +      }
  1.2313 +   }
  1.2314 +
  1.2315 +   return 0; /* no match */
  1.2316 +}
  1.2317 +#endif
  1.2318 +
  1.2319 +#ifdef PNG_sRGB_SUPPORTED
  1.2320 +void /* PRIVATE */
  1.2321 +png_icc_set_sRGB(png_const_structrp png_ptr,
  1.2322 +   png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
  1.2323 +{
  1.2324 +   /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
  1.2325 +    * the sRGB information.
  1.2326 +    */
  1.2327 +   if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler))
  1.2328 +      (void)png_colorspace_set_sRGB(png_ptr, colorspace,
  1.2329 +         (int)/*already checked*/png_get_uint_32(profile+64));
  1.2330 +}
  1.2331 +#endif /* PNG_READ_sRGB_SUPPORTED */
  1.2332 +
  1.2333 +int /* PRIVATE */
  1.2334 +png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
  1.2335 +   png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
  1.2336 +   int color_type)
  1.2337 +{
  1.2338 +   if (colorspace->flags & PNG_COLORSPACE_INVALID)
  1.2339 +      return 0;
  1.2340 +
  1.2341 +   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) &&
  1.2342 +      png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
  1.2343 +         color_type) &&
  1.2344 +      png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
  1.2345 +         profile))
  1.2346 +   {
  1.2347 +#     ifdef PNG_sRGB_SUPPORTED
  1.2348 +         /* If no sRGB support, don't try storing sRGB information */
  1.2349 +         png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
  1.2350 +#     endif
  1.2351 +      return 1;
  1.2352 +   }
  1.2353 +
  1.2354 +   /* Failure case */
  1.2355 +   return 0;
  1.2356 +}
  1.2357 +#endif /* iCCP */
  1.2358 +
  1.2359 +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
  1.2360 +void /* PRIVATE */
  1.2361 +png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
  1.2362 +{
  1.2363 +   /* Set the rgb_to_gray coefficients from the colorspace. */
  1.2364 +   if (!png_ptr->rgb_to_gray_coefficients_set &&
  1.2365 +      (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
  1.2366 +   {
  1.2367 +      /* png_set_background has not been called, get the coefficients from the Y
  1.2368 +       * values of the colorspace colorants.
  1.2369 +       */
  1.2370 +      png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
  1.2371 +      png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
  1.2372 +      png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
  1.2373 +      png_fixed_point total = r+g+b;
  1.2374 +
  1.2375 +      if (total > 0 &&
  1.2376 +         r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
  1.2377 +         g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
  1.2378 +         b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
  1.2379 +         r+g+b <= 32769)
  1.2380 +      {
  1.2381 +         /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
  1.2382 +          * all of the coefficients were rounded up.  Handle this by
  1.2383 +          * reducing the *largest* coefficient by 1; this matches the
  1.2384 +          * approach used for the default coefficients in pngrtran.c
  1.2385 +          */
  1.2386 +         int add = 0;
  1.2387 +
  1.2388 +         if (r+g+b > 32768)
  1.2389 +            add = -1;
  1.2390 +         else if (r+g+b < 32768)
  1.2391 +            add = 1;
  1.2392 +
  1.2393 +         if (add != 0)
  1.2394 +         {
  1.2395 +            if (g >= r && g >= b)
  1.2396 +               g += add;
  1.2397 +            else if (r >= g && r >= b)
  1.2398 +               r += add;
  1.2399 +            else
  1.2400 +               b += add;
  1.2401 +         }
  1.2402 +
  1.2403 +         /* Check for an internal error. */
  1.2404 +         if (r+g+b != 32768)
  1.2405 +            png_error(png_ptr,
  1.2406 +               "internal error handling cHRM coefficients");
  1.2407 +
  1.2408 +         else
  1.2409 +         {
  1.2410 +            png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
  1.2411 +            png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
  1.2412 +         }
  1.2413 +      }
  1.2414 +
  1.2415 +      /* This is a png_error at present even though it could be ignored -
  1.2416 +       * it should never happen, but it is important that if it does, the
  1.2417 +       * bug is fixed.
  1.2418 +       */
  1.2419 +      else
  1.2420 +         png_error(png_ptr, "internal error handling cHRM->XYZ");
  1.2421 +   }
  1.2422 +}
  1.2423 +#endif
  1.2424 +
  1.2425 +#endif /* COLORSPACE */
  1.2426 +
  1.2427 +void /* PRIVATE */
  1.2428 +png_check_IHDR(png_const_structrp png_ptr,
  1.2429 +   png_uint_32 width, png_uint_32 height, int bit_depth,
  1.2430 +   int color_type, int interlace_type, int compression_type,
  1.2431 +   int filter_type)
  1.2432 +{
  1.2433 +   int error = 0;
  1.2434 +
  1.2435 +   /* Check for width and height valid values */
  1.2436 +   if (width == 0)
  1.2437 +   {
  1.2438 +      png_warning(png_ptr, "Image width is zero in IHDR");
  1.2439 +      error = 1;
  1.2440 +   }
  1.2441 +
  1.2442 +   if (height == 0)
  1.2443 +   {
  1.2444 +      png_warning(png_ptr, "Image height is zero in IHDR");
  1.2445 +      error = 1;
  1.2446 +   }
  1.2447 +
  1.2448 +#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
  1.2449 +   if (width > png_ptr->user_width_max)
  1.2450 +
  1.2451 +#  else
  1.2452 +   if (width > PNG_USER_WIDTH_MAX)
  1.2453 +#  endif
  1.2454 +   {
  1.2455 +      png_warning(png_ptr, "Image width exceeds user limit in IHDR");
  1.2456 +      error = 1;
  1.2457 +   }
  1.2458 +
  1.2459 +#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
  1.2460 +   if (height > png_ptr->user_height_max)
  1.2461 +#  else
  1.2462 +   if (height > PNG_USER_HEIGHT_MAX)
  1.2463 +#  endif
  1.2464 +   {
  1.2465 +      png_warning(png_ptr, "Image height exceeds user limit in IHDR");
  1.2466 +      error = 1;
  1.2467 +   }
  1.2468 +
  1.2469 +   if (width > PNG_UINT_31_MAX)
  1.2470 +   {
  1.2471 +      png_warning(png_ptr, "Invalid image width in IHDR");
  1.2472 +      error = 1;
  1.2473 +   }
  1.2474 +
  1.2475 +   if (height > PNG_UINT_31_MAX)
  1.2476 +   {
  1.2477 +      png_warning(png_ptr, "Invalid image height in IHDR");
  1.2478 +      error = 1;
  1.2479 +   }
  1.2480 +
  1.2481 +   /* Check other values */
  1.2482 +   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
  1.2483 +       bit_depth != 8 && bit_depth != 16)
  1.2484 +   {
  1.2485 +      png_warning(png_ptr, "Invalid bit depth in IHDR");
  1.2486 +      error = 1;
  1.2487 +   }
  1.2488 +
  1.2489 +   if (color_type < 0 || color_type == 1 ||
  1.2490 +       color_type == 5 || color_type > 6)
  1.2491 +   {
  1.2492 +      png_warning(png_ptr, "Invalid color type in IHDR");
  1.2493 +      error = 1;
  1.2494 +   }
  1.2495 +
  1.2496 +   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
  1.2497 +       ((color_type == PNG_COLOR_TYPE_RGB ||
  1.2498 +         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
  1.2499 +         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
  1.2500 +   {
  1.2501 +      png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
  1.2502 +      error = 1;
  1.2503 +   }
  1.2504 +
  1.2505 +   if (interlace_type >= PNG_INTERLACE_LAST)
  1.2506 +   {
  1.2507 +      png_warning(png_ptr, "Unknown interlace method in IHDR");
  1.2508 +      error = 1;
  1.2509 +   }
  1.2510 +
  1.2511 +   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
  1.2512 +   {
  1.2513 +      png_warning(png_ptr, "Unknown compression method in IHDR");
  1.2514 +      error = 1;
  1.2515 +   }
  1.2516 +
  1.2517 +#  ifdef PNG_MNG_FEATURES_SUPPORTED
  1.2518 +   /* Accept filter_method 64 (intrapixel differencing) only if
  1.2519 +    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
  1.2520 +    * 2. Libpng did not read a PNG signature (this filter_method is only
  1.2521 +    *    used in PNG datastreams that are embedded in MNG datastreams) and
  1.2522 +    * 3. The application called png_permit_mng_features with a mask that
  1.2523 +    *    included PNG_FLAG_MNG_FILTER_64 and
  1.2524 +    * 4. The filter_method is 64 and
  1.2525 +    * 5. The color_type is RGB or RGBA
  1.2526 +    */
  1.2527 +   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
  1.2528 +       png_ptr->mng_features_permitted)
  1.2529 +      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
  1.2530 +
  1.2531 +   if (filter_type != PNG_FILTER_TYPE_BASE)
  1.2532 +   {
  1.2533 +      if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
  1.2534 +          (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
  1.2535 +          ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
  1.2536 +          (color_type == PNG_COLOR_TYPE_RGB ||
  1.2537 +          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
  1.2538 +      {
  1.2539 +         png_warning(png_ptr, "Unknown filter method in IHDR");
  1.2540 +         error = 1;
  1.2541 +      }
  1.2542 +
  1.2543 +      if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
  1.2544 +      {
  1.2545 +         png_warning(png_ptr, "Invalid filter method in IHDR");
  1.2546 +         error = 1;
  1.2547 +      }
  1.2548 +   }
  1.2549 +
  1.2550 +#  else
  1.2551 +   if (filter_type != PNG_FILTER_TYPE_BASE)
  1.2552 +   {
  1.2553 +      png_warning(png_ptr, "Unknown filter method in IHDR");
  1.2554 +      error = 1;
  1.2555 +   }
  1.2556 +#  endif
  1.2557 +
  1.2558 +   if (error == 1)
  1.2559 +      png_error(png_ptr, "Invalid IHDR data");
  1.2560 +}
  1.2561 +
  1.2562 +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
  1.2563 +/* ASCII to fp functions */
  1.2564 +/* Check an ASCII formated floating point value, see the more detailed
  1.2565 + * comments in pngpriv.h
  1.2566 + */
  1.2567 +/* The following is used internally to preserve the sticky flags */
  1.2568 +#define png_fp_add(state, flags) ((state) |= (flags))
  1.2569 +#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
  1.2570 +
  1.2571 +int /* PRIVATE */
  1.2572 +png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
  1.2573 +   png_size_tp whereami)
  1.2574 +{
  1.2575 +   int state = *statep;
  1.2576 +   png_size_t i = *whereami;
  1.2577 +
  1.2578 +   while (i < size)
  1.2579 +   {
  1.2580 +      int type;
  1.2581 +      /* First find the type of the next character */
  1.2582 +      switch (string[i])
  1.2583 +      {
  1.2584 +      case 43:  type = PNG_FP_SAW_SIGN;                   break;
  1.2585 +      case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
  1.2586 +      case 46:  type = PNG_FP_SAW_DOT;                    break;
  1.2587 +      case 48:  type = PNG_FP_SAW_DIGIT;                  break;
  1.2588 +      case 49: case 50: case 51: case 52:
  1.2589 +      case 53: case 54: case 55: case 56:
  1.2590 +      case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
  1.2591 +      case 69:
  1.2592 +      case 101: type = PNG_FP_SAW_E;                      break;
  1.2593 +      default:  goto PNG_FP_End;
  1.2594 +      }
  1.2595 +
  1.2596 +      /* Now deal with this type according to the current
  1.2597 +       * state, the type is arranged to not overlap the
  1.2598 +       * bits of the PNG_FP_STATE.
  1.2599 +       */
  1.2600 +      switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
  1.2601 +      {
  1.2602 +      case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
  1.2603 +         if (state & PNG_FP_SAW_ANY)
  1.2604 +            goto PNG_FP_End; /* not a part of the number */
  1.2605 +
  1.2606 +         png_fp_add(state, type);
  1.2607 +         break;
  1.2608 +
  1.2609 +      case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
  1.2610 +         /* Ok as trailer, ok as lead of fraction. */
  1.2611 +         if (state & PNG_FP_SAW_DOT) /* two dots */
  1.2612 +            goto PNG_FP_End;
  1.2613 +
  1.2614 +         else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */
  1.2615 +            png_fp_add(state, type);
  1.2616 +
  1.2617 +         else
  1.2618 +            png_fp_set(state, PNG_FP_FRACTION | type);
  1.2619 +
  1.2620 +         break;
  1.2621 +
  1.2622 +      case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
  1.2623 +         if (state & PNG_FP_SAW_DOT) /* delayed fraction */
  1.2624 +            png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
  1.2625 +
  1.2626 +         png_fp_add(state, type | PNG_FP_WAS_VALID);
  1.2627 +
  1.2628 +         break;
  1.2629 +
  1.2630 +      case PNG_FP_INTEGER + PNG_FP_SAW_E:
  1.2631 +         if ((state & PNG_FP_SAW_DIGIT) == 0)
  1.2632 +            goto PNG_FP_End;
  1.2633 +
  1.2634 +         png_fp_set(state, PNG_FP_EXPONENT);
  1.2635 +
  1.2636 +         break;
  1.2637 +
  1.2638 +   /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
  1.2639 +         goto PNG_FP_End; ** no sign in fraction */
  1.2640 +
  1.2641 +   /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
  1.2642 +         goto PNG_FP_End; ** Because SAW_DOT is always set */
  1.2643 +
  1.2644 +      case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
  1.2645 +         png_fp_add(state, type | PNG_FP_WAS_VALID);
  1.2646 +         break;
  1.2647 +
  1.2648 +      case PNG_FP_FRACTION + PNG_FP_SAW_E:
  1.2649 +         /* This is correct because the trailing '.' on an
  1.2650 +          * integer is handled above - so we can only get here
  1.2651 +          * with the sequence ".E" (with no preceding digits).
  1.2652 +          */
  1.2653 +         if ((state & PNG_FP_SAW_DIGIT) == 0)
  1.2654 +            goto PNG_FP_End;
  1.2655 +
  1.2656 +         png_fp_set(state, PNG_FP_EXPONENT);
  1.2657 +
  1.2658 +         break;
  1.2659 +
  1.2660 +      case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
  1.2661 +         if (state & PNG_FP_SAW_ANY)
  1.2662 +            goto PNG_FP_End; /* not a part of the number */
  1.2663 +
  1.2664 +         png_fp_add(state, PNG_FP_SAW_SIGN);
  1.2665 +
  1.2666 +         break;
  1.2667 +
  1.2668 +   /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
  1.2669 +         goto PNG_FP_End; */
  1.2670 +
  1.2671 +      case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
  1.2672 +         png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
  1.2673 +
  1.2674 +         break;
  1.2675 +
  1.2676 +   /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
  1.2677 +         goto PNG_FP_End; */
  1.2678 +
  1.2679 +      default: goto PNG_FP_End; /* I.e. break 2 */
  1.2680 +      }
  1.2681 +
  1.2682 +      /* The character seems ok, continue. */
  1.2683 +      ++i;
  1.2684 +   }
  1.2685 +
  1.2686 +PNG_FP_End:
  1.2687 +   /* Here at the end, update the state and return the correct
  1.2688 +    * return code.
  1.2689 +    */
  1.2690 +   *statep = state;
  1.2691 +   *whereami = i;
  1.2692 +
  1.2693 +   return (state & PNG_FP_SAW_DIGIT) != 0;
  1.2694 +}
  1.2695 +
  1.2696 +
  1.2697 +/* The same but for a complete string. */
  1.2698 +int
  1.2699 +png_check_fp_string(png_const_charp string, png_size_t size)
  1.2700 +{
  1.2701 +   int        state=0;
  1.2702 +   png_size_t char_index=0;
  1.2703 +
  1.2704 +   if (png_check_fp_number(string, size, &state, &char_index) &&
  1.2705 +      (char_index == size || string[char_index] == 0))
  1.2706 +      return state /* must be non-zero - see above */;
  1.2707 +
  1.2708 +   return 0; /* i.e. fail */
  1.2709 +}
  1.2710 +#endif /* pCAL or sCAL */
  1.2711 +
  1.2712 +#ifdef PNG_sCAL_SUPPORTED
  1.2713 +#  ifdef PNG_FLOATING_POINT_SUPPORTED
  1.2714 +/* Utility used below - a simple accurate power of ten from an integral
  1.2715 + * exponent.
  1.2716 + */
  1.2717 +static double
  1.2718 +png_pow10(int power)
  1.2719 +{
  1.2720 +   int recip = 0;
  1.2721 +   double d = 1;
  1.2722 +
  1.2723 +   /* Handle negative exponent with a reciprocal at the end because
  1.2724 +    * 10 is exact whereas .1 is inexact in base 2
  1.2725 +    */
  1.2726 +   if (power < 0)
  1.2727 +   {
  1.2728 +      if (power < DBL_MIN_10_EXP) return 0;
  1.2729 +      recip = 1, power = -power;
  1.2730 +   }
  1.2731 +
  1.2732 +   if (power > 0)
  1.2733 +   {
  1.2734 +      /* Decompose power bitwise. */
  1.2735 +      double mult = 10;
  1.2736 +      do
  1.2737 +      {
  1.2738 +         if (power & 1) d *= mult;
  1.2739 +         mult *= mult;
  1.2740 +         power >>= 1;
  1.2741 +      }
  1.2742 +      while (power > 0);
  1.2743 +
  1.2744 +      if (recip) d = 1/d;
  1.2745 +   }
  1.2746 +   /* else power is 0 and d is 1 */
  1.2747 +
  1.2748 +   return d;
  1.2749 +}
  1.2750 +
  1.2751 +/* Function to format a floating point value in ASCII with a given
  1.2752 + * precision.
  1.2753 + */
  1.2754 +void /* PRIVATE */
  1.2755 +png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
  1.2756 +    double fp, unsigned int precision)
  1.2757 +{
  1.2758 +   /* We use standard functions from math.h, but not printf because
  1.2759 +    * that would require stdio.  The caller must supply a buffer of
  1.2760 +    * sufficient size or we will png_error.  The tests on size and
  1.2761 +    * the space in ascii[] consumed are indicated below.
  1.2762 +    */
  1.2763 +   if (precision < 1)
  1.2764 +      precision = DBL_DIG;
  1.2765 +
  1.2766 +   /* Enforce the limit of the implementation precision too. */
  1.2767 +   if (precision > DBL_DIG+1)
  1.2768 +      precision = DBL_DIG+1;
  1.2769 +
  1.2770 +   /* Basic sanity checks */
  1.2771 +   if (size >= precision+5) /* See the requirements below. */
  1.2772 +   {
  1.2773 +      if (fp < 0)
  1.2774 +      {
  1.2775 +         fp = -fp;
  1.2776 +         *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */
  1.2777 +         --size;
  1.2778 +      }
  1.2779 +
  1.2780 +      if (fp >= DBL_MIN && fp <= DBL_MAX)
  1.2781 +      {
  1.2782 +         int exp_b10;       /* A base 10 exponent */
  1.2783 +         double base;   /* 10^exp_b10 */
  1.2784 +
  1.2785 +         /* First extract a base 10 exponent of the number,
  1.2786 +          * the calculation below rounds down when converting
  1.2787 +          * from base 2 to base 10 (multiply by log10(2) -
  1.2788 +          * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
  1.2789 +          * be increased.  Note that the arithmetic shift
  1.2790 +          * performs a floor() unlike C arithmetic - using a
  1.2791 +          * C multiply would break the following for negative
  1.2792 +          * exponents.
  1.2793 +          */
  1.2794 +         (void)frexp(fp, &exp_b10); /* exponent to base 2 */
  1.2795 +
  1.2796 +         exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
  1.2797 +
  1.2798 +         /* Avoid underflow here. */
  1.2799 +         base = png_pow10(exp_b10); /* May underflow */
  1.2800 +
  1.2801 +         while (base < DBL_MIN || base < fp)
  1.2802 +         {
  1.2803 +            /* And this may overflow. */
  1.2804 +            double test = png_pow10(exp_b10+1);
  1.2805 +
  1.2806 +            if (test <= DBL_MAX)
  1.2807 +               ++exp_b10, base = test;
  1.2808 +
  1.2809 +            else
  1.2810 +               break;
  1.2811 +         }
  1.2812 +
  1.2813 +         /* Normalize fp and correct exp_b10, after this fp is in the
  1.2814 +          * range [.1,1) and exp_b10 is both the exponent and the digit
  1.2815 +          * *before* which the decimal point should be inserted
  1.2816 +          * (starting with 0 for the first digit).  Note that this
  1.2817 +          * works even if 10^exp_b10 is out of range because of the
  1.2818 +          * test on DBL_MAX above.
  1.2819 +          */
  1.2820 +         fp /= base;
  1.2821 +         while (fp >= 1) fp /= 10, ++exp_b10;
  1.2822 +
  1.2823 +         /* Because of the code above fp may, at this point, be
  1.2824 +          * less than .1, this is ok because the code below can
  1.2825 +          * handle the leading zeros this generates, so no attempt
  1.2826 +          * is made to correct that here.
  1.2827 +          */
  1.2828 +
  1.2829 +         {
  1.2830 +            int czero, clead, cdigits;
  1.2831 +            char exponent[10];
  1.2832 +
  1.2833 +            /* Allow up to two leading zeros - this will not lengthen
  1.2834 +             * the number compared to using E-n.
  1.2835 +             */
  1.2836 +            if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
  1.2837 +            {
  1.2838 +               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
  1.2839 +               exp_b10 = 0;      /* Dot added below before first output. */
  1.2840 +            }
  1.2841 +            else
  1.2842 +               czero = 0;    /* No zeros to add */
  1.2843 +
  1.2844 +            /* Generate the digit list, stripping trailing zeros and
  1.2845 +             * inserting a '.' before a digit if the exponent is 0.
  1.2846 +             */
  1.2847 +            clead = czero; /* Count of leading zeros */
  1.2848 +            cdigits = 0;   /* Count of digits in list. */
  1.2849 +
  1.2850 +            do
  1.2851 +            {
  1.2852 +               double d;
  1.2853 +
  1.2854 +               fp *= 10;
  1.2855 +               /* Use modf here, not floor and subtract, so that
  1.2856 +                * the separation is done in one step.  At the end
  1.2857 +                * of the loop don't break the number into parts so
  1.2858 +                * that the final digit is rounded.
  1.2859 +                */
  1.2860 +               if (cdigits+czero-clead+1 < (int)precision)
  1.2861 +                  fp = modf(fp, &d);
  1.2862 +
  1.2863 +               else
  1.2864 +               {
  1.2865 +                  d = floor(fp + .5);
  1.2866 +
  1.2867 +                  if (d > 9)
  1.2868 +                  {
  1.2869 +                     /* Rounding up to 10, handle that here. */
  1.2870 +                     if (czero > 0)
  1.2871 +                     {
  1.2872 +                        --czero, d = 1;
  1.2873 +                        if (cdigits == 0) --clead;
  1.2874 +                     }
  1.2875 +                     else
  1.2876 +                     {
  1.2877 +                        while (cdigits > 0 && d > 9)
  1.2878 +                        {
  1.2879 +                           int ch = *--ascii;
  1.2880 +
  1.2881 +                           if (exp_b10 != (-1))
  1.2882 +                              ++exp_b10;
  1.2883 +
  1.2884 +                           else if (ch == 46)
  1.2885 +                           {
  1.2886 +                              ch = *--ascii, ++size;
  1.2887 +                              /* Advance exp_b10 to '1', so that the
  1.2888 +                               * decimal point happens after the
  1.2889 +                               * previous digit.
  1.2890 +                               */
  1.2891 +                              exp_b10 = 1;
  1.2892 +                           }
  1.2893 +
  1.2894 +                           --cdigits;
  1.2895 +                           d = ch - 47;  /* I.e. 1+(ch-48) */
  1.2896 +                        }
  1.2897 +
  1.2898 +                        /* Did we reach the beginning? If so adjust the
  1.2899 +                         * exponent but take into account the leading
  1.2900 +                         * decimal point.
  1.2901 +                         */
  1.2902 +                        if (d > 9)  /* cdigits == 0 */
  1.2903 +                        {
  1.2904 +                           if (exp_b10 == (-1))
  1.2905 +                           {
  1.2906 +                              /* Leading decimal point (plus zeros?), if
  1.2907 +                               * we lose the decimal point here it must
  1.2908 +                               * be reentered below.
  1.2909 +                               */
  1.2910 +                              int ch = *--ascii;
  1.2911 +
  1.2912 +                              if (ch == 46)
  1.2913 +                                 ++size, exp_b10 = 1;
  1.2914 +
  1.2915 +                              /* Else lost a leading zero, so 'exp_b10' is
  1.2916 +                               * still ok at (-1)
  1.2917 +                               */
  1.2918 +                           }
  1.2919 +                           else
  1.2920 +                              ++exp_b10;
  1.2921 +
  1.2922 +                           /* In all cases we output a '1' */
  1.2923 +                           d = 1;
  1.2924 +                        }
  1.2925 +                     }
  1.2926 +                  }
  1.2927 +                  fp = 0; /* Guarantees termination below. */
  1.2928 +               }
  1.2929 +
  1.2930 +               if (d == 0)
  1.2931 +               {
  1.2932 +                  ++czero;
  1.2933 +                  if (cdigits == 0) ++clead;
  1.2934 +               }
  1.2935 +               else
  1.2936 +               {
  1.2937 +                  /* Included embedded zeros in the digit count. */
  1.2938 +                  cdigits += czero - clead;
  1.2939 +                  clead = 0;
  1.2940 +
  1.2941 +                  while (czero > 0)
  1.2942 +                  {
  1.2943 +                     /* exp_b10 == (-1) means we just output the decimal
  1.2944 +                      * place - after the DP don't adjust 'exp_b10' any
  1.2945 +                      * more!
  1.2946 +                      */
  1.2947 +                     if (exp_b10 != (-1))
  1.2948 +                     {
  1.2949 +                        if (exp_b10 == 0) *ascii++ = 46, --size;
  1.2950 +                        /* PLUS 1: TOTAL 4 */
  1.2951 +                        --exp_b10;
  1.2952 +                     }
  1.2953 +                     *ascii++ = 48, --czero;
  1.2954 +                  }
  1.2955 +
  1.2956 +                  if (exp_b10 != (-1))
  1.2957 +                  {
  1.2958 +                     if (exp_b10 == 0) *ascii++ = 46, --size; /* counted
  1.2959 +                                                                 above */
  1.2960 +                     --exp_b10;
  1.2961 +                  }
  1.2962 +                  *ascii++ = (char)(48 + (int)d), ++cdigits;
  1.2963 +               }
  1.2964 +            }
  1.2965 +            while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
  1.2966 +
  1.2967 +            /* The total output count (max) is now 4+precision */
  1.2968 +
  1.2969 +            /* Check for an exponent, if we don't need one we are
  1.2970 +             * done and just need to terminate the string.  At
  1.2971 +             * this point exp_b10==(-1) is effectively if flag - it got
  1.2972 +             * to '-1' because of the decrement after outputing
  1.2973 +             * the decimal point above (the exponent required is
  1.2974 +             * *not* -1!)
  1.2975 +             */
  1.2976 +            if (exp_b10 >= (-1) && exp_b10 <= 2)
  1.2977 +            {
  1.2978 +               /* The following only happens if we didn't output the
  1.2979 +                * leading zeros above for negative exponent, so this
  1.2980 +                * doest add to the digit requirement.  Note that the
  1.2981 +                * two zeros here can only be output if the two leading
  1.2982 +                * zeros were *not* output, so this doesn't increase
  1.2983 +                * the output count.
  1.2984 +                */
  1.2985 +               while (--exp_b10 >= 0) *ascii++ = 48;
  1.2986 +
  1.2987 +               *ascii = 0;
  1.2988 +
  1.2989 +               /* Total buffer requirement (including the '\0') is
  1.2990 +                * 5+precision - see check at the start.
  1.2991 +                */
  1.2992 +               return;
  1.2993 +            }
  1.2994 +
  1.2995 +            /* Here if an exponent is required, adjust size for
  1.2996 +             * the digits we output but did not count.  The total
  1.2997 +             * digit output here so far is at most 1+precision - no
  1.2998 +             * decimal point and no leading or trailing zeros have
  1.2999 +             * been output.
  1.3000 +             */
  1.3001 +            size -= cdigits;
  1.3002 +
  1.3003 +            *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */
  1.3004 +
  1.3005 +            /* The following use of an unsigned temporary avoids ambiguities in
  1.3006 +             * the signed arithmetic on exp_b10 and permits GCC at least to do
  1.3007 +             * better optimization.
  1.3008 +             */
  1.3009 +            {
  1.3010 +               unsigned int uexp_b10;
  1.3011 +
  1.3012 +               if (exp_b10 < 0)
  1.3013 +               {
  1.3014 +                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
  1.3015 +                  uexp_b10 = -exp_b10;
  1.3016 +               }
  1.3017 +
  1.3018 +               else
  1.3019 +                  uexp_b10 = exp_b10;
  1.3020 +
  1.3021 +               cdigits = 0;
  1.3022 +
  1.3023 +               while (uexp_b10 > 0)
  1.3024 +               {
  1.3025 +                  exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
  1.3026 +                  uexp_b10 /= 10;
  1.3027 +               }
  1.3028 +            }
  1.3029 +
  1.3030 +            /* Need another size check here for the exponent digits, so
  1.3031 +             * this need not be considered above.
  1.3032 +             */
  1.3033 +            if ((int)size > cdigits)
  1.3034 +            {
  1.3035 +               while (cdigits > 0) *ascii++ = exponent[--cdigits];
  1.3036 +
  1.3037 +               *ascii = 0;
  1.3038 +
  1.3039 +               return;
  1.3040 +            }
  1.3041 +         }
  1.3042 +      }
  1.3043 +      else if (!(fp >= DBL_MIN))
  1.3044 +      {
  1.3045 +         *ascii++ = 48; /* '0' */
  1.3046 +         *ascii = 0;
  1.3047 +         return;
  1.3048 +      }
  1.3049 +      else
  1.3050 +      {
  1.3051 +         *ascii++ = 105; /* 'i' */
  1.3052 +         *ascii++ = 110; /* 'n' */
  1.3053 +         *ascii++ = 102; /* 'f' */
  1.3054 +         *ascii = 0;
  1.3055 +         return;
  1.3056 +      }
  1.3057 +   }
  1.3058 +
  1.3059 +   /* Here on buffer too small. */
  1.3060 +   png_error(png_ptr, "ASCII conversion buffer too small");
  1.3061 +}
  1.3062 +
  1.3063 +#  endif /* FLOATING_POINT */
  1.3064 +
  1.3065 +#  ifdef PNG_FIXED_POINT_SUPPORTED
  1.3066 +/* Function to format a fixed point value in ASCII.
  1.3067 + */
  1.3068 +void /* PRIVATE */
  1.3069 +png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
  1.3070 +    png_size_t size, png_fixed_point fp)
  1.3071 +{
  1.3072 +   /* Require space for 10 decimal digits, a decimal point, a minus sign and a
  1.3073 +    * trailing \0, 13 characters:
  1.3074 +    */
  1.3075 +   if (size > 12)
  1.3076 +   {
  1.3077 +      png_uint_32 num;
  1.3078 +
  1.3079 +      /* Avoid overflow here on the minimum integer. */
  1.3080 +      if (fp < 0)
  1.3081 +         *ascii++ = 45, --size, num = -fp;
  1.3082 +      else
  1.3083 +         num = fp;
  1.3084 +
  1.3085 +      if (num <= 0x80000000) /* else overflowed */
  1.3086 +      {
  1.3087 +         unsigned int ndigits = 0, first = 16 /* flag value */;
  1.3088 +         char digits[10];
  1.3089 +
  1.3090 +         while (num)
  1.3091 +         {
  1.3092 +            /* Split the low digit off num: */
  1.3093 +            unsigned int tmp = num/10;
  1.3094 +            num -= tmp*10;
  1.3095 +            digits[ndigits++] = (char)(48 + num);
  1.3096 +            /* Record the first non-zero digit, note that this is a number
  1.3097 +             * starting at 1, it's not actually the array index.
  1.3098 +             */
  1.3099 +            if (first == 16 && num > 0)
  1.3100 +               first = ndigits;
  1.3101 +            num = tmp;
  1.3102 +         }
  1.3103 +
  1.3104 +         if (ndigits > 0)
  1.3105 +         {
  1.3106 +            while (ndigits > 5) *ascii++ = digits[--ndigits];
  1.3107 +            /* The remaining digits are fractional digits, ndigits is '5' or
  1.3108 +             * smaller at this point.  It is certainly not zero.  Check for a
  1.3109 +             * non-zero fractional digit:
  1.3110 +             */
  1.3111 +            if (first <= 5)
  1.3112 +            {
  1.3113 +               unsigned int i;
  1.3114 +               *ascii++ = 46; /* decimal point */
  1.3115 +               /* ndigits may be <5 for small numbers, output leading zeros
  1.3116 +                * then ndigits digits to first:
  1.3117 +                */
  1.3118 +               i = 5;
  1.3119 +               while (ndigits < i) *ascii++ = 48, --i;
  1.3120 +               while (ndigits >= first) *ascii++ = digits[--ndigits];
  1.3121 +               /* Don't output the trailing zeros! */
  1.3122 +            }
  1.3123 +         }
  1.3124 +         else
  1.3125 +            *ascii++ = 48;
  1.3126 +
  1.3127 +         /* And null terminate the string: */
  1.3128 +         *ascii = 0;
  1.3129 +         return;
  1.3130 +      }
  1.3131 +   }
  1.3132 +
  1.3133 +   /* Here on buffer too small. */
  1.3134 +   png_error(png_ptr, "ASCII conversion buffer too small");
  1.3135 +}
  1.3136 +#   endif /* FIXED_POINT */
  1.3137 +#endif /* READ_SCAL */
  1.3138 +
  1.3139 +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
  1.3140 +   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
  1.3141 +   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
  1.3142 +   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
  1.3143 +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
  1.3144 +   (defined(PNG_sCAL_SUPPORTED) && \
  1.3145 +   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
  1.3146 +png_fixed_point
  1.3147 +png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
  1.3148 +{
  1.3149 +   double r = floor(100000 * fp + .5);
  1.3150 +
  1.3151 +   if (r > 2147483647. || r < -2147483648.)
  1.3152 +      png_fixed_error(png_ptr, text);
  1.3153 +
  1.3154 +#  ifndef PNG_ERROR_TEXT_SUPPORTED
  1.3155 +      PNG_UNUSED(text)
  1.3156 +#  endif
  1.3157 +
  1.3158 +   return (png_fixed_point)r;
  1.3159 +}
  1.3160 +#endif
  1.3161 +
  1.3162 +#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
  1.3163 +    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
  1.3164 +/* muldiv functions */
  1.3165 +/* This API takes signed arguments and rounds the result to the nearest
  1.3166 + * integer (or, for a fixed point number - the standard argument - to
  1.3167 + * the nearest .00001).  Overflow and divide by zero are signalled in
  1.3168 + * the result, a boolean - true on success, false on overflow.
  1.3169 + */
  1.3170 +int
  1.3171 +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
  1.3172 +    png_int_32 divisor)
  1.3173 +{
  1.3174 +   /* Return a * times / divisor, rounded. */
  1.3175 +   if (divisor != 0)
  1.3176 +   {
  1.3177 +      if (a == 0 || times == 0)
  1.3178 +      {
  1.3179 +         *res = 0;
  1.3180 +         return 1;
  1.3181 +      }
  1.3182 +      else
  1.3183 +      {
  1.3184 +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3185 +         double r = a;
  1.3186 +         r *= times;
  1.3187 +         r /= divisor;
  1.3188 +         r = floor(r+.5);
  1.3189 +
  1.3190 +         /* A png_fixed_point is a 32-bit integer. */
  1.3191 +         if (r <= 2147483647. && r >= -2147483648.)
  1.3192 +         {
  1.3193 +            *res = (png_fixed_point)r;
  1.3194 +            return 1;
  1.3195 +         }
  1.3196 +#else
  1.3197 +         int negative = 0;
  1.3198 +         png_uint_32 A, T, D;
  1.3199 +         png_uint_32 s16, s32, s00;
  1.3200 +
  1.3201 +         if (a < 0)
  1.3202 +            negative = 1, A = -a;
  1.3203 +         else
  1.3204 +            A = a;
  1.3205 +
  1.3206 +         if (times < 0)
  1.3207 +            negative = !negative, T = -times;
  1.3208 +         else
  1.3209 +            T = times;
  1.3210 +
  1.3211 +         if (divisor < 0)
  1.3212 +            negative = !negative, D = -divisor;
  1.3213 +         else
  1.3214 +            D = divisor;
  1.3215 +
  1.3216 +         /* Following can't overflow because the arguments only
  1.3217 +          * have 31 bits each, however the result may be 32 bits.
  1.3218 +          */
  1.3219 +         s16 = (A >> 16) * (T & 0xffff) +
  1.3220 +                           (A & 0xffff) * (T >> 16);
  1.3221 +         /* Can't overflow because the a*times bit is only 30
  1.3222 +          * bits at most.
  1.3223 +          */
  1.3224 +         s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
  1.3225 +         s00 = (A & 0xffff) * (T & 0xffff);
  1.3226 +
  1.3227 +         s16 = (s16 & 0xffff) << 16;
  1.3228 +         s00 += s16;
  1.3229 +
  1.3230 +         if (s00 < s16)
  1.3231 +            ++s32; /* carry */
  1.3232 +
  1.3233 +         if (s32 < D) /* else overflow */
  1.3234 +         {
  1.3235 +            /* s32.s00 is now the 64-bit product, do a standard
  1.3236 +             * division, we know that s32 < D, so the maximum
  1.3237 +             * required shift is 31.
  1.3238 +             */
  1.3239 +            int bitshift = 32;
  1.3240 +            png_fixed_point result = 0; /* NOTE: signed */
  1.3241 +
  1.3242 +            while (--bitshift >= 0)
  1.3243 +            {
  1.3244 +               png_uint_32 d32, d00;
  1.3245 +
  1.3246 +               if (bitshift > 0)
  1.3247 +                  d32 = D >> (32-bitshift), d00 = D << bitshift;
  1.3248 +
  1.3249 +               else
  1.3250 +                  d32 = 0, d00 = D;
  1.3251 +
  1.3252 +               if (s32 > d32)
  1.3253 +               {
  1.3254 +                  if (s00 < d00) --s32; /* carry */
  1.3255 +                  s32 -= d32, s00 -= d00, result += 1<<bitshift;
  1.3256 +               }
  1.3257 +
  1.3258 +               else
  1.3259 +                  if (s32 == d32 && s00 >= d00)
  1.3260 +                     s32 = 0, s00 -= d00, result += 1<<bitshift;
  1.3261 +            }
  1.3262 +
  1.3263 +            /* Handle the rounding. */
  1.3264 +            if (s00 >= (D >> 1))
  1.3265 +               ++result;
  1.3266 +
  1.3267 +            if (negative)
  1.3268 +               result = -result;
  1.3269 +
  1.3270 +            /* Check for overflow. */
  1.3271 +            if ((negative && result <= 0) || (!negative && result >= 0))
  1.3272 +            {
  1.3273 +               *res = result;
  1.3274 +               return 1;
  1.3275 +            }
  1.3276 +         }
  1.3277 +#endif
  1.3278 +      }
  1.3279 +   }
  1.3280 +
  1.3281 +   return 0;
  1.3282 +}
  1.3283 +#endif /* READ_GAMMA || INCH_CONVERSIONS */
  1.3284 +
  1.3285 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
  1.3286 +/* The following is for when the caller doesn't much care about the
  1.3287 + * result.
  1.3288 + */
  1.3289 +png_fixed_point
  1.3290 +png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
  1.3291 +    png_int_32 divisor)
  1.3292 +{
  1.3293 +   png_fixed_point result;
  1.3294 +
  1.3295 +   if (png_muldiv(&result, a, times, divisor))
  1.3296 +      return result;
  1.3297 +
  1.3298 +   png_warning(png_ptr, "fixed point overflow ignored");
  1.3299 +   return 0;
  1.3300 +}
  1.3301 +#endif
  1.3302 +
  1.3303 +#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
  1.3304 +/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
  1.3305 +png_fixed_point
  1.3306 +png_reciprocal(png_fixed_point a)
  1.3307 +{
  1.3308 +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3309 +   double r = floor(1E10/a+.5);
  1.3310 +
  1.3311 +   if (r <= 2147483647. && r >= -2147483648.)
  1.3312 +      return (png_fixed_point)r;
  1.3313 +#else
  1.3314 +   png_fixed_point res;
  1.3315 +
  1.3316 +   if (png_muldiv(&res, 100000, 100000, a))
  1.3317 +      return res;
  1.3318 +#endif
  1.3319 +
  1.3320 +   return 0; /* error/overflow */
  1.3321 +}
  1.3322 +
  1.3323 +/* This is the shared test on whether a gamma value is 'significant' - whether
  1.3324 + * it is worth doing gamma correction.
  1.3325 + */
  1.3326 +int /* PRIVATE */
  1.3327 +png_gamma_significant(png_fixed_point gamma_val)
  1.3328 +{
  1.3329 +   return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
  1.3330 +       gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
  1.3331 +}
  1.3332 +#endif
  1.3333 +
  1.3334 +#ifdef PNG_READ_GAMMA_SUPPORTED
  1.3335 +#  ifdef PNG_16BIT_SUPPORTED
  1.3336 +/* A local convenience routine. */
  1.3337 +static png_fixed_point
  1.3338 +png_product2(png_fixed_point a, png_fixed_point b)
  1.3339 +{
  1.3340 +   /* The required result is 1/a * 1/b; the following preserves accuracy. */
  1.3341 +#    ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3342 +   double r = a * 1E-5;
  1.3343 +   r *= b;
  1.3344 +   r = floor(r+.5);
  1.3345 +
  1.3346 +   if (r <= 2147483647. && r >= -2147483648.)
  1.3347 +      return (png_fixed_point)r;
  1.3348 +#    else
  1.3349 +   png_fixed_point res;
  1.3350 +
  1.3351 +   if (png_muldiv(&res, a, b, 100000))
  1.3352 +      return res;
  1.3353 +#    endif
  1.3354 +
  1.3355 +   return 0; /* overflow */
  1.3356 +}
  1.3357 +#  endif /* 16BIT */
  1.3358 +
  1.3359 +/* The inverse of the above. */
  1.3360 +png_fixed_point
  1.3361 +png_reciprocal2(png_fixed_point a, png_fixed_point b)
  1.3362 +{
  1.3363 +   /* The required result is 1/a * 1/b; the following preserves accuracy. */
  1.3364 +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3365 +   double r = 1E15/a;
  1.3366 +   r /= b;
  1.3367 +   r = floor(r+.5);
  1.3368 +
  1.3369 +   if (r <= 2147483647. && r >= -2147483648.)
  1.3370 +      return (png_fixed_point)r;
  1.3371 +#else
  1.3372 +   /* This may overflow because the range of png_fixed_point isn't symmetric,
  1.3373 +    * but this API is only used for the product of file and screen gamma so it
  1.3374 +    * doesn't matter that the smallest number it can produce is 1/21474, not
  1.3375 +    * 1/100000
  1.3376 +    */
  1.3377 +   png_fixed_point res = png_product2(a, b);
  1.3378 +
  1.3379 +   if (res != 0)
  1.3380 +      return png_reciprocal(res);
  1.3381 +#endif
  1.3382 +
  1.3383 +   return 0; /* overflow */
  1.3384 +}
  1.3385 +#endif /* READ_GAMMA */
  1.3386 +
  1.3387 +#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
  1.3388 +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3389 +/* Fixed point gamma.
  1.3390 + *
  1.3391 + * The code to calculate the tables used below can be found in the shell script
  1.3392 + * contrib/tools/intgamma.sh
  1.3393 + *
  1.3394 + * To calculate gamma this code implements fast log() and exp() calls using only
  1.3395 + * fixed point arithmetic.  This code has sufficient precision for either 8-bit
  1.3396 + * or 16-bit sample values.
  1.3397 + *
  1.3398 + * The tables used here were calculated using simple 'bc' programs, but C double
  1.3399 + * precision floating point arithmetic would work fine.
  1.3400 + *
  1.3401 + * 8-bit log table
  1.3402 + *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
  1.3403 + *   255, so it's the base 2 logarithm of a normalized 8-bit floating point
  1.3404 + *   mantissa.  The numbers are 32-bit fractions.
  1.3405 + */
  1.3406 +static const png_uint_32
  1.3407 +png_8bit_l2[128] =
  1.3408 +{
  1.3409 +   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
  1.3410 +   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
  1.3411 +   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
  1.3412 +   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
  1.3413 +   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
  1.3414 +   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
  1.3415 +   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
  1.3416 +   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
  1.3417 +   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
  1.3418 +   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
  1.3419 +   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
  1.3420 +   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
  1.3421 +   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
  1.3422 +   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
  1.3423 +   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
  1.3424 +   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
  1.3425 +   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
  1.3426 +   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
  1.3427 +   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
  1.3428 +   324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
  1.3429 +   172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
  1.3430 +   24347096U, 0U
  1.3431 +
  1.3432 +#if 0
  1.3433 +   /* The following are the values for 16-bit tables - these work fine for the
  1.3434 +    * 8-bit conversions but produce very slightly larger errors in the 16-bit
  1.3435 +    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
  1.3436 +    * use these all the shifts below must be adjusted appropriately.
  1.3437 +    */
  1.3438 +   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
  1.3439 +   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
  1.3440 +   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
  1.3441 +   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
  1.3442 +   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
  1.3443 +   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
  1.3444 +   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
  1.3445 +   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
  1.3446 +   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
  1.3447 +   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
  1.3448 +   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
  1.3449 +   1119, 744, 372
  1.3450 +#endif
  1.3451 +};
  1.3452 +
  1.3453 +static png_int_32
  1.3454 +png_log8bit(unsigned int x)
  1.3455 +{
  1.3456 +   unsigned int lg2 = 0;
  1.3457 +   /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
  1.3458 +    * because the log is actually negate that means adding 1.  The final
  1.3459 +    * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
  1.3460 +    * input), return -1 for the overflow (log 0) case, - so the result is
  1.3461 +    * always at most 19 bits.
  1.3462 +    */
  1.3463 +   if ((x &= 0xff) == 0)
  1.3464 +      return -1;
  1.3465 +
  1.3466 +   if ((x & 0xf0) == 0)
  1.3467 +      lg2  = 4, x <<= 4;
  1.3468 +
  1.3469 +   if ((x & 0xc0) == 0)
  1.3470 +      lg2 += 2, x <<= 2;
  1.3471 +
  1.3472 +   if ((x & 0x80) == 0)
  1.3473 +      lg2 += 1, x <<= 1;
  1.3474 +
  1.3475 +   /* result is at most 19 bits, so this cast is safe: */
  1.3476 +   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
  1.3477 +}
  1.3478 +
  1.3479 +/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
  1.3480 + * for 16-bit images we use the most significant 8 bits of the 16-bit value to
  1.3481 + * get an approximation then multiply the approximation by a correction factor
  1.3482 + * determined by the remaining up to 8 bits.  This requires an additional step
  1.3483 + * in the 16-bit case.
  1.3484 + *
  1.3485 + * We want log2(value/65535), we have log2(v'/255), where:
  1.3486 + *
  1.3487 + *    value = v' * 256 + v''
  1.3488 + *          = v' * f
  1.3489 + *
  1.3490 + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
  1.3491 + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
  1.3492 + * than 258.  The final factor also needs to correct for the fact that our 8-bit
  1.3493 + * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
  1.3494 + *
  1.3495 + * This gives a final formula using a calculated value 'x' which is value/v' and
  1.3496 + * scaling by 65536 to match the above table:
  1.3497 + *
  1.3498 + *   log2(x/257) * 65536
  1.3499 + *
  1.3500 + * Since these numbers are so close to '1' we can use simple linear
  1.3501 + * interpolation between the two end values 256/257 (result -368.61) and 258/257
  1.3502 + * (result 367.179).  The values used below are scaled by a further 64 to give
  1.3503 + * 16-bit precision in the interpolation:
  1.3504 + *
  1.3505 + * Start (256): -23591
  1.3506 + * Zero  (257):      0
  1.3507 + * End   (258):  23499
  1.3508 + */
  1.3509 +static png_int_32
  1.3510 +png_log16bit(png_uint_32 x)
  1.3511 +{
  1.3512 +   unsigned int lg2 = 0;
  1.3513 +
  1.3514 +   /* As above, but now the input has 16 bits. */
  1.3515 +   if ((x &= 0xffff) == 0)
  1.3516 +      return -1;
  1.3517 +
  1.3518 +   if ((x & 0xff00) == 0)
  1.3519 +      lg2  = 8, x <<= 8;
  1.3520 +
  1.3521 +   if ((x & 0xf000) == 0)
  1.3522 +      lg2 += 4, x <<= 4;
  1.3523 +
  1.3524 +   if ((x & 0xc000) == 0)
  1.3525 +      lg2 += 2, x <<= 2;
  1.3526 +
  1.3527 +   if ((x & 0x8000) == 0)
  1.3528 +      lg2 += 1, x <<= 1;
  1.3529 +
  1.3530 +   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
  1.3531 +    * value.
  1.3532 +    */
  1.3533 +   lg2 <<= 28;
  1.3534 +   lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
  1.3535 +
  1.3536 +   /* Now we need to interpolate the factor, this requires a division by the top
  1.3537 +    * 8 bits.  Do this with maximum precision.
  1.3538 +    */
  1.3539 +   x = ((x << 16) + (x >> 9)) / (x >> 8);
  1.3540 +
  1.3541 +   /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
  1.3542 +    * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
  1.3543 +    * 16 bits to interpolate to get the low bits of the result.  Round the
  1.3544 +    * answer.  Note that the end point values are scaled by 64 to retain overall
  1.3545 +    * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
  1.3546 +    * the overall scaling by 6-12.  Round at every step.
  1.3547 +    */
  1.3548 +   x -= 1U << 24;
  1.3549 +
  1.3550 +   if (x <= 65536U) /* <= '257' */
  1.3551 +      lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
  1.3552 +
  1.3553 +   else
  1.3554 +      lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
  1.3555 +
  1.3556 +   /* Safe, because the result can't have more than 20 bits: */
  1.3557 +   return (png_int_32)((lg2 + 2048) >> 12);
  1.3558 +}
  1.3559 +
  1.3560 +/* The 'exp()' case must invert the above, taking a 20-bit fixed point
  1.3561 + * logarithmic value and returning a 16 or 8-bit number as appropriate.  In
  1.3562 + * each case only the low 16 bits are relevant - the fraction - since the
  1.3563 + * integer bits (the top 4) simply determine a shift.
  1.3564 + *
  1.3565 + * The worst case is the 16-bit distinction between 65535 and 65534, this
  1.3566 + * requires perhaps spurious accuracty in the decoding of the logarithm to
  1.3567 + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance
  1.3568 + * of getting this accuracy in practice.
  1.3569 + *
  1.3570 + * To deal with this the following exp() function works out the exponent of the
  1.3571 + * frational part of the logarithm by using an accurate 32-bit value from the
  1.3572 + * top four fractional bits then multiplying in the remaining bits.
  1.3573 + */
  1.3574 +static const png_uint_32
  1.3575 +png_32bit_exp[16] =
  1.3576 +{
  1.3577 +   /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
  1.3578 +   4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
  1.3579 +   3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
  1.3580 +   2553802834U, 2445529972U, 2341847524U, 2242560872U
  1.3581 +};
  1.3582 +
  1.3583 +/* Adjustment table; provided to explain the numbers in the code below. */
  1.3584 +#if 0
  1.3585 +for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
  1.3586 +   11 44937.64284865548751208448
  1.3587 +   10 45180.98734845585101160448
  1.3588 +    9 45303.31936980687359311872
  1.3589 +    8 45364.65110595323018870784
  1.3590 +    7 45395.35850361789624614912
  1.3591 +    6 45410.72259715102037508096
  1.3592 +    5 45418.40724413220722311168
  1.3593 +    4 45422.25021786898173001728
  1.3594 +    3 45424.17186732298419044352
  1.3595 +    2 45425.13273269940811464704
  1.3596 +    1 45425.61317555035558641664
  1.3597 +    0 45425.85339951654943850496
  1.3598 +#endif
  1.3599 +
  1.3600 +static png_uint_32
  1.3601 +png_exp(png_fixed_point x)
  1.3602 +{
  1.3603 +   if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
  1.3604 +   {
  1.3605 +      /* Obtain a 4-bit approximation */
  1.3606 +      png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];
  1.3607 +
  1.3608 +      /* Incorporate the low 12 bits - these decrease the returned value by
  1.3609 +       * multiplying by a number less than 1 if the bit is set.  The multiplier
  1.3610 +       * is determined by the above table and the shift. Notice that the values
  1.3611 +       * converge on 45426 and this is used to allow linear interpolation of the
  1.3612 +       * low bits.
  1.3613 +       */
  1.3614 +      if (x & 0x800)
  1.3615 +         e -= (((e >> 16) * 44938U) +  16U) >> 5;
  1.3616 +
  1.3617 +      if (x & 0x400)
  1.3618 +         e -= (((e >> 16) * 45181U) +  32U) >> 6;
  1.3619 +
  1.3620 +      if (x & 0x200)
  1.3621 +         e -= (((e >> 16) * 45303U) +  64U) >> 7;
  1.3622 +
  1.3623 +      if (x & 0x100)
  1.3624 +         e -= (((e >> 16) * 45365U) + 128U) >> 8;
  1.3625 +
  1.3626 +      if (x & 0x080)
  1.3627 +         e -= (((e >> 16) * 45395U) + 256U) >> 9;
  1.3628 +
  1.3629 +      if (x & 0x040)
  1.3630 +         e -= (((e >> 16) * 45410U) + 512U) >> 10;
  1.3631 +
  1.3632 +      /* And handle the low 6 bits in a single block. */
  1.3633 +      e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
  1.3634 +
  1.3635 +      /* Handle the upper bits of x. */
  1.3636 +      e >>= x >> 16;
  1.3637 +      return e;
  1.3638 +   }
  1.3639 +
  1.3640 +   /* Check for overflow */
  1.3641 +   if (x <= 0)
  1.3642 +      return png_32bit_exp[0];
  1.3643 +
  1.3644 +   /* Else underflow */
  1.3645 +   return 0;
  1.3646 +}
  1.3647 +
  1.3648 +static png_byte
  1.3649 +png_exp8bit(png_fixed_point lg2)
  1.3650 +{
  1.3651 +   /* Get a 32-bit value: */
  1.3652 +   png_uint_32 x = png_exp(lg2);
  1.3653 +
  1.3654 +   /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the
  1.3655 +    * second, rounding, step can't overflow because of the first, subtraction,
  1.3656 +    * step.
  1.3657 +    */
  1.3658 +   x -= x >> 8;
  1.3659 +   return (png_byte)((x + 0x7fffffU) >> 24);
  1.3660 +}
  1.3661 +
  1.3662 +#ifdef PNG_16BIT_SUPPORTED
  1.3663 +static png_uint_16
  1.3664 +png_exp16bit(png_fixed_point lg2)
  1.3665 +{
  1.3666 +   /* Get a 32-bit value: */
  1.3667 +   png_uint_32 x = png_exp(lg2);
  1.3668 +
  1.3669 +   /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
  1.3670 +   x -= x >> 16;
  1.3671 +   return (png_uint_16)((x + 32767U) >> 16);
  1.3672 +}
  1.3673 +#endif /* 16BIT */
  1.3674 +#endif /* FLOATING_ARITHMETIC */
  1.3675 +
  1.3676 +png_byte
  1.3677 +png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
  1.3678 +{
  1.3679 +   if (value > 0 && value < 255)
  1.3680 +   {
  1.3681 +#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3682 +         double r = floor(255*pow(value/255.,gamma_val*.00001)+.5);
  1.3683 +         return (png_byte)r;
  1.3684 +#     else
  1.3685 +         png_int_32 lg2 = png_log8bit(value);
  1.3686 +         png_fixed_point res;
  1.3687 +
  1.3688 +         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
  1.3689 +            return png_exp8bit(res);
  1.3690 +
  1.3691 +         /* Overflow. */
  1.3692 +         value = 0;
  1.3693 +#     endif
  1.3694 +   }
  1.3695 +
  1.3696 +   return (png_byte)value;
  1.3697 +}
  1.3698 +
  1.3699 +#ifdef PNG_16BIT_SUPPORTED
  1.3700 +png_uint_16
  1.3701 +png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
  1.3702 +{
  1.3703 +   if (value > 0 && value < 65535)
  1.3704 +   {
  1.3705 +#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3706 +         double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5);
  1.3707 +         return (png_uint_16)r;
  1.3708 +#     else
  1.3709 +         png_int_32 lg2 = png_log16bit(value);
  1.3710 +         png_fixed_point res;
  1.3711 +
  1.3712 +         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
  1.3713 +            return png_exp16bit(res);
  1.3714 +
  1.3715 +         /* Overflow. */
  1.3716 +         value = 0;
  1.3717 +#     endif
  1.3718 +   }
  1.3719 +
  1.3720 +   return (png_uint_16)value;
  1.3721 +}
  1.3722 +#endif /* 16BIT */
  1.3723 +
  1.3724 +/* This does the right thing based on the bit_depth field of the
  1.3725 + * png_struct, interpreting values as 8-bit or 16-bit.  While the result
  1.3726 + * is nominally a 16-bit value if bit depth is 8 then the result is
  1.3727 + * 8-bit (as are the arguments.)
  1.3728 + */
  1.3729 +png_uint_16 /* PRIVATE */
  1.3730 +png_gamma_correct(png_structrp png_ptr, unsigned int value,
  1.3731 +    png_fixed_point gamma_val)
  1.3732 +{
  1.3733 +   if (png_ptr->bit_depth == 8)
  1.3734 +      return png_gamma_8bit_correct(value, gamma_val);
  1.3735 +
  1.3736 +#ifdef PNG_16BIT_SUPPORTED
  1.3737 +   else
  1.3738 +      return png_gamma_16bit_correct(value, gamma_val);
  1.3739 +#else
  1.3740 +      /* should not reach this */
  1.3741 +      return 0;
  1.3742 +#endif /* 16BIT */
  1.3743 +}
  1.3744 +
  1.3745 +#ifdef PNG_16BIT_SUPPORTED
  1.3746 +/* Internal function to build a single 16-bit table - the table consists of
  1.3747 + * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
  1.3748 + * to shift the input values right (or 16-number_of_signifiant_bits).
  1.3749 + *
  1.3750 + * The caller is responsible for ensuring that the table gets cleaned up on
  1.3751 + * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
  1.3752 + * should be somewhere that will be cleaned.
  1.3753 + */
  1.3754 +static void
  1.3755 +png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
  1.3756 +   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
  1.3757 +{
  1.3758 +   /* Various values derived from 'shift': */
  1.3759 +   PNG_CONST unsigned int num = 1U << (8U - shift);
  1.3760 +   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
  1.3761 +   PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
  1.3762 +   unsigned int i;
  1.3763 +
  1.3764 +   png_uint_16pp table = *ptable =
  1.3765 +       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
  1.3766 +
  1.3767 +   for (i = 0; i < num; i++)
  1.3768 +   {
  1.3769 +      png_uint_16p sub_table = table[i] =
  1.3770 +          (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));
  1.3771 +
  1.3772 +      /* The 'threshold' test is repeated here because it can arise for one of
  1.3773 +       * the 16-bit tables even if the others don't hit it.
  1.3774 +       */
  1.3775 +      if (png_gamma_significant(gamma_val))
  1.3776 +      {
  1.3777 +         /* The old code would overflow at the end and this would cause the
  1.3778 +          * 'pow' function to return a result >1, resulting in an
  1.3779 +          * arithmetic error.  This code follows the spec exactly; ig is
  1.3780 +          * the recovered input sample, it always has 8-16 bits.
  1.3781 +          *
  1.3782 +          * We want input * 65535/max, rounded, the arithmetic fits in 32
  1.3783 +          * bits (unsigned) so long as max <= 32767.
  1.3784 +          */
  1.3785 +         unsigned int j;
  1.3786 +         for (j = 0; j < 256; j++)
  1.3787 +         {
  1.3788 +            png_uint_32 ig = (j << (8-shift)) + i;
  1.3789 +#           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
  1.3790 +               /* Inline the 'max' scaling operation: */
  1.3791 +               double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5);
  1.3792 +               sub_table[j] = (png_uint_16)d;
  1.3793 +#           else
  1.3794 +               if (shift)
  1.3795 +                  ig = (ig * 65535U + max_by_2)/max;
  1.3796 +
  1.3797 +               sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
  1.3798 +#           endif
  1.3799 +         }
  1.3800 +      }
  1.3801 +      else
  1.3802 +      {
  1.3803 +         /* We must still build a table, but do it the fast way. */
  1.3804 +         unsigned int j;
  1.3805 +
  1.3806 +         for (j = 0; j < 256; j++)
  1.3807 +         {
  1.3808 +            png_uint_32 ig = (j << (8-shift)) + i;
  1.3809 +
  1.3810 +            if (shift)
  1.3811 +               ig = (ig * 65535U + max_by_2)/max;
  1.3812 +
  1.3813 +            sub_table[j] = (png_uint_16)ig;
  1.3814 +         }
  1.3815 +      }
  1.3816 +   }
  1.3817 +}
  1.3818 +
  1.3819 +/* NOTE: this function expects the *inverse* of the overall gamma transformation
  1.3820 + * required.
  1.3821 + */
  1.3822 +static void
  1.3823 +png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
  1.3824 +   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
  1.3825 +{
  1.3826 +   PNG_CONST unsigned int num = 1U << (8U - shift);
  1.3827 +   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
  1.3828 +   unsigned int i;
  1.3829 +   png_uint_32 last;
  1.3830 +
  1.3831 +   png_uint_16pp table = *ptable =
  1.3832 +       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
  1.3833 +
  1.3834 +   /* 'num' is the number of tables and also the number of low bits of low
  1.3835 +    * bits of the input 16-bit value used to select a table.  Each table is
  1.3836 +    * itself index by the high 8 bits of the value.
  1.3837 +    */
  1.3838 +   for (i = 0; i < num; i++)
  1.3839 +      table[i] = (png_uint_16p)png_malloc(png_ptr,
  1.3840 +          256 * (sizeof (png_uint_16)));
  1.3841 +
  1.3842 +   /* 'gamma_val' is set to the reciprocal of the value calculated above, so
  1.3843 +    * pow(out,g) is an *input* value.  'last' is the last input value set.
  1.3844 +    *
  1.3845 +    * In the loop 'i' is used to find output values.  Since the output is
  1.3846 +    * 8-bit there are only 256 possible values.  The tables are set up to
  1.3847 +    * select the closest possible output value for each input by finding
  1.3848 +    * the input value at the boundary between each pair of output values
  1.3849 +    * and filling the table up to that boundary with the lower output
  1.3850 +    * value.
  1.3851 +    *
  1.3852 +    * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit
  1.3853 +    * values the code below uses a 16-bit value in i; the values start at
  1.3854 +    * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
  1.3855 +    * entries are filled with 255).  Start i at 128 and fill all 'last'
  1.3856 +    * table entries <= 'max'
  1.3857 +    */
  1.3858 +   last = 0;
  1.3859 +   for (i = 0; i < 255; ++i) /* 8-bit output value */
  1.3860 +   {
  1.3861 +      /* Find the corresponding maximum input value */
  1.3862 +      png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
  1.3863 +
  1.3864 +      /* Find the boundary value in 16 bits: */
  1.3865 +      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
  1.3866 +
  1.3867 +      /* Adjust (round) to (16-shift) bits: */
  1.3868 +      bound = (bound * max + 32768U)/65535U + 1U;
  1.3869 +
  1.3870 +      while (last < bound)
  1.3871 +      {
  1.3872 +         table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
  1.3873 +         last++;
  1.3874 +      }
  1.3875 +   }
  1.3876 +
  1.3877 +   /* And fill in the final entries. */
  1.3878 +   while (last < (num << 8))
  1.3879 +   {
  1.3880 +      table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
  1.3881 +      last++;
  1.3882 +   }
  1.3883 +}
  1.3884 +#endif /* 16BIT */
  1.3885 +
  1.3886 +/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
  1.3887 + * typically much faster).  Note that libpng currently does no sBIT processing
  1.3888 + * (apparently contrary to the spec) so a 256 entry table is always generated.
  1.3889 + */
  1.3890 +static void
  1.3891 +png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
  1.3892 +   PNG_CONST png_fixed_point gamma_val)
  1.3893 +{
  1.3894 +   unsigned int i;
  1.3895 +   png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
  1.3896 +
  1.3897 +   if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++)
  1.3898 +      table[i] = png_gamma_8bit_correct(i, gamma_val);
  1.3899 +
  1.3900 +   else for (i=0; i<256; ++i)
  1.3901 +      table[i] = (png_byte)i;
  1.3902 +}
  1.3903 +
  1.3904 +/* Used from png_read_destroy and below to release the memory used by the gamma
  1.3905 + * tables.
  1.3906 + */
  1.3907 +void /* PRIVATE */
  1.3908 +png_destroy_gamma_table(png_structrp png_ptr)
  1.3909 +{
  1.3910 +   png_free(png_ptr, png_ptr->gamma_table);
  1.3911 +   png_ptr->gamma_table = NULL;
  1.3912 +
  1.3913 +#ifdef PNG_16BIT_SUPPORTED
  1.3914 +   if (png_ptr->gamma_16_table != NULL)
  1.3915 +   {
  1.3916 +      int i;
  1.3917 +      int istop = (1 << (8 - png_ptr->gamma_shift));
  1.3918 +      for (i = 0; i < istop; i++)
  1.3919 +      {
  1.3920 +         png_free(png_ptr, png_ptr->gamma_16_table[i]);
  1.3921 +      }
  1.3922 +   png_free(png_ptr, png_ptr->gamma_16_table);
  1.3923 +   png_ptr->gamma_16_table = NULL;
  1.3924 +   }
  1.3925 +#endif /* 16BIT */
  1.3926 +
  1.3927 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
  1.3928 +   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
  1.3929 +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1.3930 +   png_free(png_ptr, png_ptr->gamma_from_1);
  1.3931 +   png_ptr->gamma_from_1 = NULL;
  1.3932 +   png_free(png_ptr, png_ptr->gamma_to_1);
  1.3933 +   png_ptr->gamma_to_1 = NULL;
  1.3934 +
  1.3935 +#ifdef PNG_16BIT_SUPPORTED
  1.3936 +   if (png_ptr->gamma_16_from_1 != NULL)
  1.3937 +   {
  1.3938 +      int i;
  1.3939 +      int istop = (1 << (8 - png_ptr->gamma_shift));
  1.3940 +      for (i = 0; i < istop; i++)
  1.3941 +      {
  1.3942 +         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
  1.3943 +      }
  1.3944 +   png_free(png_ptr, png_ptr->gamma_16_from_1);
  1.3945 +   png_ptr->gamma_16_from_1 = NULL;
  1.3946 +   }
  1.3947 +   if (png_ptr->gamma_16_to_1 != NULL)
  1.3948 +   {
  1.3949 +      int i;
  1.3950 +      int istop = (1 << (8 - png_ptr->gamma_shift));
  1.3951 +      for (i = 0; i < istop; i++)
  1.3952 +      {
  1.3953 +         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
  1.3954 +      }
  1.3955 +   png_free(png_ptr, png_ptr->gamma_16_to_1);
  1.3956 +   png_ptr->gamma_16_to_1 = NULL;
  1.3957 +   }
  1.3958 +#endif /* 16BIT */
  1.3959 +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
  1.3960 +}
  1.3961 +
  1.3962 +/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
  1.3963 + * tables, we don't make a full table if we are reducing to 8-bit in
  1.3964 + * the future.  Note also how the gamma_16 tables are segmented so that
  1.3965 + * we don't need to allocate > 64K chunks for a full 16-bit table.
  1.3966 + */
  1.3967 +void /* PRIVATE */
  1.3968 +png_build_gamma_table(png_structrp png_ptr, int bit_depth)
  1.3969 +{
  1.3970 +  png_debug(1, "in png_build_gamma_table");
  1.3971 +
  1.3972 +  /* Remove any existing table; this copes with multiple calls to
  1.3973 +   * png_read_update_info.  The warning is because building the gamma tables
  1.3974 +   * multiple times is a performance hit - it's harmless but the ability to call
  1.3975 +   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
  1.3976 +   * to warn if the app introduces such a hit.
  1.3977 +   */
  1.3978 +  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
  1.3979 +  {
  1.3980 +    png_warning(png_ptr, "gamma table being rebuilt");
  1.3981 +    png_destroy_gamma_table(png_ptr);
  1.3982 +  }
  1.3983 +
  1.3984 +  if (bit_depth <= 8)
  1.3985 +  {
  1.3986 +     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
  1.3987 +         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->colorspace.gamma,
  1.3988 +         png_ptr->screen_gamma) : PNG_FP_1);
  1.3989 +
  1.3990 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
  1.3991 +   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
  1.3992 +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1.3993 +     if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
  1.3994 +     {
  1.3995 +        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
  1.3996 +            png_reciprocal(png_ptr->colorspace.gamma));
  1.3997 +
  1.3998 +        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
  1.3999 +            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
  1.4000 +            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
  1.4001 +     }
  1.4002 +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
  1.4003 +  }
  1.4004 +#ifdef PNG_16BIT_SUPPORTED
  1.4005 +  else
  1.4006 +  {
  1.4007 +     png_byte shift, sig_bit;
  1.4008 +
  1.4009 +     if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1.4010 +     {
  1.4011 +        sig_bit = png_ptr->sig_bit.red;
  1.4012 +
  1.4013 +        if (png_ptr->sig_bit.green > sig_bit)
  1.4014 +           sig_bit = png_ptr->sig_bit.green;
  1.4015 +
  1.4016 +        if (png_ptr->sig_bit.blue > sig_bit)
  1.4017 +           sig_bit = png_ptr->sig_bit.blue;
  1.4018 +     }
  1.4019 +     else
  1.4020 +        sig_bit = png_ptr->sig_bit.gray;
  1.4021 +
  1.4022 +     /* 16-bit gamma code uses this equation:
  1.4023 +      *
  1.4024 +      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
  1.4025 +      *
  1.4026 +      * Where 'iv' is the input color value and 'ov' is the output value -
  1.4027 +      * pow(iv, gamma).
  1.4028 +      *
  1.4029 +      * Thus the gamma table consists of up to 256 256 entry tables.  The table
  1.4030 +      * is selected by the (8-gamma_shift) most significant of the low 8 bits of
  1.4031 +      * the color value then indexed by the upper 8 bits:
  1.4032 +      *
  1.4033 +      *   table[low bits][high 8 bits]
  1.4034 +      *
  1.4035 +      * So the table 'n' corresponds to all those 'iv' of:
  1.4036 +      *
  1.4037 +      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
  1.4038 +      *
  1.4039 +      */
  1.4040 +     if (sig_bit > 0 && sig_bit < 16U)
  1.4041 +        shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
  1.4042 +
  1.4043 +     else
  1.4044 +        shift = 0; /* keep all 16 bits */
  1.4045 +
  1.4046 +     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
  1.4047 +     {
  1.4048 +        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
  1.4049 +         * the significant bits in the *input* when the output will
  1.4050 +         * eventually be 8 bits.  By default it is 11.
  1.4051 +         */
  1.4052 +        if (shift < (16U - PNG_MAX_GAMMA_8))
  1.4053 +           shift = (16U - PNG_MAX_GAMMA_8);
  1.4054 +     }
  1.4055 +
  1.4056 +     if (shift > 8U)
  1.4057 +        shift = 8U; /* Guarantees at least one table! */
  1.4058 +
  1.4059 +     png_ptr->gamma_shift = shift;
  1.4060 +
  1.4061 +     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
  1.4062 +      * PNG_COMPOSE).  This effectively smashed the background calculation for
  1.4063 +      * 16-bit output because the 8-bit table assumes the result will be reduced
  1.4064 +      * to 8 bits.
  1.4065 +      */
  1.4066 +     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
  1.4067 +         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
  1.4068 +         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
  1.4069 +         png_ptr->screen_gamma) : PNG_FP_1);
  1.4070 +
  1.4071 +     else
  1.4072 +         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
  1.4073 +         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
  1.4074 +         png_ptr->screen_gamma) : PNG_FP_1);
  1.4075 +
  1.4076 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
  1.4077 +   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
  1.4078 +   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1.4079 +     if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
  1.4080 +     {
  1.4081 +        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
  1.4082 +            png_reciprocal(png_ptr->colorspace.gamma));
  1.4083 +
  1.4084 +        /* Notice that the '16 from 1' table should be full precision, however
  1.4085 +         * the lookup on this table still uses gamma_shift, so it can't be.
  1.4086 +         * TODO: fix this.
  1.4087 +         */
  1.4088 +        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
  1.4089 +            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
  1.4090 +            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
  1.4091 +     }
  1.4092 +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
  1.4093 +  }
  1.4094 +#endif /* 16BIT */
  1.4095 +}
  1.4096 +#endif /* READ_GAMMA */
  1.4097 +
  1.4098 +/* HARDWARE OPTION SUPPORT */
  1.4099 +#ifdef PNG_SET_OPTION_SUPPORTED
  1.4100 +int PNGAPI
  1.4101 +png_set_option(png_structrp png_ptr, int option, int onoff)
  1.4102 +{
  1.4103 +   if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
  1.4104 +      (option & 1) == 0)
  1.4105 +   {
  1.4106 +      int mask = 3 << option;
  1.4107 +      int setting = (2 + (onoff != 0)) << option;
  1.4108 +      int current = png_ptr->options;
  1.4109 +
  1.4110 +      png_ptr->options = (png_byte)((current & ~mask) | setting);
  1.4111 +
  1.4112 +      return (current & mask) >> option;
  1.4113 +   }
  1.4114 +
  1.4115 +   return PNG_OPTION_INVALID;
  1.4116 +}
  1.4117 +#endif
  1.4118 +
  1.4119 +/* sRGB support */
  1.4120 +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
  1.4121 +   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
  1.4122 +/* sRGB conversion tables; these are machine generated with the code in
  1.4123 + * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
  1.4124 + * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
  1.4125 + * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
  1.4126 + * The sRGB to linear table is exact (to the nearest 16 bit linear fraction).
  1.4127 + * The inverse (linear to sRGB) table has accuracies as follows:
  1.4128 + *
  1.4129 + * For all possible (255*65535+1) input values:
  1.4130 + *
  1.4131 + *    error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
  1.4132 + *
  1.4133 + * For the input values corresponding to the 65536 16-bit values:
  1.4134 + *
  1.4135 + *    error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
  1.4136 + *
  1.4137 + * In all cases the inexact readings are off by one.
  1.4138 + */
  1.4139 +
  1.4140 +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
  1.4141 +/* The convert-to-sRGB table is only currently required for read. */
  1.4142 +const png_uint_16 png_sRGB_table[256] =
  1.4143 +{
  1.4144 +   0,20,40,60,80,99,119,139,
  1.4145 +   159,179,199,219,241,264,288,313,
  1.4146 +   340,367,396,427,458,491,526,562,
  1.4147 +   599,637,677,718,761,805,851,898,
  1.4148 +   947,997,1048,1101,1156,1212,1270,1330,
  1.4149 +   1391,1453,1517,1583,1651,1720,1790,1863,
  1.4150 +   1937,2013,2090,2170,2250,2333,2418,2504,
  1.4151 +   2592,2681,2773,2866,2961,3058,3157,3258,
  1.4152 +   3360,3464,3570,3678,3788,3900,4014,4129,
  1.4153 +   4247,4366,4488,4611,4736,4864,4993,5124,
  1.4154 +   5257,5392,5530,5669,5810,5953,6099,6246,
  1.4155 +   6395,6547,6700,6856,7014,7174,7335,7500,
  1.4156 +   7666,7834,8004,8177,8352,8528,8708,8889,
  1.4157 +   9072,9258,9445,9635,9828,10022,10219,10417,
  1.4158 +   10619,10822,11028,11235,11446,11658,11873,12090,
  1.4159 +   12309,12530,12754,12980,13209,13440,13673,13909,
  1.4160 +   14146,14387,14629,14874,15122,15371,15623,15878,
  1.4161 +   16135,16394,16656,16920,17187,17456,17727,18001,
  1.4162 +   18277,18556,18837,19121,19407,19696,19987,20281,
  1.4163 +   20577,20876,21177,21481,21787,22096,22407,22721,
  1.4164 +   23038,23357,23678,24002,24329,24658,24990,25325,
  1.4165 +   25662,26001,26344,26688,27036,27386,27739,28094,
  1.4166 +   28452,28813,29176,29542,29911,30282,30656,31033,
  1.4167 +   31412,31794,32179,32567,32957,33350,33745,34143,
  1.4168 +   34544,34948,35355,35764,36176,36591,37008,37429,
  1.4169 +   37852,38278,38706,39138,39572,40009,40449,40891,
  1.4170 +   41337,41785,42236,42690,43147,43606,44069,44534,
  1.4171 +   45002,45473,45947,46423,46903,47385,47871,48359,
  1.4172 +   48850,49344,49841,50341,50844,51349,51858,52369,
  1.4173 +   52884,53401,53921,54445,54971,55500,56032,56567,
  1.4174 +   57105,57646,58190,58737,59287,59840,60396,60955,
  1.4175 +   61517,62082,62650,63221,63795,64372,64952,65535
  1.4176 +};
  1.4177 +
  1.4178 +#endif /* simplified read only */
  1.4179 +
  1.4180 +/* The base/delta tables are required for both read and write (but currently
  1.4181 + * only the simplified versions.)
  1.4182 + */
  1.4183 +const png_uint_16 png_sRGB_base[512] =
  1.4184 +{
  1.4185 +   128,1782,3383,4644,5675,6564,7357,8074,
  1.4186 +   8732,9346,9921,10463,10977,11466,11935,12384,
  1.4187 +   12816,13233,13634,14024,14402,14769,15125,15473,
  1.4188 +   15812,16142,16466,16781,17090,17393,17690,17981,
  1.4189 +   18266,18546,18822,19093,19359,19621,19879,20133,
  1.4190 +   20383,20630,20873,21113,21349,21583,21813,22041,
  1.4191 +   22265,22487,22707,22923,23138,23350,23559,23767,
  1.4192 +   23972,24175,24376,24575,24772,24967,25160,25352,
  1.4193 +   25542,25730,25916,26101,26284,26465,26645,26823,
  1.4194 +   27000,27176,27350,27523,27695,27865,28034,28201,
  1.4195 +   28368,28533,28697,28860,29021,29182,29341,29500,
  1.4196 +   29657,29813,29969,30123,30276,30429,30580,30730,
  1.4197 +   30880,31028,31176,31323,31469,31614,31758,31902,
  1.4198 +   32045,32186,32327,32468,32607,32746,32884,33021,
  1.4199 +   33158,33294,33429,33564,33697,33831,33963,34095,
  1.4200 +   34226,34357,34486,34616,34744,34873,35000,35127,
  1.4201 +   35253,35379,35504,35629,35753,35876,35999,36122,
  1.4202 +   36244,36365,36486,36606,36726,36845,36964,37083,
  1.4203 +   37201,37318,37435,37551,37668,37783,37898,38013,
  1.4204 +   38127,38241,38354,38467,38580,38692,38803,38915,
  1.4205 +   39026,39136,39246,39356,39465,39574,39682,39790,
  1.4206 +   39898,40005,40112,40219,40325,40431,40537,40642,
  1.4207 +   40747,40851,40955,41059,41163,41266,41369,41471,
  1.4208 +   41573,41675,41777,41878,41979,42079,42179,42279,
  1.4209 +   42379,42478,42577,42676,42775,42873,42971,43068,
  1.4210 +   43165,43262,43359,43456,43552,43648,43743,43839,
  1.4211 +   43934,44028,44123,44217,44311,44405,44499,44592,
  1.4212 +   44685,44778,44870,44962,45054,45146,45238,45329,
  1.4213 +   45420,45511,45601,45692,45782,45872,45961,46051,
  1.4214 +   46140,46229,46318,46406,46494,46583,46670,46758,
  1.4215 +   46846,46933,47020,47107,47193,47280,47366,47452,
  1.4216 +   47538,47623,47709,47794,47879,47964,48048,48133,
  1.4217 +   48217,48301,48385,48468,48552,48635,48718,48801,
  1.4218 +   48884,48966,49048,49131,49213,49294,49376,49458,
  1.4219 +   49539,49620,49701,49782,49862,49943,50023,50103,
  1.4220 +   50183,50263,50342,50422,50501,50580,50659,50738,
  1.4221 +   50816,50895,50973,51051,51129,51207,51285,51362,
  1.4222 +   51439,51517,51594,51671,51747,51824,51900,51977,
  1.4223 +   52053,52129,52205,52280,52356,52432,52507,52582,
  1.4224 +   52657,52732,52807,52881,52956,53030,53104,53178,
  1.4225 +   53252,53326,53400,53473,53546,53620,53693,53766,
  1.4226 +   53839,53911,53984,54056,54129,54201,54273,54345,
  1.4227 +   54417,54489,54560,54632,54703,54774,54845,54916,
  1.4228 +   54987,55058,55129,55199,55269,55340,55410,55480,
  1.4229 +   55550,55620,55689,55759,55828,55898,55967,56036,
  1.4230 +   56105,56174,56243,56311,56380,56448,56517,56585,
  1.4231 +   56653,56721,56789,56857,56924,56992,57059,57127,
  1.4232 +   57194,57261,57328,57395,57462,57529,57595,57662,
  1.4233 +   57728,57795,57861,57927,57993,58059,58125,58191,
  1.4234 +   58256,58322,58387,58453,58518,58583,58648,58713,
  1.4235 +   58778,58843,58908,58972,59037,59101,59165,59230,
  1.4236 +   59294,59358,59422,59486,59549,59613,59677,59740,
  1.4237 +   59804,59867,59930,59993,60056,60119,60182,60245,
  1.4238 +   60308,60370,60433,60495,60558,60620,60682,60744,
  1.4239 +   60806,60868,60930,60992,61054,61115,61177,61238,
  1.4240 +   61300,61361,61422,61483,61544,61605,61666,61727,
  1.4241 +   61788,61848,61909,61969,62030,62090,62150,62211,
  1.4242 +   62271,62331,62391,62450,62510,62570,62630,62689,
  1.4243 +   62749,62808,62867,62927,62986,63045,63104,63163,
  1.4244 +   63222,63281,63340,63398,63457,63515,63574,63632,
  1.4245 +   63691,63749,63807,63865,63923,63981,64039,64097,
  1.4246 +   64155,64212,64270,64328,64385,64443,64500,64557,
  1.4247 +   64614,64672,64729,64786,64843,64900,64956,65013,
  1.4248 +   65070,65126,65183,65239,65296,65352,65409,65465
  1.4249 +};
  1.4250 +
  1.4251 +const png_byte png_sRGB_delta[512] =
  1.4252 +{
  1.4253 +   207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
  1.4254 +   52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
  1.4255 +   35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
  1.4256 +   28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
  1.4257 +   23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
  1.4258 +   21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
  1.4259 +   19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
  1.4260 +   17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
  1.4261 +   16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
  1.4262 +   15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
  1.4263 +   14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
  1.4264 +   13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
  1.4265 +   12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
  1.4266 +   12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
  1.4267 +   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
  1.4268 +   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
  1.4269 +   11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  1.4270 +   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  1.4271 +   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  1.4272 +   10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  1.4273 +   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  1.4274 +   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  1.4275 +   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  1.4276 +   9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  1.4277 +   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  1.4278 +   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  1.4279 +   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  1.4280 +   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  1.4281 +   8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
  1.4282 +   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1.4283 +   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1.4284 +   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  1.4285 +};
  1.4286 +#endif /* SIMPLIFIED READ/WRITE sRGB support */
  1.4287 +
  1.4288 +/* SIMPLIFIED READ/WRITE SUPPORT */
  1.4289 +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
  1.4290 +   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
  1.4291 +static int
  1.4292 +png_image_free_function(png_voidp argument)
  1.4293 +{
  1.4294 +   png_imagep image = png_voidcast(png_imagep, argument);
  1.4295 +   png_controlp cp = image->opaque;
  1.4296 +   png_control c;
  1.4297 +
  1.4298 +   /* Double check that we have a png_ptr - it should be impossible to get here
  1.4299 +    * without one.
  1.4300 +    */
  1.4301 +   if (cp->png_ptr == NULL)
  1.4302 +      return 0;
  1.4303 +
  1.4304 +   /* First free any data held in the control structure. */
  1.4305 +#  ifdef PNG_STDIO_SUPPORTED
  1.4306 +      if (cp->owned_file)
  1.4307 +      {
  1.4308 +         FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
  1.4309 +         cp->owned_file = 0;
  1.4310 +
  1.4311 +         /* Ignore errors here. */
  1.4312 +         if (fp != NULL)
  1.4313 +         {
  1.4314 +            cp->png_ptr->io_ptr = NULL;
  1.4315 +            (void)fclose(fp);
  1.4316 +         }
  1.4317 +      }
  1.4318 +#  endif
  1.4319 +
  1.4320 +   /* Copy the control structure so that the original, allocated, version can be
  1.4321 +    * safely freed.  Notice that a png_error here stops the remainder of the
  1.4322 +    * cleanup, but this is probably fine because that would indicate bad memory
  1.4323 +    * problems anyway.
  1.4324 +    */
  1.4325 +   c = *cp;
  1.4326 +   image->opaque = &c;
  1.4327 +   png_free(c.png_ptr, cp);
  1.4328 +
  1.4329 +   /* Then the structures, calling the correct API. */
  1.4330 +   if (c.for_write)
  1.4331 +   {
  1.4332 +#     ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
  1.4333 +         png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
  1.4334 +#     else
  1.4335 +         png_error(c.png_ptr, "simplified write not supported");
  1.4336 +#     endif
  1.4337 +   }
  1.4338 +   else
  1.4339 +   {
  1.4340 +#     ifdef PNG_SIMPLIFIED_READ_SUPPORTED
  1.4341 +         png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
  1.4342 +#     else
  1.4343 +         png_error(c.png_ptr, "simplified read not supported");
  1.4344 +#     endif
  1.4345 +   }
  1.4346 +
  1.4347 +   /* Success. */
  1.4348 +   return 1;
  1.4349 +}
  1.4350 +
  1.4351 +void PNGAPI
  1.4352 +png_image_free(png_imagep image)
  1.4353 +{
  1.4354 +   /* Safely call the real function, but only if doing so is safe at this point
  1.4355 +    * (if not inside an error handling context).  Otherwise assume
  1.4356 +    * png_safe_execute will call this API after the return.
  1.4357 +    */
  1.4358 +   if (image != NULL && image->opaque != NULL &&
  1.4359 +      image->opaque->error_buf == NULL)
  1.4360 +   {
  1.4361 +      /* Ignore errors here: */
  1.4362 +      (void)png_safe_execute(image, png_image_free_function, image);
  1.4363 +      image->opaque = NULL;
  1.4364 +   }
  1.4365 +}
  1.4366 +
  1.4367 +int /* PRIVATE */
  1.4368 +png_image_error(png_imagep image, png_const_charp error_message)
  1.4369 +{
  1.4370 +   /* Utility to log an error. */
  1.4371 +   png_safecat(image->message, (sizeof image->message), 0, error_message);
  1.4372 +   image->warning_or_error |= PNG_IMAGE_ERROR;
  1.4373 +   png_image_free(image);
  1.4374 +   return 0;
  1.4375 +}
  1.4376 +
  1.4377 +#endif /* SIMPLIFIED READ/WRITE */
  1.4378 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */

mercurial