14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* png.c - location for general purpose libpng functions
34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Last changed in libpng 1.6.19 [November 12, 2015]
54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This code is released under the libpng license.
104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For conditions of distribution and use, see the disclaimer
114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and license in png.h
124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "pngpriv.h"
154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Generate a compiler error if there is an old png.h in the search path. */
174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanntypedef png_libpng_version_1_6_22 Your_png_h_is_not_version_1_6_22;
184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Tells libpng that we have already handled the first "num_bytes" bytes
204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of the PNG file signature.  If the PNG data is embedded into another
214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * stream we can set num_bytes = 8 so that libpng will not attempt to read
224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or write any of the magic bytes before it starts on the IHDR.
234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED
264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_sig_bytes(png_structrp png_ptr, int num_bytes)
284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   unsigned int nb = (unsigned int)num_bytes;
304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_set_sig_bytes");
324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (num_bytes < 0)
374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      nb = 0;
384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (nb > 8)
404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "Too many bytes for PNG signature");
414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->sig_bytes = (png_byte)nb;
434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Checks whether the supplied bytes match the PNG signature.  We allow
464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * checking less than the full 8-byte signature so that those apps that
474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * already read the first few bytes of a file to determine the file type
484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * can simply check the remaining bytes for extra assurance.  Returns
494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * an integer less than, equal to, or greater than zero if sig is found,
504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * respectively, to be less than, to match, or be greater than the correct
514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG signature (this is the same behavior as strcmp, memcmp, etc).
524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI
544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (num_to_check > 8)
594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      num_to_check = 8;
604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if (num_to_check < 1)
624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return (-1);
634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (start > 7)
654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return (-1);
664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (start + num_to_check > 8)
684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      num_to_check = 8 - start;
694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ */
744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to allocate memory for zlib */
774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(voidpf /* PRIVATE */,
784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_alloc_size_t num_bytes = size;
814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return NULL;
844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (items >= (~(png_alloc_size_t)0)/size)
864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning (png_voidcast(png_structrp, png_ptr),
884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "Potential overflow in png_zalloc()");
894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return NULL;
904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   num_bytes *= items;
934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to free memory for zlib */
974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_zfree(voidpf png_ptr, voidpf ptr)
994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in case CRC is > 32 bits to leave the top bits 0.
1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reset_crc(png_structrp png_ptr)
1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The cast is safe because the crc is a 32-bit value. */
1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Calculate the CRC over a section of data.  We can only pass as
1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * much data to this routine as the largest single buffer size.  We
1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * also check that this data will actually be used before going to the
1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * trouble of calculating it.
1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int need_crc = 1;
1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         need_crc = 0;
1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else /* critical */
1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         need_crc = 0;
1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * systems it is a 64-bit value.  crc32, however, returns 32 bits so the
1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * following cast is safe.  'uInt' may be no more than 16 bits, so it is
1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * necessary to perform a loop here.
1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (need_crc != 0 && length > 0)
1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      uLong crc = png_ptr->crc; /* Should never issue a warning */
1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      do
1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         uInt safe_length = (uInt)length;
1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifndef __COVERITY__
1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (safe_length == 0)
1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            safe_length = (uInt)-1; /* evil, but safe */
1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         crc = crc32(crc, ptr, safe_length);
1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* The following should never issue compiler warnings; if they do the
1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * target system has characteristics that will probably violate other
1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * assumptions within the libpng code.
1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         ptr += safe_length;
1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         length -= safe_length;
1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (length > 0);
1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* And the following is always safe because the crc is only 32 bits. */
1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->crc = (png_uint_32)crc;
1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Check a user supplied version number, called from both read and write
1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * functions that create a png_struct.
1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint
1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     /* Libpng versions 1.0.0 and later are binary compatible if the version
1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * string matches through the second '.'; we must recompile any
1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * applications that use any older library version.
1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      */
1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (user_png_ver != NULL)
1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i = -1;
1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int found_dots = 0;
1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      do
1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         i++;
1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (user_png_ver[i] == '.')
1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            found_dots++;
1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      } while (found_dots < 2 && user_png_ver[i] != 0 &&
1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            PNG_LIBPNG_VER_STRING[i] != 0);
1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_WARNINGS_SUPPORTED
2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      size_t pos = 0;
2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      char m[128];
2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      pos = png_safecat(m, (sizeof m), pos,
2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          "Application built with libpng-");
2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      pos = png_safecat(m, (sizeof m), pos, user_png_ver);
2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      pos = png_safecat(m, (sizeof m), pos, " but running with ");
2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_UNUSED(pos)
2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, m);
2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_ERROR_NUMBERS_SUPPORTED
2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->flags = 0;
2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Success return. */
2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Generic function to create a png_struct for either read or write - this
2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contains the common initialization.
2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(png_structp /* PRIVATE */,
2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_struct create_struct;
2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_SETJMP_SUPPORTED
2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      jmp_buf create_jmp_buf;
2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This temporary stack-allocated structure is used to provide a place to
2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * build enough context to allow the user provided memory allocator (if any)
2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * to be called.
2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   memset(&create_struct, 0, (sizeof create_struct));
2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Added at libpng-1.2.6 */
2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_USER_LIMITS_SUPPORTED
2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      create_struct.user_width_max = PNG_USER_WIDTH_MAX;
2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_USER_CHUNK_CACHE_MAX
2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Added at libpng-1.2.43 and 1.4.0 */
2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_USER_CHUNK_MALLOC_MAX
2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * in png_struct regardless.
2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following two API calls simply set fields in png_struct, so it is safe
2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * to do them now even though error handling is not yet set up.
2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_USER_MEM_SUPPORTED
2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  else
2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_UNUSED(mem_ptr)
2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_UNUSED(malloc_fn)
2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_UNUSED(free_fn)
2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* (*error_fn) can return control to the caller after the error_ptr is set,
2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * this will result in a memory leak unless the error_fn does something
2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * extremely sophisticated.  The design lacks merit but is implicit in the
2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * API.
2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_SETJMP_SUPPORTED
2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (!setjmp(create_jmp_buf))
2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_SETJMP_SUPPORTED
2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Temporarily fake out the longjmp information until we have
2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * successfully completed this function.  This only works if we have
2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * setjmp() support compiled in, but it is safe - this stuff should
2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * never happen.
2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         create_struct.jmp_buf_ptr = &create_jmp_buf;
2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         create_struct.jmp_buf_size = 0; /*stack allocation*/
2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         create_struct.longjmp_fn = longjmp;
2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Call the general version checker (shared with read and write code):
2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_user_version_check(&create_struct, user_png_ver) != 0)
2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_structrp png_ptr = png_voidcast(png_structrp,
3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_malloc_warn(&create_struct, (sizeof *png_ptr)));
3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (png_ptr != NULL)
3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* png_ptr->zstream holds a back-pointer to the png_struct, so
3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * this can only be done now:
3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               create_struct.zstream.zalloc = png_zalloc;
3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               create_struct.zstream.zfree = png_zfree;
3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               create_struct.zstream.opaque = png_ptr;
3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#              ifdef PNG_SETJMP_SUPPORTED
3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* Eliminate the local error handling: */
3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               create_struct.jmp_buf_ptr = NULL;
3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               create_struct.jmp_buf_size = 0;
3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               create_struct.longjmp_fn = 0;
3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#              endif
3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *png_ptr = create_struct;
3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* This is the successful return point */
3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               return png_ptr;
3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* A longjmp because of a bug in the application storage allocator or a
3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * simple failure to allocate the png_struct.
3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return NULL;
3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Allocate the memory for an info_struct for the application. */
3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(png_infop,PNGAPI
3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_inforp info_ptr;
3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_create_info_struct");
3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return NULL;
3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Use the internal API that does not (or at least should not) error out, so
3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * that this call always returns ok.  The application typically sets up the
3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * error handling *after* creating the info_struct because this is the way it
3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * has always been done in 'example.c'.
3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (sizeof *info_ptr)));
3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr != NULL)
3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      memset(info_ptr, 0, (sizeof *info_ptr));
3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return info_ptr;
3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function frees the memory associated with a single info struct.
3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Normally, one would use either png_destroy_read_struct() or
3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_destroy_write_struct() to free an info struct, but this may be
3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * useful for some applications.  From libpng 1.6.0 this function is also used
3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * internally to implement the png_info release part of the 'struct' destroy
3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * APIs.  This ensures that all possible approaches free the same data (all of
3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it).
3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
3654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_inforp info_ptr = NULL;
3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_destroy_info_struct");
3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr_ptr != NULL)
3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr = *info_ptr_ptr;
3774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr != NULL)
3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Do this first in case of an error below; if the app implements its own
3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * memory management this can lead to png_free calling png_error, which
3824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * will abort this routine and return control to the app error handler.
3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * An infinite loop may result if it then tries to free the same info
3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * ptr.
3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *info_ptr_ptr = NULL;
3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      memset(info_ptr, 0, (sizeof *info_ptr));
3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr);
3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Initialize the info structure.  This is now an internal function (0.89)
3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and applications using it are urged to use png_create_info_struct()
3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * instead.  Use deprecated in 1.6.0, internal use removed (used internally it
3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is just a memset).
3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * NOTE: it is almost inconceivable that this API is used because it bypasses
4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the user-memory mechanism and the user error handling/warning mechanisms in
4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * those cases where it does anything other than a memset.
4024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(void,PNGAPI
4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_DEPRECATED)
4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_inforp info_ptr = *ptr_ptr;
4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_info_init_3");
4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr == NULL)
4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((sizeof (png_info)) > png_info_struct_size)
4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *ptr_ptr = NULL;
4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The following line is why this API should not be used: */
4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      free(info_ptr);
4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
4204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (sizeof *info_ptr)));
4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (info_ptr == NULL)
4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return;
4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *ptr_ptr = info_ptr;
4244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Set everything to 0 */
4274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   memset(info_ptr, 0, (sizeof *info_ptr));
4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following API is not called internally */
4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
4334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int freer, png_uint_32 mask)
4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_data_freer");
4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL || info_ptr == NULL)
4384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (freer == PNG_DESTROY_WILL_FREE_DATA)
4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->free_me |= mask;
4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if (freer == PNG_USER_WILL_FREE_DATA)
4444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->free_me &= ~mask;
4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "Unknown freer parameter in png_data_freer");
4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
4524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int num)
4534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_free_data");
4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL || info_ptr == NULL)
4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_TEXT_SUPPORTED
4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free text item num or (if num == -1) all text items */
4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr->text != 0 &&
4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (num != -1)
4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, info_ptr->text[num].key);
4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->text[num].key = NULL;
4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int i;
4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < info_ptr->num_text; i++)
4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_free(png_ptr, info_ptr->text[i].key);
4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, info_ptr->text);
4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->text = NULL;
4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->num_text = 0;
4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_tRNS_SUPPORTED
4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free any tRNS entry */
4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~PNG_INFO_tRNS;
4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->trans_alpha);
4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->trans_alpha = NULL;
4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->num_trans = 0;
4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sCAL_SUPPORTED
4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free any sCAL entry */
4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->scal_s_width);
5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->scal_s_height);
5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->scal_s_width = NULL;
5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->scal_s_height = NULL;
5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~PNG_INFO_sCAL;
5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_pCAL_SUPPORTED
5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free any pCAL entry */
5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->pcal_purpose);
5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->pcal_units);
5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->pcal_purpose = NULL;
5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->pcal_units = NULL;
5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (info_ptr->pcal_params != NULL)
5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
5184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int i;
5194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            for (i = 0; i < info_ptr->pcal_nparams; i++)
5214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_free(png_ptr, info_ptr->pcal_params[i]);
5224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_free(png_ptr, info_ptr->pcal_params);
5244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            info_ptr->pcal_params = NULL;
5254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
5264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~PNG_INFO_pCAL;
5274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
5284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
5294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_iCCP_SUPPORTED
5314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free any profile entry */
5324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
5334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
5344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->iccp_name);
5354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->iccp_profile);
5364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->iccp_name = NULL;
5374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->iccp_profile = NULL;
5384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~PNG_INFO_iCCP;
5394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
5404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
5414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sPLT_SUPPORTED
5434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
5444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr->splt_palettes != 0 &&
5454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
5464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
5474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (num != -1)
5484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
5494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, info_ptr->splt_palettes[num].name);
5504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, info_ptr->splt_palettes[num].entries);
5514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->splt_palettes[num].name = NULL;
5524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->splt_palettes[num].entries = NULL;
5534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
5544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
5564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
5574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int i;
5584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < info_ptr->splt_palettes_num; i++)
5604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
5614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_free(png_ptr, info_ptr->splt_palettes[i].name);
5624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_free(png_ptr, info_ptr->splt_palettes[i].entries);
5634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
5644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, info_ptr->splt_palettes);
5664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->splt_palettes = NULL;
5674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->splt_palettes_num = 0;
5684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->valid &= ~PNG_INFO_sPLT;
5694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
5704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
5724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
5744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr->unknown_chunks != 0 &&
5754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
5764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
5774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (num != -1)
5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
5794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
5804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          info_ptr->unknown_chunks[num].data = NULL;
5814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
5824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
5844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
5854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int i;
5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (i = 0; i < info_ptr->unknown_chunks_num; i++)
5884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_free(png_ptr, info_ptr->unknown_chunks[i].data);
5894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, info_ptr->unknown_chunks);
5914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->unknown_chunks = NULL;
5924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->unknown_chunks_num = 0;
5934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
5944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
5954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
5964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
5974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_hIST_SUPPORTED
5984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free any hIST entry */
5994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
6004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
6014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->hist);
6024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->hist = NULL;
6034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~PNG_INFO_hIST;
6044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
6054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
6064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free any PLTE entry that was internally allocated */
6084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
6094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
6104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free(png_ptr, info_ptr->palette);
6114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->palette = NULL;
6124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~PNG_INFO_PLTE;
6134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->num_palette = 0;
6144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
6154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_INFO_IMAGE_SUPPORTED
6174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Free any image bits attached to the info structure */
6184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
6194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
6204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (info_ptr->row_pointers != 0)
6214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
6224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_32 row;
6234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (row = 0; row < info_ptr->height; row++)
6244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_free(png_ptr, info_ptr->row_pointers[row]);
6254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, info_ptr->row_pointers);
6274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->row_pointers = NULL;
6284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
6294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~PNG_INFO_IDAT;
6304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
6314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
6324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (num != -1)
6344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      mask &= ~PNG_FREE_MUL;
6354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   info_ptr->free_me &= ~mask;
6374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
6384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ || WRITE */
6394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function returns a pointer to the io_ptr associated with the user
6414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * functions.  The application should free any memory associated with this
6424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pointer before png_write_destroy() or png_read_destroy() are called.
6434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
6444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_voidp PNGAPI
6454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_io_ptr(png_const_structrp png_ptr)
6464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
6474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
6484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return (NULL);
6494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_ptr->io_ptr);
6514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
6524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
6544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_STDIO_SUPPORTED
6554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Initialize the default input/output functions for the PNG file.  If you
6564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * use your own read or write routines, you can call either png_set_read_fn()
6574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or png_set_write_fn() instead of png_init_io().  If you have defined
6584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
6594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * function of your own because "FILE *" isn't necessarily available.
6604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
6614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
6624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_init_io(png_structrp png_ptr, png_FILE_p fp)
6634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
6644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_init_io");
6654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
6674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
6684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->io_ptr = (png_voidp)fp;
6704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
6714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
6724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_SAVE_INT_32_SUPPORTED
6744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* PNG signed integers are saved in 32-bit 2's complement format.  ANSI C-90
6754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * defines a cast of a signed integer to an unsigned integer either to preserve
6764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the value, if it is positive, or to calculate:
6774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
6784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *     (UNSIGNED_MAX+1) + integer
6794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
6804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
6814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * negative integral value is added the result will be an unsigned value
6824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * correspnding to the 2's complement representation.
6834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
6844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
6854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_save_int_32(png_bytep buf, png_int_32 i)
6864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
6874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_save_uint_32(buf, i);
6884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
6894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
6904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
6914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_TIME_RFC1123_SUPPORTED
6924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Convert the supplied time into an RFC 1123 string suitable for use in
6934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a "Creation Time" or other text-based time string.
6944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
6954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI
6964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
6974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
6984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   static PNG_CONST char short_months[12][4] =
6994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
7004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
7014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (out == NULL)
7034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
7044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (ptime->year > 9999 /* RFC1123 limitation */ ||
7064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ptime->month == 0    ||  ptime->month > 12  ||
7074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ptime->day   == 0    ||  ptime->day   > 31  ||
7084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ptime->hour  > 23    ||  ptime->minute > 59 ||
7094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ptime->second > 60)
7104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
7114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
7134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      size_t pos = 0;
7144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      char number_buf[5]; /* enough for a four-digit year */
7154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
7174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     define APPEND_NUMBER(format, value)\
7184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
7194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     define APPEND(ch) if (pos < 28) out[pos++] = (ch)
7204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
7224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND(' ');
7234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND_STRING(short_months[(ptime->month - 1)]);
7244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND(' ');
7254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
7264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND(' ');
7274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
7284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND(':');
7294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
7304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND(':');
7314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
7324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
7334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_UNUSED (pos)
7344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     undef APPEND
7364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     undef APPEND_NUMBER
7374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     undef APPEND_STRING
7384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
7394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
7414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
7424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#    if PNG_LIBPNG_VER < 10700
7444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* To do: remove the following from libpng-1.7 */
7454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Original API that uses a private buffer in png_struct.
7464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Deprecated because it causes png_struct to carry a spurious temporary
7474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * buffer (png_struct::time_buffer), better to have the caller pass this in.
7484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
7494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI
7504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
7514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
7524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr != NULL)
7534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
7544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The only failure above if png_ptr != NULL is from an invalid ptime */
7554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)
7564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_warning(png_ptr, "Ignoring invalid time value");
7574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
7594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_ptr->time_buffer;
7604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
7614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return NULL;
7634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
7644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#    endif /* LIBPNG_VER < 10700 */
7654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif /* TIME_RFC1123 */
7664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ || WRITE */
7684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI
7704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_copyright(png_const_structrp png_ptr)
7714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
7724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
7734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_STRING_COPYRIGHT
7744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return PNG_STRING_COPYRIGHT
7754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
7764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef __STDC__
7774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return PNG_STRING_NEWLINE \
7784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "libpng version 1.6.22 - May 26, 2016" PNG_STRING_NEWLINE \
7794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson" \
7804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_STRING_NEWLINE \
7814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
7824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
7834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_STRING_NEWLINE;
7844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  else
7854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return "libpng version 1.6.22 - May 26, 2016\
7864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\
7874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      Copyright (c) 1996-1997 Andreas Dilger\
7884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
7894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
7904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
7914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
7924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
7934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following return the library version as a short string in the
7944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
7954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * used with your application, print out PNG_LIBPNG_VER_STRING, which
7964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is defined in png.h.
7974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Note: now there is no difference between png_get_libpng_ver() and
7984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
7994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it is guaranteed that png.c uses the correct version of png.h.
8004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
8014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI
8024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_libpng_ver(png_const_structrp png_ptr)
8034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Version of *.c files used when building libpng */
8054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return png_get_header_ver(png_ptr);
8064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI
8094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_header_ver(png_const_structrp png_ptr)
8104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Version of *.h files used when building libpng */
8124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
8134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return PNG_LIBPNG_VER_STRING;
8144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI
8174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_header_version(png_const_structrp png_ptr)
8184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Returns longer string containing both version and date */
8204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
8214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef __STDC__
8224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return PNG_HEADER_VERSION_STRING
8234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifndef PNG_READ_SUPPORTED
8244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      " (NO READ SUPPORT)"
8254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
8264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_STRING_NEWLINE;
8274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
8284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return PNG_HEADER_VERSION_STRING;
8294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
8304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
8334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* NOTE: this routine is not used internally! */
8344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
8354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * large of png_color.  This lets grayscale images be treated as
8364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * paletted.  Most useful for gamma correction and simplification
8374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of code.  This API is not used internally.
8384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
8394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
8404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_grayscale_palette(int bit_depth, png_colorp palette)
8414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int num_palette;
8434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int color_inc;
8444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int i;
8454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int v;
8464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_debug(1, "in png_do_build_grayscale_palette");
8484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (palette == NULL)
8504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
8514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (bit_depth)
8534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
8544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 1:
8554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         num_palette = 2;
8564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         color_inc = 0xff;
8574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
8584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 2:
8604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         num_palette = 4;
8614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         color_inc = 0x55;
8624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
8634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 4:
8654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         num_palette = 16;
8664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         color_inc = 0x11;
8674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
8684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 8:
8704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         num_palette = 256;
8714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         color_inc = 1;
8724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
8734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
8754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         num_palette = 0;
8764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         color_inc = 0;
8774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
8784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
8794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
8814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
8824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      palette[i].red = (png_byte)(v & 0xff);
8834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      palette[i].green = (png_byte)(v & 0xff);
8844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      palette[i].blue = (png_byte)(v & 0xff);
8854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
8864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
8874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
8884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
8904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI
8914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
8924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
8934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Check chunk_name and return "keep" value if it's on the list, else 0 */
8944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep p, p_end;
8954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
8974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return PNG_HANDLE_CHUNK_AS_DEFAULT;
8984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
8994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   p_end = png_ptr->chunk_list;
9004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
9014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The code is the fifth byte after each four byte string.  Historically this
9034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * code was always searched from the end of the list, this is no longer
9044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * necessary because the 'set' routine handles duplicate entries correcty.
9054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
9064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   do /* num_chunk_list > 0, so at least one */
9074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
9084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      p -= 5;
9094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (memcmp(chunk_name, p, 4) == 0)
9114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return p[4];
9124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
9134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   while (p > p_end);
9144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This means that known chunks should be processed and unknown chunks should
9164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * be handled according to the value of png_ptr->unknown_default; this can be
9174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * confusing because, as a result, there are two levels of defaulting for
9184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * unknown chunks.
9194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
9204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return PNG_HANDLE_CHUNK_AS_DEFAULT;
9214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
9244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
9254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
9264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
9274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte chunk_string[5];
9294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
9314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return png_handle_as_unknown(png_ptr, chunk_string);
9324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
9344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SET_UNKNOWN_CHUNKS */
9354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED
9374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function, added to libpng-1.0.6g, is untested. */
9384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI
9394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reset_zstream(png_structrp png_ptr)
9404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr == NULL)
9424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return Z_STREAM_ERROR;
9434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* WARNING: this resets the window bits to the maximum! */
9454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (inflateReset(&png_ptr->zstream));
9464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ */
9484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function was added to libpng-1.0.7 */
9504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_uint_32 PNGAPI
9514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_access_version_number(void)
9524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Version of *.c files used when building libpng */
9544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return((png_uint_32)PNG_LIBPNG_VER);
9554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
9564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
9584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
9594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * If it doesn't 'ret' is used to set it to something appropriate, even in cases
9604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
9614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
9624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
9634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_zstream_error(png_structrp png_ptr, int ret)
9644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
9654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Translate 'ret' into an appropriate error string, priority is given to the
9664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * one in zstream if set.  This always returns a string, even in cases like
9674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Z_OK or Z_STREAM_END where the error code is a success code.
9684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
9694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->zstream.msg == NULL) switch (ret)
9704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
9714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
9724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_OK:
9734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
9744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_STREAM_END:
9774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Normal exit */
9784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
9794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_NEED_DICT:
9824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This means the deflate stream did not have a dictionary; this
9834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * indicates a bogus PNG.
9844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
9854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
9864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_ERRNO:
9894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* gz APIs only: should not happen */
9904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
9914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_STREAM_ERROR:
9944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* internal libpng error */
9954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
9964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
9974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
9984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_DATA_ERROR:
9994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
10004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
10014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_MEM_ERROR:
10034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
10044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
10054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_BUF_ERROR:
10074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* End of input or output; not a problem if the caller is doing
10084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * incremental read or write.
10094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
10104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
10114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
10124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case Z_VERSION_ERROR:
10144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
10154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
10164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_UNEXPECTED_ZLIB_RETURN:
10184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Compile errors here mean that zlib now uses the value co-opted in
10194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
10204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * and change pngpriv.h.  Note that this message is "... return",
10214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * whereas the default/Z_OK one is "... return code".
10224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
10234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
10244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
10254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
10264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
10274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
10294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * at libpng 1.5.5!
10304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
10314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
10334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
10344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
10354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_check_gamma(png_const_structrp png_ptr,
10364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_colorspacerp colorspace, png_fixed_point gAMA, int from)
10374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This is called to check a new gamma value against an existing one.  The
10384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * routine returns false if the new gamma value should not be written.
10394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
10404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 'from' says where the new gamma value comes from:
10414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
10424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    0: the new gamma value is the libpng estimate for an ICC profile
10434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    1: the new gamma value comes from a gAMA chunk
10444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    2: the new gamma value comes from an sRGB chunk
10454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
10464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
10474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point gtest;
10484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
10504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
10514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_gamma_significant(gtest) != 0))
10524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
10534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Either this is an sRGB image, in which case the calculated gamma
10544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * approximation should match, or this is an image with a profile and the
10554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * value libpng calculates for the gamma of the profile does not match the
10564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * value recorded in the file.  The former, sRGB, case is an error, the
10574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * latter is just a warning.
10584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
10594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
10604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
10614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_chunk_report(png_ptr, "gamma value does not match sRGB",
10624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            PNG_CHUNK_ERROR);
10634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Do not overwrite an sRGB value */
10644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return from == 2;
10654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
10664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else /* sRGB tag not involved */
10684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
10694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
10704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            PNG_CHUNK_WARNING);
10714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return from == 1;
10724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
10734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
10744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
10764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
10774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
10794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_gamma(png_const_structrp png_ptr,
10804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_colorspacerp colorspace, png_fixed_point gAMA)
10814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
10824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
10834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * occur.  Since the fixed point representation is asymetrical it is
10844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * possible for 1/gamma to overflow the limit of 21474 and this means the
10854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * gamma value must be at least 5/100000 and hence at most 20000.0.  For
10864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * safety the limits here are a little narrower.  The values are 0.00016 to
10874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 6250.0, which are truly ridiculous gamma values (and will produce
10884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * displays that are all black or all white.)
10894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
10904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
10914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * handling code, which only required the value to be >0.
10924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
10934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_charp errmsg;
10944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (gAMA < 16 || gAMA > 625000000)
10964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      errmsg = "gamma value out of range";
10974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
10984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_READ_gAMA_SUPPORTED
10994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Allow the application to set the gamma value more than once */
11004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
11014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
11024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      errmsg = "duplicate";
11034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
11044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Do nothing if the colorspace is already invalid */
11064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
11074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
11084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
11104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
11114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,
11124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          1/*from gAMA*/) != 0)
11134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
11144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Store this gamma value. */
11154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         colorspace->gamma = gAMA;
11164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         colorspace->flags |=
11174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
11184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
11194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* At present if the check_gamma test fails the gamma of the colorspace is
11214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * not updated however the colorspace is not invalidated.  This
11224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * corresponds to the case where the existing gamma comes from an sRGB
11234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * chunk or profile.  An error message has already been output.
11244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
11254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
11264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
11274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Error exit - errmsg has been set. */
11294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->flags |= PNG_COLORSPACE_INVALID;
11304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
11314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
11324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
11344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
11354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
11364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
11374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
11384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Everything is invalid */
11394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
11404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_INFO_iCCP);
11414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_COLORSPACE_SUPPORTED
11434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Clean up the iCCP profile now if it won't be used. */
11444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
11454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     else
11464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_UNUSED(png_ptr)
11474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
11484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
11494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
11514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
11524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_COLORSPACE_SUPPORTED
11534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Leave the INFO_iCCP flag set if the pngset.c code has already set
11544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * it; this allows a PNG to contain a profile which matches sRGB and
11554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * yet still have that profile retrievable by the application.
11564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
11574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)
11584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->valid |= PNG_INFO_sRGB;
11594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
11614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->valid &= ~PNG_INFO_sRGB;
11624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
11644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->valid |= PNG_INFO_cHRM;
11654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
11674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->valid &= ~PNG_INFO_cHRM;
11684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
11694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)
11714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->valid |= PNG_INFO_gAMA;
11724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
11744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         info_ptr->valid &= ~PNG_INFO_gAMA;
11754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
11764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
11774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED
11794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
11804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
11814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
11824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (info_ptr == NULL) /* reduce code size; check here not in the caller */
11834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return;
11844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   info_ptr->colorspace = png_ptr->colorspace;
11864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_colorspace_sync_info(png_ptr, info_ptr);
11874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
11884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
11894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* GAMMA */
11904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
11914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_COLORSPACE_SUPPORTED
11924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
11934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * cHRM, as opposed to using chromaticities.  These internal APIs return
11944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * non-zero on a parameter error.  The X, Y and Z values are required to be
11954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * positive and less than 1.0.
11964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
11974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
11984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
11994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
12004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_int_32 d, dwhite, whiteX, whiteY;
12014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
12034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
12044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
12064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   dwhite = d;
12084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   whiteX = XYZ->red_X;
12094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   whiteY = XYZ->red_Y;
12104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
12124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
12134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
12154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   dwhite += d;
12174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   whiteX += XYZ->green_X;
12184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   whiteY += XYZ->green_Y;
12194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
12214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
12224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
12244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   dwhite += d;
12264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   whiteX += XYZ->blue_X;
12274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   whiteY += XYZ->blue_Y;
12284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
12304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * thus:
12314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
12324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
12334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
12354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
12364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
12384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
12394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
12414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
12424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
12434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point red_inverse, green_inverse, blue_scale;
12444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point left, right, denominator;
12454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically
12474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * have end points with 0 tristimulus values (these are impossible end
12484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * points, but they are used to cover the possible colors).  We check
12494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * xy->whitey against 5, not 0, to avoid a possible integer overflow.
12504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
12514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->redx   < 0 || xy->redx > PNG_FP_1) return 1;
12524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->redy   < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
12534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
12544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
12554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->bluex  < 0 || xy->bluex > PNG_FP_1) return 1;
12564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->bluey  < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
12574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
12584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
12594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
12604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The reverse calculation is more difficult because the original tristimulus
12614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
12624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * derived values were recorded in the cHRM chunk;
12634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * (red,green,blue,white)x(x,y).  This loses one degree of freedom and
12644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * therefore an arbitrary ninth value has to be introduced to undo the
12654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * original transformations.
12664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Think of the original end-points as points in (X,Y,Z) space.  The
12684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * chromaticity values (c) have the property:
12694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *           C
12714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *   c = ---------
12724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *       X + Y + Z
12734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * For each c (x,y,z) from the corresponding original C (X,Y,Z).  Thus the
12754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * three chromaticity values (x,y,z) for each end-point obey the
12764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * relationship:
12774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *   x + y + z = 1
12794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * This describes the plane in (X,Y,Z) space that intersects each axis at the
12814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * value 1.0; call this the chromaticity plane.  Thus the chromaticity
12824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * calculation has scaled each end-point so that it is on the x+y+z=1 plane
12834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * and chromaticity is the intersection of the vector from the origin to the
12844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * (X,Y,Z) value with the chromaticity plane.
12854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * To fully invert the chromaticity calculation we would need the three
12874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * end-point scale factors, (red-scale, green-scale, blue-scale), but these
12884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * were not recorded.  Instead we calculated the reference white (X,Y,Z) and
12894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * recorded the chromaticity of this.  The reference white (X,Y,Z) would have
12904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * given all three of the scale factors since:
12914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    color-C = color-c * color-scale
12934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    white-C = red-C + green-C + blue-C
12944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
12954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * But cHRM records only white-x and white-y, so we have lost the white scale
12974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * factor:
12984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
12994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    white-C = white-c*white-scale
13004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * To handle this the inverse transformation makes an arbitrary assumption
13024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * about white-scale:
13034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    Assume: white-Y = 1.0
13054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    Hence:  white-scale = 1/white-y
13064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    Or:     red-Y + green-Y + blue-Y = 1.0
13074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Notice the last statement of the assumption gives an equation in three of
13094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the nine values we want to calculate.  8 more equations come from the
13104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * above routine as summarised at the top above (the chromaticity
13114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * calculation):
13124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    Given: color-x = color-X / (color-X + color-Y + color-Z)
13144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
13154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * This is 9 simultaneous equations in the 9 variables "color-C" and can be
13174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * solved by Cramer's rule.  Cramer's rule requires calculating 10 9x9 matrix
13184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * determinants, however this is not as bad as it seems because only 28 of
13194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the total of 90 terms in the various matrices are non-zero.  Nevertheless
13204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Cramer's rule is notoriously numerically unstable because the determinant
13214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * calculation involves the difference of large, but similar, numbers.  It is
13224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * difficult to be sure that the calculation is stable for real world values
13234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * and it is certain that it becomes unstable where the end points are close
13244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * together.
13254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * So this code uses the perhaps slightly less optimal but more
13274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * understandable and totally obvious approach of calculating color-scale.
13284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * This algorithm depends on the precision in white-scale and that is
13304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * (1/white-y), so we can immediately see that as white-y approaches 0 the
13314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * accuracy inherent in the cHRM chunk drops off substantially.
13324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * libpng arithmetic: a simple inversion of the above equations
13344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * ------------------------------------------------------------
13354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    white_scale = 1/white-y
13374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    white-X = white-x * white-scale
13384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    white-Y = 1.0
13394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    white-Z = (1 - white-x - white-y) * white_scale
13404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    white-C = red-C + green-C + blue-C
13424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
13434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * This gives us three equations in (red-scale,green-scale,blue-scale) where
13454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * all the coefficients are now known:
13464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    red-x*red-scale + green-x*green-scale + blue-x*blue-scale
13484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *       = white-x/white-y
13494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
13504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    red-z*red-scale + green-z*green-scale + blue-z*blue-scale
13514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *       = (1 - white-x - white-y)/white-y
13524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * In the last equation color-z is (1 - color-x - color-y) so we can add all
13544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * three equations together to get an alternative third:
13554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    red-scale + green-scale + blue-scale = 1/white-y = white-scale
13574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * So now we have a Cramer's rule solution where the determinants are just
13594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 3x3 - far more tractible.  Unfortunately 3x3 determinants still involve
13604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * multiplication of three coefficients so we can't guarantee to avoid
13614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * overflow in the libpng fixed point representation.  Using Cramer's rule in
13624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * floating point is probably a good choice here, but it's not an option for
13634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * fixed point.  Instead proceed to simplify the first two equations by
13644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * eliminating what is likely to be the largest value, blue-scale:
13654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    blue-scale = white-scale - red-scale - green-scale
13674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Hence:
13694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
13714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                (white-x - blue-x)*white-scale
13724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
13744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                1 - blue-y*white-scale
13754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * And now we can trivially solve for (red-scale,green-scale):
13774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    green-scale =
13794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
13804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                -----------------------------------------------------------
13814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                                  green-x - blue-x
13824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    red-scale =
13844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                1 - blue-y*white-scale - (green-y - blue-y) * green-scale
13854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                ---------------------------------------------------------
13864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *                                  red-y - blue-y
13874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Hence:
13894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    red-scale =
13914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *          ( (green-x - blue-x) * (white-y - blue-y) -
13924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *            (green-y - blue-y) * (white-x - blue-x) ) / white-y
13934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * -------------------------------------------------------------------------
13944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
13954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
13964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    green-scale =
13974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *          ( (red-y - blue-y) * (white-x - blue-x) -
13984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *            (red-x - blue-x) * (white-y - blue-y) ) / white-y
13994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * -------------------------------------------------------------------------
14004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
14014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Accuracy:
14034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * The input values have 5 decimal digits of accuracy.  The values are all in
14044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the range 0 < value < 1, so simple products are in the same range but may
14054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * need up to 10 decimal digits to preserve the original precision and avoid
14064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * underflow.  Because we are using a 32-bit signed representation we cannot
14074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * match this; the best is a little over 9 decimal digits, less than 10.
14084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * The approach used here is to preserve the maximum precision within the
14104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * signed representation.  Because the red-scale calculation above uses the
14114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * difference between two products of values that must be in the range -1..+1
14124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * it is sufficient to divide the product by 7; ceil(100,000/32767*2).  The
14134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * factor is irrelevant in the calculation because it is applied to both
14144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * numerator and denominator.
14154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Note that the values of the differences of the products of the
14174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * chromaticities in the above equations tend to be small, for example for
14184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the sRGB chromaticities they are:
14194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * red numerator:    -0.04751
14214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * green numerator:  -0.08788
14224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * denominator:      -0.2241 (without white-y multiplication)
14234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  The resultant Y coefficients from the chromaticities of some widely used
14254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  color space definitions are (to 15 decimal places):
14264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
14274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  sRGB
14284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    0.212639005871510 0.715168678767756 0.072192315360734
14294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  Kodak ProPhoto
14304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    0.288071128229293 0.711843217810102 0.000085653960605
14314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  Adobe RGB
14324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    0.297344975250536 0.627363566255466 0.075291458493998
14334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *  Adobe Wide Gamut RGB
14344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    0.258728243040113 0.724682314948566 0.016589442011321
14354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* By the argument, above overflow should be impossible here. The return
14374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * value of 2 indicates an internal error to the caller.
14384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)
14404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 2;
14414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)
14424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 2;
14434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   denominator = left - right;
14444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Now find the red numerator. */
14464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
14474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 2;
14484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
14494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 2;
14504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Overflow is possible here and it indicates an extreme set of PNG cHRM
14524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * chunk values.  This calculation actually returns the reciprocal of the
14534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * scale value because this allows us to delay the multiplication of white-y
14544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * into the denominator, which tends to produce a small number.
14554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||
14574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       red_inverse <= xy->whitey /* r+g+b scales = white scale */)
14584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Similarly for green_inverse: */
14614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
14624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 2;
14634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
14644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 2;
14654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||
14664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       green_inverse <= xy->whitey)
14674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* And the blue scale, the checks above guarantee this can't overflow but it
14704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * can still produce 0 for extreme cHRM values.
14714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
14724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
14734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_reciprocal(green_inverse);
14744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (blue_scale <= 0)
14754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* And fill in the png_XYZ: */
14794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
14804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
14824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
14844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       red_inverse) == 0)
14854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
14884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
14904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
14924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       green_inverse) == 0)
14934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
14954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
14964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
14984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
14994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
15004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_FP_1) == 0)
15014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
15024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /*success*/
15044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
15054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
15074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_XYZ_normalize(png_XYZ *XYZ)
15084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
15094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_int_32 Y;
15104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
15124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
15134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
15144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
15154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
15174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
15184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * relying on addition of two positive values producing a negative one is not
15194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * safe.
15204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
15214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   Y = XYZ->red_Y;
15224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (0x7fffffff - Y < XYZ->green_X)
15234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
15244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   Y += XYZ->green_Y;
15254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (0x7fffffff - Y < XYZ->blue_X)
15264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
15274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   Y += XYZ->blue_Y;
15284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (Y != PNG_FP_1)
15304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
15314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
15324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
15344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
15364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
15394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
15414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
15434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
15464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
15484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
15504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
15514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
15524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
15544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
15554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
15574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
15584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
15594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
15604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
15614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
15624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_OUT_OF_RANGE(xy1->redx,   xy2->redx,  delta) ||
15634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_OUT_OF_RANGE(xy1->redy,   xy2->redy,  delta) ||
15644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
15654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
15664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_OUT_OF_RANGE(xy1->bluex,  xy2->bluex, delta) ||
15674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       PNG_OUT_OF_RANGE(xy1->bluey,  xy2->bluey, delta))
15684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
15694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
15704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
15714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
15734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chunk chromaticities.  Earlier checks used to simply look for the overflow
15744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * condition (where the determinant of the matrix to solve for XYZ ends up zero
15754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * because the chromaticity values are not all distinct.)  Despite this it is
15764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * theoretically possible to produce chromaticities that are apparently valid
15774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * but that rapidly degrade to invalid, potentially crashing, sets because of
15784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * arithmetic inaccuracies when calculations are performed on them.  The new
15794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * check is to round-trip xy -> XYZ -> xy and then check that the result is
15804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * within a small percentage of the original.
15814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
15824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
15834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
15844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
15854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int result;
15864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_xy xy_test;
15874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* As a side-effect this routine also returns the XYZ endpoints. */
15894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   result = png_XYZ_from_xy(XYZ, xy);
15904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (result != 0)
15914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return result;
15924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   result = png_xy_from_XYZ(&xy_test, XYZ);
15944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (result != 0)
15954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return result;
15964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
15974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_colorspace_endpoints_match(xy, &xy_test,
15984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       5/*actually, the math is pretty accurate*/) != 0)
15994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
16004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Too much slip */
16024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
16034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
16044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This is the check going the other way.  The XYZ is modified to normalize it
16064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (another side-effect) and the xy chromaticities are returned.
16074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
16084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
16094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
16104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
16114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int result;
16124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_XYZ XYZtemp;
16134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   result = png_XYZ_normalize(XYZ);
16154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (result != 0)
16164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return result;
16174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   result = png_xy_from_XYZ(xy, XYZ);
16194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (result != 0)
16204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return result;
16214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   XYZtemp = *XYZ;
16234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return png_colorspace_check_xy(&XYZtemp, xy);
16244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
16254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Used to check for an endpoint match against sRGB */
16274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
16284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
16294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* color      x       y */
16304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* red   */ 64000, 33000,
16314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* green */ 30000, 60000,
16324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* blue  */ 15000,  6000,
16334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* white */ 31270, 32900
16344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
16354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
16374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
16384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
16394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int preferred)
16404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
16414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
16424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
16434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The consistency check is performed on the chromaticities; this factors out
16454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * variations because of the normalization (or not) of the end point Y
16464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * values.
16474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
16484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (preferred < 2 &&
16494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
16504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
16514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The end points must be reasonably close to any we already have.  The
16524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * following allows an error of up to +/-.001
16534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
16544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,
16554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          100) == 0)
16564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
16574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         colorspace->flags |= PNG_COLORSPACE_INVALID;
16584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_benign_error(png_ptr, "inconsistent chromaticities");
16594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 0; /* failed */
16604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
16614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Only overwrite with preferred values */
16634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (preferred == 0)
16644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1; /* ok, but no change */
16654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
16664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->end_points_xy = *xy;
16684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->end_points_XYZ = *XYZ;
16694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
16704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The end points are normally quoted to two decimal digits, so allow +/-0.01
16724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * on this test.
16734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
16744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)
16754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
16764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
16784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      colorspace->flags &= PNG_COLORSPACE_CANCEL(
16794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
16804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 2; /* ok and changed */
16824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
16834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
16854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_chromaticities(png_const_structrp png_ptr,
16864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_colorspacerp colorspace, const png_xy *xy, int preferred)
16874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
16884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* We must check the end points to ensure they are reasonable - in the past
16894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * color management systems have crashed as a result of getting bogus
16904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * colorant values, while this isn't the fault of libpng it is the
16914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * responsibility of libpng because PNG carries the bomb and libpng is in a
16924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * position to protect against it.
16934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
16944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_XYZ XYZ;
16954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
16964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (png_colorspace_check_xy(&XYZ, xy))
16974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
16984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0: /* success */
16994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
17004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            preferred);
17014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 1:
17034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* We can't invert the chromaticities so we can't produce value XYZ
17044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * values.  Likely as not a color management system will fail too.
17054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
17064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         colorspace->flags |= PNG_COLORSPACE_INVALID;
17074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_benign_error(png_ptr, "invalid chromaticities");
17084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
17094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
17114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* libpng is broken; this should be a warning but if it happens we
17124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * want error reports so for the moment it is an error.
17134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
17144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         colorspace->flags |= PNG_COLORSPACE_INVALID;
17154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(png_ptr, "internal error checking chromaticities");
17164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
17174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* failed */
17194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
17204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
17224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_endpoints(png_const_structrp png_ptr,
17234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
17244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
17254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_XYZ XYZ = *XYZ_in;
17264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_xy xy;
17274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (png_colorspace_check_XYZ(&xy, &XYZ))
17294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
17304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0:
17314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
17324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            preferred);
17334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 1:
17354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* End points are invalid. */
17364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         colorspace->flags |= PNG_COLORSPACE_INVALID;
17374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_benign_error(png_ptr, "invalid end points");
17384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
17394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
17414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         colorspace->flags |= PNG_COLORSPACE_INVALID;
17424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(png_ptr, "internal error checking chromaticities");
17434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
17444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* failed */
17464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
17474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
17494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Error message generation */
17504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic char
17514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_tag_char(png_uint_32 byte)
17524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
17534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   byte &= 0xff;
17544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (byte >= 32 && byte <= 126)
17554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return (char)byte;
17564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
17574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return '?';
17584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
17594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
17614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_tag_name(char *name, png_uint_32 tag)
17624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
17634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   name[0] = '\'';
17644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   name[1] = png_icc_tag_char(tag >> 24);
17654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   name[2] = png_icc_tag_char(tag >> 16);
17664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   name[3] = png_icc_tag_char(tag >>  8);
17674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   name[4] = png_icc_tag_char(tag      );
17684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   name[5] = '\'';
17694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
17704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
17724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannis_ICC_signature_char(png_alloc_size_t it)
17734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
17744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
17754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (it >= 97 && it <= 122);
17764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
17774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
17794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannis_ICC_signature(png_alloc_size_t it)
17804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
17814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
17824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      is_ICC_signature_char((it >> 16) & 0xff) &&
17834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      is_ICC_signature_char((it >> 8) & 0xff) &&
17844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      is_ICC_signature_char(it & 0xff);
17854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
17864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
17884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
17894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_charp name, png_alloc_size_t value, png_const_charp reason)
17904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
17914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   size_t pos;
17924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   char message[196]; /* see below for calculation */
17934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (colorspace != NULL)
17954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      colorspace->flags |= PNG_COLORSPACE_INVALID;
17964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
17974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
17984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
17994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
18004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (is_ICC_signature(value) != 0)
18014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
18024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* So 'value' is at most 4 bytes and the following cast is safe */
18034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_icc_tag_name(message+pos, (png_uint_32)value);
18044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      pos += 6; /* total +8; less than the else clause */
18054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      message[pos++] = ':';
18064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      message[pos++] = ' ';
18074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
18084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_WARNINGS_SUPPORTED
18094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
18104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
18114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
18124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         pos = png_safecat(message, (sizeof message), pos,
18144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_format_number(number, number+(sizeof number),
18154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               PNG_NUMBER_FORMAT_x, value));
18164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
18174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
18184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
18194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
18204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   pos = png_safecat(message, (sizeof message), pos, reason);
18214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_UNUSED(pos)
18224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This is recoverable, but make it unconditionally an app_error on write to
18244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * avoid writing invalid ICC profiles into PNG files (i.e., we handle them
18254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * on read, with a warning, but on write unless the app turns off
18264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * application errors the PNG won't be written.)
18274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
18284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_chunk_report(png_ptr, message,
18294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
18304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
18324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
18334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* sRGB || iCCP */
18344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sRGB_SUPPORTED
18364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
18374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
18384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int intent)
18394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
18404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* sRGB sets known gamma, end points and (from the chunk) intent. */
18414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* IMPORTANT: these are not necessarily the values found in an ICC profile
18424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * because ICC profiles store values adapted to a D50 environment; it is
18434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * expected that the ICC profile mediaWhitePointTag will be D50; see the
18444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * checks and code elsewhere to understand this better.
18454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
18464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * These XYZ values, which are accurate to 5dp, produce rgb to gray
18474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * coefficients of (6968,23435,2366), which are reduced (because they add up
18484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * to 32769 not 32768) to (6968,23434,2366).  These are the values that
18494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * libpng has traditionally used (and are the best values given the 15bit
18504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * algorithm used by the rgb to gray code.)
18514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
18524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
18534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
18544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* color      X      Y      Z */
18554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* red   */ 41239, 21264,  1933,
18564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* green */ 35758, 71517, 11919,
18574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* blue  */ 18048,  7219, 95053
18584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   };
18594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Do nothing if the colorspace is already invalidated. */
18614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
18624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
18634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Check the intent, then check for existing settings.  It is valid for the
18654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
18664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * be consistent with the correct values.  If, however, this function is
18674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * called below because an iCCP chunk matches sRGB then it is quite
18684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * conceivable that an older app recorded incorrect gAMA and cHRM because of
18694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * an incorrect calculation based on the values in the profile - this does
18704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * *not* invalidate the profile (though it still produces an error, which can
18714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * be ignored.)
18724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
18734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
18744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
18754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (unsigned)intent, "invalid sRGB rendering intent");
18764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
18784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      colorspace->rendering_intent != intent)
18794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, "sRGB",
18804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (unsigned)intent, "inconsistent rendering intents");
18814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
18834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
18844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_benign_error(png_ptr, "duplicate sRGB information ignored");
18854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
18864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
18874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* If the standard sRGB cHRM chunk does not match the one from the PNG file
18894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * warn but overwrite the value with the correct one.
18904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
18914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
18924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
18934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         100))
18944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
18954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         PNG_CHUNK_ERROR);
18964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
18974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This check is just done for the error reporting - the routine always
18984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * returns true when the 'from' argument corresponds to sRGB (2).
18994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
19004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
19014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      2/*from sRGB*/);
19024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* intent: bugs in GCC force 'int' to be used as the parameter type. */
19044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->rendering_intent = (png_uint_16)intent;
19054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
19064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* endpoints */
19084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->end_points_xy = sRGB_xy;
19094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->end_points_XYZ = sRGB_XYZ;
19104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->flags |=
19114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
19124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* gamma */
19144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
19154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
19164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Finally record that we have an sRGB profile */
19184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   colorspace->flags |=
19194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
19204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1; /* set */
19224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
19234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* sRGB */
19244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_iCCP_SUPPORTED
19264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Encoded value of D50 as an ICC XYZNumber.  From the ICC 2010 spec the value
19274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is XYZ(0.9642,1.0,0.8249), which scales to:
19284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
19294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *    (63189.8112, 65536, 54060.6464)
19304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
19314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_byte D50_nCIEXYZ[12] =
19324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
19334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
19354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
19364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_charp name, png_uint_32 profile_length)
19374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
19384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (profile_length < 132)
19394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
19404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "too short");
19414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
19434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
19444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
19464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
19474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_charp name, png_uint_32 profile_length,
19484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep profile/* first 132 bytes only */, int color_type)
19494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
19504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 temp;
19514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Length check; this cannot be ignored in this code because profile_length
19534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * is used later to check the tag table, so even if the profile seems over
19544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * long profile_length from the caller must be correct.  The caller can fix
19554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * this up on read or write by just passing in the profile header length.
19564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
19574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = png_get_uint_32(profile);
19584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (temp != profile_length)
19594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, name, temp,
19604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "length does not match profile");
19614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = (png_uint_32) (*(profile+8));
19634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (temp > 3 && (profile_length & 3))
19644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
19654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "invalid length");
19664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
19684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
19694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      profile_length < 132+12*temp) /* truncated tag table */
19704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, name, temp,
19714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "tag count too large");
19724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The 'intent' must be valid or we can't store it, ICC limits the intent to
19744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 16 bits.
19754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
19764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = png_get_uint_32(profile+64);
19774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (temp >= 0xffff) /* The ICC limit */
19784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, name, temp,
19794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "invalid rendering intent");
19804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This is just a warning because the profile may be valid in future
19824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * versions.
19834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
19844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (temp >= PNG_sRGB_INTENT_LAST)
19854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (void)png_icc_profile_error(png_ptr, NULL, name, temp,
19864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "intent outside defined range");
19874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* At this point the tag table can't be checked because it hasn't necessarily
19894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * been loaded; however, various header fields can be checked.  These checks
19904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * are for values permitted by the PNG spec in an ICC profile; the PNG spec
19914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * restricts the profiles that can be passed in an iCCP chunk (they must be
19924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * appropriate to processing PNG data!)
19934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
19944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
19954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Data checks (could be skipped).  These checks must be independent of the
19964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * version number; however, the version number doesn't accomodate changes in
19974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the header fields (just the known tags and the interpretation of the
19984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * data.)
19994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
20004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = png_get_uint_32(profile+36); /* signature 'ascp' */
20014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (temp != 0x61637370)
20024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_icc_profile_error(png_ptr, colorspace, name, temp,
20034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "invalid signature");
20044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Currently the PCS illuminant/adopted white point (the computational
20064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * white point) are required to be D50,
20074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * however the profile contains a record of the illuminant so perhaps ICC
20084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * expects to be able to change this in the future (despite the rationale in
20094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the introduction for using a fixed PCS adopted white.)  Consequently the
20104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * following is just a warning.
20114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
20124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
20134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
20144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         "PCS illuminant is not D50");
20154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The PNG spec requires this:
20174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * "If the iCCP chunk is present, the image samples conform to the colour
20184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * space represented by the embedded ICC profile as defined by the
20194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * International Color Consortium [ICC]. The colour space of the ICC profile
20204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
20214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 6), or a greyscale colour space for greyscale images (PNG colour types 0
20224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * and 4)."
20234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
20244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * This checking code ensures the embedded profile (on either read or write)
20254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * conforms to the specification requirements.  Notice that an ICC 'gray'
20264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * color-space profile contains the information to transform the monochrome
20274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * data to XYZ or L*a*b (according to which PCS the profile uses) and this
20284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * should be used in preference to the standard libpng K channel replication
20294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * into R, G and B channels.
20304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
20314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Previously it was suggested that an RGB profile on grayscale data could be
20324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * handled.  However it it is clear that using an RGB profile in this context
20334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * must be an error - there is no specification of what it means.  Thus it is
20344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * almost certainly more correct to ignore the profile.
20354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
20364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = png_get_uint_32(profile+16); /* data colour space field */
20374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (temp)
20384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
20394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x52474220: /* 'RGB ' */
20404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
20414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return png_icc_profile_error(png_ptr, colorspace, name, temp,
20424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               "RGB color space not permitted on grayscale PNG");
20434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
20444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x47524159: /* 'GRAY' */
20464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
20474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return png_icc_profile_error(png_ptr, colorspace, name, temp,
20484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               "Gray color space not permitted on RGB PNG");
20494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
20504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
20524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_icc_profile_error(png_ptr, colorspace, name, temp,
20534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "invalid ICC profile color space");
20544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
20554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* It is up to the application to check that the profile class matches the
20574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * application requirements; the spec provides no guidance, but it's pretty
20584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
20594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * ('prtr') or 'spac' (for generic color spaces).  Issue a warning in these
20604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * cases.  Issue an error for device link or abstract profiles - these don't
20614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * contain the records necessary to transform the color-space to anything
20624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * other than the target device (and not even that for an abstract profile).
20634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * Profiles of these classes may not be embedded in images.
20644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
20654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = png_get_uint_32(profile+12); /* profile/device class */
20664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (temp)
20674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
20684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x73636e72: /* 'scnr' */
20694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x6d6e7472: /* 'mntr' */
20704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x70727472: /* 'prtr' */
20714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x73706163: /* 'spac' */
20724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* All supported */
20734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
20744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x61627374: /* 'abst' */
20764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* May not be embedded in an image */
20774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_icc_profile_error(png_ptr, colorspace, name, temp,
20784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "invalid embedded Abstract ICC profile");
20794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x6c696e6b: /* 'link' */
20814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* DeviceLink profiles cannot be interpreted in a non-device specific
20824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * fashion, if an app uses the AToB0Tag in the profile the results are
20834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * undefined unless the result is sent to the intended device,
20844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * therefore a DeviceLink profile should not be found embedded in a
20854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * PNG.
20864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
20874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_icc_profile_error(png_ptr, colorspace, name, temp,
20884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "unexpected DeviceLink ICC profile class");
20894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x6e6d636c: /* 'nmcl' */
20914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* A NamedColor profile is also device specific, however it doesn't
20924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * contain an AToB0 tag that is open to misinterpretation.  Almost
20934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * certainly it will fail the tests below.
20944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
20954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
20964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "unexpected NamedColor ICC profile class");
20974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
20984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
20994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
21004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* To allow for future enhancements to the profile accept unrecognized
21014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * profile classes with a warning, these then hit the test below on the
21024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * tag content to ensure they are backward compatible with one of the
21034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * understood profiles.
21044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
21054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (void)png_icc_profile_error(png_ptr, NULL, name, temp,
21064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "unrecognized ICC profile class");
21074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
21084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
21094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* For any profile other than a device link one the PCS must be encoded
21114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * either in XYZ or Lab.
21124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
21134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   temp = png_get_uint_32(profile+20);
21144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   switch (temp)
21154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
21164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x58595a20: /* 'XYZ ' */
21174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 0x4c616220: /* 'Lab ' */
21184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
21194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:
21214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_icc_profile_error(png_ptr, colorspace, name, temp,
21224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "unexpected ICC PCS encoding");
21234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
21244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
21264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
21274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
21294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
21304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_charp name, png_uint_32 profile_length,
21314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep profile /* header plus whole tag table */)
21324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
21334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 tag_count = png_get_uint_32(profile+128);
21344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 itag;
21354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep tag = profile+132; /* The first tag */
21364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* First scan all the tags in the table and add bits to the icc_info value
21384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * (temporarily in 'tags').
21394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
21404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   for (itag=0; itag < tag_count; ++itag, tag += 12)
21414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
21424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 tag_id = png_get_uint_32(tag+0);
21434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
21444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
21454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The ICC specification does not exclude zero length tags, therefore the
21474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * start might actually be anywhere if there is no data, but this would be
21484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * a clear abuse of the intent of the standard so the start is checked for
21494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * being in range.  All defined tag types have an 8 byte header - a 4 byte
21504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * type signature then 0.
21514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
21524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((tag_start & 3) != 0)
21534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
21544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
21554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * only a warning here because libpng does not care about the
21564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * alignment.
21574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
21584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
21594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "ICC profile tag start not a multiple of 4");
21604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
21614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* This is a hard error; potentially it can cause read outside the
21634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * profile.
21644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
21654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (tag_start > profile_length || tag_length > profile_length - tag_start)
21664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
21674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            "ICC profile tag outside profile");
21684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
21694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1; /* success, maybe with warnings */
21714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
21724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sRGB_SUPPORTED
21744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if PNG_sRGB_PROFILE_CHECKS >= 0
21754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Information about the known ICC sRGB profiles */
21764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const struct
21774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
21784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 adler, crc, length;
21794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 md5[4];
21804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte    have_md5;
21814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_byte    is_broken;
21824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_16 intent;
21834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
21854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
21864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      { adler, crc, length, md5, broke, intent },
21874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} png_sRGB_checks[] =
21894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
21904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This data comes from contrib/tools/checksum-icc run on downloads of
21914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * all four ICC sRGB profiles from www.color.org.
21924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
21934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* adler32, crc32, MD5[4], intent, date, length, file-name */
21944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
21954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
21964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
21974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
21984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* ICC sRGB v2 perceptual no black-compensation: */
21994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
22004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
22014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
22024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
22044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
22054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
22064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* ICC sRGB v4 perceptual */
22084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
22094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
22104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
22114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following profiles have no known MD5 checksum. If there is a match
22134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * on the (empty) MD5 the other fields are used to attempt a match and
22144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * a warning is produced.  The first two of these profiles have a 'cprt' tag
22154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * which suggests that they were also made by Hewlett Packard.
22164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
22174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
22184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
22194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
22204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
22224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * match the D50 PCS illuminant in the header (it is in fact the D65 values,
22234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * so the white point is recorded as the un-adapted value.)  The profiles
22244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * below only differ in one byte - the intent - and are basically the same as
22254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the previous profile except for the mediaWhitePointTag error and a missing
22264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * chromaticAdaptationTag.
22274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
22284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
22294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
22304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
22314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
22334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
22344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
22354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
22364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
22384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
22394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_bytep profile, uLong adler)
22404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
22414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The quick check is to verify just the MD5 signature and trust the
22424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * rest of the data.  Because the profile has already been verified for
22434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * correctness this is safe.  png_colorspace_set_sRGB will check the 'intent'
22444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * field too, so if the profile has been edited with an intent not defined
22454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * by sRGB (but maybe defined by a later ICC specification) the read of
22464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the profile will fail at that point.
22474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
22484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 length = 0;
22504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 intent = 0x10000; /* invalid */
22514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if PNG_sRGB_PROFILE_CHECKS > 1
22524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   uLong crc = 0; /* the value for 0 length data */
22534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
22544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   unsigned int i;
22554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_OPTION_SUPPORTED
22574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */
22584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) ==
22594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               PNG_OPTION_ON)
22604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
22614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
22624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
22644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
22654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
22664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
22674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
22684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
22694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
22704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This may be one of the old HP profiles without an MD5, in that
22714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * case we can only use the length and Adler32 (note that these
22724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * are not used by default if there is an MD5!)
22734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
22744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#        if PNG_sRGB_PROFILE_CHECKS == 0
22754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (png_sRGB_checks[i].have_md5 != 0)
22764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               return 1+png_sRGB_checks[i].is_broken;
22774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#        endif
22784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Profile is unsigned or more checks have been configured in. */
22804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (length == 0)
22814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
22824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            length = png_get_uint_32(profile);
22834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            intent = png_get_uint_32(profile+64);
22844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
22854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Length *and* intent must match */
22874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (length == (png_uint_32) png_sRGB_checks[i].length &&
22884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            intent == (png_uint_32) png_sRGB_checks[i].intent)
22894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
22904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Now calculate the adler32 if not done already. */
22914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (adler == 0)
22924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
22934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               adler = adler32(0, NULL, 0);
22944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               adler = adler32(adler, profile, length);
22954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
22964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
22974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (adler == png_sRGB_checks[i].adler)
22984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
22994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* These basic checks suggest that the data has not been
23004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * modified, but if the check level is more than 1 perform
23014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * our own crc32 checksum on the data.
23024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
23034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#              if PNG_sRGB_PROFILE_CHECKS > 1
23044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (crc == 0)
23054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
23064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     crc = crc32(0, NULL, 0);
23074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     crc = crc32(crc, profile, length);
23084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
23094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* So this check must pass for the 'return' below to happen.
23114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   */
23124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (crc == png_sRGB_checks[i].crc)
23134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#              endif
23144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
23154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (png_sRGB_checks[i].is_broken != 0)
23164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
23174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     /* These profiles are known to have bad data that may cause
23184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      * problems if they are used, therefore attempt to
23194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      * discourage their use, skip the 'have_md5' warning below,
23204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      * which is made irrelevant by this error.
23214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      */
23224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_chunk_report(png_ptr, "known incorrect sRGB profile",
23234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        PNG_CHUNK_ERROR);
23244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
23254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* Warn that this being done; this isn't even an error since
23274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   * the profile is perfectly valid, but it would be nice if
23284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   * people used the up-to-date ones.
23294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                   */
23304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  else if (png_sRGB_checks[i].have_md5 == 0)
23314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
23324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     png_chunk_report(png_ptr,
23334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        "out-of-date sRGB profile with no signature",
23344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        PNG_CHUNK_WARNING);
23354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
23364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  return 1+png_sRGB_checks[i].is_broken;
23384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
23394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
23404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# if PNG_sRGB_PROFILE_CHECKS > 0
23424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* The signature matched, but the profile had been changed in some
23434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * way.  This probably indicates a data error or uninformed hacking.
23444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * Fall through to "no match".
23454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
23464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_chunk_report(png_ptr,
23474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             "Not recognizing known sRGB profile that has been edited",
23484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             PNG_CHUNK_WARNING);
23494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
23504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif
23514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
23524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
23534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
23544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* no match */
23564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
23574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
23584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
23604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_set_sRGB(png_const_structrp png_ptr,
23614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
23624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
23634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
23644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the sRGB information.
23654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
23664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if PNG_sRGB_PROFILE_CHECKS >= 0
23674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
23684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
23694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (void)png_colorspace_set_sRGB(png_ptr, colorspace,
23704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (int)/*already checked*/png_get_uint_32(profile+64));
23714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
23724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* sRGB */
23734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
23754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
23764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
23774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int color_type)
23784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
23794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
23804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
23814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
23834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
23844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          color_type) != 0 &&
23854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
23864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          profile) != 0)
23874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
23884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_sRGB_SUPPORTED
23894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* If no sRGB support, don't try storing sRGB information */
23904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
23914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
23924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 1;
23934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
23944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Failure case */
23964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
23974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
23984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* iCCP */
23994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
24014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
24024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_rgb_coefficients(png_structrp png_ptr)
24034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
24044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Set the rgb_to_gray coefficients from the colorspace. */
24054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->rgb_to_gray_coefficients_set == 0 &&
24064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
24074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
24084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* png_set_background has not been called, get the coefficients from the Y
24094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * values of the colorspace colorants.
24104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
24114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
24124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
24134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
24144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed_point total = r+g+b;
24154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (total > 0 &&
24174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
24184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
24194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
24204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         r+g+b <= 32769)
24214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
24224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
24234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * all of the coefficients were rounded up.  Handle this by
24244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * reducing the *largest* coefficient by 1; this matches the
24254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * approach used for the default coefficients in pngrtran.c
24264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
24274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int add = 0;
24284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (r+g+b > 32768)
24304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            add = -1;
24314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else if (r+g+b < 32768)
24324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            add = 1;
24334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (add != 0)
24354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
24364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (g >= r && g >= b)
24374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               g += add;
24384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else if (r >= g && r >= b)
24394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               r += add;
24404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else
24414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               b += add;
24424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
24434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Check for an internal error. */
24454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (r+g+b != 32768)
24464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_error(png_ptr,
24474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               "internal error handling cHRM coefficients");
24484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
24504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
24514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
24524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
24534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
24544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
24554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* This is a png_error at present even though it could be ignored -
24574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * it should never happen, but it is important that if it does, the
24584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * bug is fixed.
24594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
24604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
24614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(png_ptr, "internal error handling cHRM->XYZ");
24624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
24634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
24644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_RGB_TO_GRAY */
24654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* COLORSPACE */
24674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* #ifdef __GNUC__ */
24694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if 1
24704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This exists solely to work round a warning from GNU C. */
24714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int /* PRIVATE */
24724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gt(size_t a, size_t b)
24734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
24744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return a > b;
24754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
24764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
24774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#   define png_gt(a,b) ((a) > (b))
24784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
24794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
24814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_check_IHDR(png_const_structrp png_ptr,
24824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 width, png_uint_32 height, int bit_depth,
24834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int color_type, int interlace_type, int compression_type,
24844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int filter_type)
24854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
24864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int error = 0;
24874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Check for width and height valid values */
24894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (width == 0)
24904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
24914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Image width is zero in IHDR");
24924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
24934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
24944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
24954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (width > PNG_UINT_31_MAX)
24964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
24974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Invalid image width in IHDR");
24984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
24994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_gt(((width + 7) & (~7)),
25024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ((PNG_SIZE_MAX
25034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           - 48        /* big_row_buf hack */
25044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           - 1)        /* filter byte */
25054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           / 8)        /* 8-byte RGBA pixels */
25064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           - 1))       /* extra max_pixel_depth pad */
25074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The size of the row must be within the limits of this architecture.
25094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * Because the read code can perform arbitrary transformations the
25104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * maximum size is checked here.  Because the code in png_read_start_row
25114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * adds extra space "for safety's sake" in several places a conservative
25124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * limit is used here.
25134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       *
25144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * NOTE: it would be far better to check the size that is actually used,
25154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * but the effect in the real world is minor and the changes are more
25164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * extensive, therefore much more dangerous and much more difficult to
25174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * write in a way that avoids compiler warnings.
25184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
25194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Image width is too large for this architecture");
25204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_USER_LIMITS_SUPPORTED
25244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (width > png_ptr->user_width_max)
25254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
25264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (width > PNG_USER_WIDTH_MAX)
25274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
25284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Image width exceeds user limit in IHDR");
25304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (height == 0)
25344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Image height is zero in IHDR");
25364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (height > PNG_UINT_31_MAX)
25404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Invalid image height in IHDR");
25424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_USER_LIMITS_SUPPORTED
25464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (height > png_ptr->user_height_max)
25474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
25484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (height > PNG_USER_HEIGHT_MAX)
25494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
25504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Image height exceeds user limit in IHDR");
25524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Check other values */
25564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
25574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       bit_depth != 8 && bit_depth != 16)
25584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Invalid bit depth in IHDR");
25604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (color_type < 0 || color_type == 1 ||
25644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       color_type == 5 || color_type > 6)
25654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Invalid color type in IHDR");
25674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
25714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       ((color_type == PNG_COLOR_TYPE_RGB ||
25724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
25734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
25744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
25764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (interlace_type >= PNG_INTERLACE_LAST)
25804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Unknown interlace method in IHDR");
25824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
25864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
25874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Unknown compression method in IHDR");
25884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
25894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
25904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
25914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_MNG_FEATURES_SUPPORTED
25924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Accept filter_method 64 (intrapixel differencing) only if
25934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
25944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 2. Libpng did not read a PNG signature (this filter_method is only
25954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    used in PNG datastreams that are embedded in MNG datastreams) and
25964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 3. The application called png_permit_mng_features with a mask that
25974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *    included PNG_FLAG_MNG_FILTER_64 and
25984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 4. The filter_method is 64 and
25994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 5. The color_type is RGB or RGBA
26004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
26014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
26024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       png_ptr->mng_features_permitted != 0)
26034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
26044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (filter_type != PNG_FILTER_TYPE_BASE)
26064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
26074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
26084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
26094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
26104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (color_type == PNG_COLOR_TYPE_RGB ||
26114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
26124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
26134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_warning(png_ptr, "Unknown filter method in IHDR");
26144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         error = 1;
26154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
26164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
26184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
26194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_warning(png_ptr, "Invalid filter method in IHDR");
26204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         error = 1;
26214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
26224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
26234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
26254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (filter_type != PNG_FILTER_TYPE_BASE)
26264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
26274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_warning(png_ptr, "Unknown filter method in IHDR");
26284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      error = 1;
26294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
26304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
26314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (error == 1)
26334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_error(png_ptr, "Invalid IHDR data");
26344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
26354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
26374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* ASCII to fp functions */
26384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Check an ASCII formated floating point value, see the more detailed
26394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * comments in pngpriv.h
26404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
26414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following is used internally to preserve the sticky flags */
26424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define png_fp_add(state, flags) ((state) |= (flags))
26434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
26444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
26464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_check_fp_number(png_const_charp string, png_size_t size, int *statep,
26474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_size_tp whereami)
26484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
26494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int state = *statep;
26504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_size_t i = *whereami;
26514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   while (i < size)
26534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
26544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int type;
26554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* First find the type of the next character */
26564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      switch (string[i])
26574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
26584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 43:  type = PNG_FP_SAW_SIGN;                   break;
26594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
26604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 46:  type = PNG_FP_SAW_DOT;                    break;
26614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 48:  type = PNG_FP_SAW_DIGIT;                  break;
26624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 49: case 50: case 51: case 52:
26634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 53: case 54: case 55: case 56:
26644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
26654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 69:
26664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case 101: type = PNG_FP_SAW_E;                      break;
26674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default:  goto PNG_FP_End;
26684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
26694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Now deal with this type according to the current
26714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * state, the type is arranged to not overlap the
26724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * bits of the PNG_FP_STATE.
26734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
26744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
26754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
26764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
26774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((state & PNG_FP_SAW_ANY) != 0)
26784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            goto PNG_FP_End; /* not a part of the number */
26794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fp_add(state, type);
26814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
26824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
26844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Ok as trailer, ok as lead of fraction. */
26854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
26864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            goto PNG_FP_End;
26874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
26894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_fp_add(state, type);
26904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
26924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_fp_set(state, PNG_FP_FRACTION | type);
26934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
26954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
26964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
26974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
26984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
26994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fp_add(state, type | PNG_FP_WAS_VALID);
27014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
27034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_INTEGER + PNG_FP_SAW_E:
27054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((state & PNG_FP_SAW_DIGIT) == 0)
27064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            goto PNG_FP_End;
27074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fp_set(state, PNG_FP_EXPONENT);
27094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
27114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
27134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         goto PNG_FP_End; ** no sign in fraction */
27144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
27164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         goto PNG_FP_End; ** Because SAW_DOT is always set */
27174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
27194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fp_add(state, type | PNG_FP_WAS_VALID);
27204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
27214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_FRACTION + PNG_FP_SAW_E:
27234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* This is correct because the trailing '.' on an
27244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * integer is handled above - so we can only get here
27254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * with the sequence ".E" (with no preceding digits).
27264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
27274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((state & PNG_FP_SAW_DIGIT) == 0)
27284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            goto PNG_FP_End;
27294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fp_set(state, PNG_FP_EXPONENT);
27314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
27334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
27354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if ((state & PNG_FP_SAW_ANY) != 0)
27364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            goto PNG_FP_End; /* not a part of the number */
27374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fp_add(state, PNG_FP_SAW_SIGN);
27394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
27414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
27434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         goto PNG_FP_End; */
27444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
27464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
27474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         break;
27494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
27514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         goto PNG_FP_End; */
27524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      default: goto PNG_FP_End; /* I.e. break 2 */
27544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
27554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The character seems ok, continue. */
27574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      ++i;
27584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
27594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FP_End:
27614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Here at the end, update the state and return the correct
27624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * return code.
27634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
27644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   *statep = state;
27654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   *whereami = i;
27664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (state & PNG_FP_SAW_DIGIT) != 0;
27684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
27694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The same but for a complete string. */
27724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint
27734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_check_fp_string(png_const_charp string, png_size_t size)
27744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
27754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int        state=0;
27764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_size_t char_index=0;
27774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
27794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (char_index == size || string[char_index] == 0))
27804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return state /* must be non-zero - see above */;
27814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* i.e. fail */
27834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
27844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* pCAL || sCAL */
27854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sCAL_SUPPORTED
27874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_FLOATING_POINT_SUPPORTED
27884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Utility used below - a simple accurate power of ten from an integral
27894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * exponent.
27904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
27914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic double
27924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_pow10(int power)
27934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
27944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   int recip = 0;
27954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   double d = 1;
27964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
27974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Handle negative exponent with a reciprocal at the end because
27984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 10 is exact whereas .1 is inexact in base 2
27994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
28004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (power < 0)
28014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
28024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (power < DBL_MIN_10_EXP) return 0;
28034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      recip = 1, power = -power;
28044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
28054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (power > 0)
28074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
28084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Decompose power bitwise. */
28094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      double mult = 10;
28104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      do
28114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
28124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (power & 1) d *= mult;
28134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         mult *= mult;
28144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         power >>= 1;
28154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
28164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (power > 0);
28174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (recip != 0) d = 1/d;
28194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
28204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* else power is 0 and d is 1 */
28214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return d;
28234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
28244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to format a floating point value in ASCII with a given
28264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * precision.
28274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
28284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
28294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
28304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    double fp, unsigned int precision)
28314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
28324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* We use standard functions from math.h, but not printf because
28334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * that would require stdio.  The caller must supply a buffer of
28344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * sufficient size or we will png_error.  The tests on size and
28354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the space in ascii[] consumed are indicated below.
28364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
28374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (precision < 1)
28384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      precision = DBL_DIG;
28394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Enforce the limit of the implementation precision too. */
28414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (precision > DBL_DIG+1)
28424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      precision = DBL_DIG+1;
28434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Basic sanity checks */
28454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (size >= precision+5) /* See the requirements below. */
28464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
28474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (fp < 0)
28484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
28494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         fp = -fp;
28504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */
28514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         --size;
28524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
28534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (fp >= DBL_MIN && fp <= DBL_MAX)
28554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
28564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int exp_b10;   /* A base 10 exponent */
28574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         double base;   /* 10^exp_b10 */
28584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* First extract a base 10 exponent of the number,
28604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * the calculation below rounds down when converting
28614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * from base 2 to base 10 (multiply by log10(2) -
28624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
28634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * be increased.  Note that the arithmetic shift
28644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * performs a floor() unlike C arithmetic - using a
28654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * C multiply would break the following for negative
28664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * exponents.
28674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
28684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         (void)frexp(fp, &exp_b10); /* exponent to base 2 */
28694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
28714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Avoid underflow here. */
28734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         base = png_pow10(exp_b10); /* May underflow */
28744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         while (base < DBL_MIN || base < fp)
28764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
28774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* And this may overflow. */
28784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            double test = png_pow10(exp_b10+1);
28794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (test <= DBL_MAX)
28814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               ++exp_b10, base = test;
28824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else
28844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               break;
28854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
28864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Normalize fp and correct exp_b10, after this fp is in the
28884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * range [.1,1) and exp_b10 is both the exponent and the digit
28894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * *before* which the decimal point should be inserted
28904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * (starting with 0 for the first digit).  Note that this
28914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * works even if 10^exp_b10 is out of range because of the
28924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * test on DBL_MAX above.
28934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
28944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         fp /= base;
28954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         while (fp >= 1) fp /= 10, ++exp_b10;
28964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
28974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Because of the code above fp may, at this point, be
28984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * less than .1, this is ok because the code below can
28994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * handle the leading zeros this generates, so no attempt
29004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * is made to correct that here.
29014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
29024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
29044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            unsigned int czero, clead, cdigits;
29054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            char exponent[10];
29064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Allow up to two leading zeros - this will not lengthen
29084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * the number compared to using E-n.
29094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
29104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
29114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
29124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
29134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               exp_b10 = 0;      /* Dot added below before first output. */
29144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
29154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            else
29164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               czero = 0;    /* No zeros to add */
29174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Generate the digit list, stripping trailing zeros and
29194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * inserting a '.' before a digit if the exponent is 0.
29204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
29214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            clead = czero; /* Count of leading zeros */
29224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            cdigits = 0;   /* Count of digits in list. */
29234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            do
29254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
29264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               double d;
29274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               fp *= 10;
29294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* Use modf here, not floor and subtract, so that
29304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * the separation is done in one step.  At the end
29314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * of the loop don't break the number into parts so
29324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * that the final digit is rounded.
29334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
29344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (cdigits+czero+1 < precision+clead)
29354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  fp = modf(fp, &d);
29364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
29384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
29394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  d = floor(fp + .5);
29404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (d > 9)
29424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
29434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     /* Rounding up to 10, handle that here. */
29444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (czero > 0)
29454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
29464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        --czero, d = 1;
29474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (cdigits == 0) --clead;
29484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
29494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     else
29504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
29514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        while (cdigits > 0 && d > 9)
29524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
29534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           int ch = *--ascii;
29544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           if (exp_b10 != (-1))
29564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              ++exp_b10;
29574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           else if (ch == 46)
29594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           {
29604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              ch = *--ascii, ++size;
29614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              /* Advance exp_b10 to '1', so that the
29624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               * decimal point happens after the
29634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               * previous digit.
29644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               */
29654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              exp_b10 = 1;
29664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           }
29674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           --cdigits;
29694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           d = ch - 47;  /* I.e. 1+(ch-48) */
29704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
29714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        /* Did we reach the beginning? If so adjust the
29734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         * exponent but take into account the leading
29744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         * decimal point.
29754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                         */
29764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (d > 9)  /* cdigits == 0 */
29774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        {
29784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           if (exp_b10 == (-1))
29794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           {
29804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              /* Leading decimal point (plus zeros?), if
29814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               * we lose the decimal point here it must
29824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               * be reentered below.
29834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               */
29844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              int ch = *--ascii;
29854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              if (ch == 46)
29874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 ++size, exp_b10 = 1;
29884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              /* Else lost a leading zero, so 'exp_b10' is
29904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               * still ok at (-1)
29914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                               */
29924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           }
29934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           else
29944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                              ++exp_b10;
29954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
29964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           /* In all cases we output a '1' */
29974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           d = 1;
29984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        }
29994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
30004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
30014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  fp = 0; /* Guarantees termination below. */
30024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
30034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (d == 0)
30054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
30064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  ++czero;
30074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (cdigits == 0) ++clead;
30084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
30094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
30104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
30114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  /* Included embedded zeros in the digit count. */
30124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  cdigits += czero - clead;
30134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  clead = 0;
30144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  while (czero > 0)
30164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
30174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     /* exp_b10 == (-1) means we just output the decimal
30184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      * place - after the DP don't adjust 'exp_b10' any
30194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      * more!
30204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                      */
30214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (exp_b10 != (-1))
30224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     {
30234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        if (exp_b10 == 0) *ascii++ = 46, --size;
30244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        /* PLUS 1: TOTAL 4 */
30254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        --exp_b10;
30264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     }
30274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     *ascii++ = 48, --czero;
30284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
30294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (exp_b10 != (-1))
30314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  {
30324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     if (exp_b10 == 0)
30334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                        *ascii++ = 46, --size; /* counted above */
30344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     --exp_b10;
30364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  }
30374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *ascii++ = (char)(48 + (int)d), ++cdigits;
30384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
30394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
30404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (cdigits+czero < precision+clead && fp > DBL_MIN);
30414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* The total output count (max) is now 4+precision */
30434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Check for an exponent, if we don't need one we are
30454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * done and just need to terminate the string.  At
30464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * this point exp_b10==(-1) is effectively if flag - it got
30474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * to '-1' because of the decrement after outputting
30484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * the decimal point above (the exponent required is
30494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * *not* -1!)
30504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
30514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (exp_b10 >= (-1) && exp_b10 <= 2)
30524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
30534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* The following only happens if we didn't output the
30544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * leading zeros above for negative exponent, so this
30554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * doesn't add to the digit requirement.  Note that the
30564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * two zeros here can only be output if the two leading
30574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * zeros were *not* output, so this doesn't increase
30584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * the output count.
30594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
30604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               while (--exp_b10 >= 0) *ascii++ = 48;
30614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *ascii = 0;
30634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* Total buffer requirement (including the '\0') is
30654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * 5+precision - see check at the start.
30664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
30674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               return;
30684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
30694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Here if an exponent is required, adjust size for
30714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * the digits we output but did not count.  The total
30724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * digit output here so far is at most 1+precision - no
30734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * decimal point and no leading or trailing zeros have
30744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * been output.
30754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
30764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            size -= cdigits;
30774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */
30794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* The following use of an unsigned temporary avoids ambiguities in
30814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * the signed arithmetic on exp_b10 and permits GCC at least to do
30824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * better optimization.
30834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
30844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
30854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               unsigned int uexp_b10;
30864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (exp_b10 < 0)
30884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
30894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
30904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  uexp_b10 = -exp_b10;
30914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
30924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
30944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  uexp_b10 = exp_b10;
30954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               cdigits = 0;
30974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
30984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               while (uexp_b10 > 0)
30994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
31004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
31014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  uexp_b10 /= 10;
31024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
31034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
31044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Need another size check here for the exponent digits, so
31064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * this need not be considered above.
31074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
31084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (size > cdigits)
31094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
31104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               while (cdigits > 0) *ascii++ = exponent[--cdigits];
31114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *ascii = 0;
31134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               return;
31154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
31164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
31174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
31184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else if (!(fp >= DBL_MIN))
31194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
31204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii++ = 48; /* '0' */
31214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii = 0;
31224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return;
31234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
31244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
31254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
31264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii++ = 105; /* 'i' */
31274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii++ = 110; /* 'n' */
31284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii++ = 102; /* 'f' */
31294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii = 0;
31304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return;
31314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
31324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
31334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Here on buffer too small. */
31354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_error(png_ptr, "ASCII conversion buffer too small");
31364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
31374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif /* FLOATING_POINT */
31394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_FIXED_POINT_SUPPORTED
31414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to format a fixed point value in ASCII.
31424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
31434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
31444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
31454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_size_t size, png_fixed_point fp)
31464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
31474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Require space for 10 decimal digits, a decimal point, a minus sign and a
31484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * trailing \0, 13 characters:
31494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
31504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (size > 12)
31514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
31524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 num;
31534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Avoid overflow here on the minimum integer. */
31554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (fp < 0)
31564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii++ = 45, num = -fp;
31574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
31584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         num = fp;
31594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (num <= 0x80000000) /* else overflowed */
31614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
31624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         unsigned int ndigits = 0, first = 16 /* flag value */;
31634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         char digits[10];
31644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         while (num)
31664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
31674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Split the low digit off num: */
31684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            unsigned int tmp = num/10;
31694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            num -= tmp*10;
31704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            digits[ndigits++] = (char)(48 + num);
31714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Record the first non-zero digit, note that this is a number
31724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * starting at 1, it's not actually the array index.
31734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
31744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (first == 16 && num > 0)
31754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               first = ndigits;
31764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            num = tmp;
31774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
31784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
31794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (ndigits > 0)
31804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
31814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (ndigits > 5) *ascii++ = digits[--ndigits];
31824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* The remaining digits are fractional digits, ndigits is '5' or
31834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * smaller at this point.  It is certainly not zero.  Check for a
31844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * non-zero fractional digit:
31854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
31864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (first <= 5)
31874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
31884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               unsigned int i;
31894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *ascii++ = 46; /* decimal point */
31904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* ndigits may be <5 for small numbers, output leading zeros
31914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * then ndigits digits to first:
31924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
31934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               i = 5;
31944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               while (ndigits < i) *ascii++ = 48, --i;
31954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               while (ndigits >= first) *ascii++ = digits[--ndigits];
31964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* Don't output the trailing zeros! */
31974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
31984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
31994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
32004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *ascii++ = 48;
32014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* And null terminate the string: */
32034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *ascii = 0;
32044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return;
32054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
32064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
32074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Here on buffer too small. */
32094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_error(png_ptr, "ASCII conversion buffer too small");
32104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
32114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#   endif /* FIXED_POINT */
32124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SCAL */
32134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
32154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
32164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
32174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
32184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
32194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   (defined(PNG_sCAL_SUPPORTED) && \
32204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
32214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point
32224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
32234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
32244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   double r = floor(100000 * fp + .5);
32254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (r > 2147483647. || r < -2147483648.)
32274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_fixed_error(png_ptr, text);
32284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifndef PNG_ERROR_TEXT_SUPPORTED
32304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_UNUSED(text)
32314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
32324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_fixed_point)r;
32344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
32354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
32364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
32384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
32394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* muldiv functions */
32404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This API takes signed arguments and rounds the result to the nearest
32414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * integer (or, for a fixed point number - the standard argument - to
32424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the nearest .00001).  Overflow and divide by zero are signalled in
32434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the result, a boolean - true on success, false on overflow.
32444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
32454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint
32464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
32474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_int_32 divisor)
32484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
32494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Return a * times / divisor, rounded. */
32504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (divisor != 0)
32514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
32524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (a == 0 || times == 0)
32534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
32544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         *res = 0;
32554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return 1;
32564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
32574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
32584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
32594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
32604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         double r = a;
32614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         r *= times;
32624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         r /= divisor;
32634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         r = floor(r+.5);
32644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* A png_fixed_point is a 32-bit integer. */
32664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (r <= 2147483647. && r >= -2147483648.)
32674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
32684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            *res = (png_fixed_point)r;
32694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return 1;
32704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
32714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
32724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         int negative = 0;
32734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_32 A, T, D;
32744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_uint_32 s16, s32, s00;
32754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (a < 0)
32774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            negative = 1, A = -a;
32784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
32794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            A = a;
32804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (times < 0)
32824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            negative = !negative, T = -times;
32834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
32844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            T = times;
32854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (divisor < 0)
32874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            negative = !negative, D = -divisor;
32884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         else
32894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            D = divisor;
32904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
32914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Following can't overflow because the arguments only
32924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * have 31 bits each, however the result may be 32 bits.
32934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
32944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         s16 = (A >> 16) * (T & 0xffff) +
32954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                           (A & 0xffff) * (T >> 16);
32964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Can't overflow because the a*times bit is only 30
32974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * bits at most.
32984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
32994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
33004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         s00 = (A & 0xffff) * (T & 0xffff);
33014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         s16 = (s16 & 0xffff) << 16;
33034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         s00 += s16;
33044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (s00 < s16)
33064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            ++s32; /* carry */
33074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (s32 < D) /* else overflow */
33094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
33104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* s32.s00 is now the 64-bit product, do a standard
33114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * division, we know that s32 < D, so the maximum
33124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             * required shift is 31.
33134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann             */
33144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            int bitshift = 32;
33154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_fixed_point result = 0; /* NOTE: signed */
33164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            while (--bitshift >= 0)
33184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
33194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               png_uint_32 d32, d00;
33204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (bitshift > 0)
33224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  d32 = D >> (32-bitshift), d00 = D << bitshift;
33234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
33254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  d32 = 0, d00 = D;
33264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (s32 > d32)
33284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               {
33294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (s00 < d00) --s32; /* carry */
33304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  s32 -= d32, s00 -= d00, result += 1<<bitshift;
33314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               }
33324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               else
33344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  if (s32 == d32 && s00 >= d00)
33354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     s32 = 0, s00 -= d00, result += 1<<bitshift;
33364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
33374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Handle the rounding. */
33394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (s00 >= (D >> 1))
33404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               ++result;
33414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (negative != 0)
33434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               result = -result;
33444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            /* Check for overflow. */
33464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if ((negative != 0 && result <= 0) ||
33474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                (negative == 0 && result >= 0))
33484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            {
33494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               *res = result;
33504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               return 1;
33514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            }
33524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
33534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
33544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
33554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
33564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
33584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
33594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA || INCH_CONVERSIONS */
33604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
33624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following is for when the caller doesn't much care about the
33634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * result.
33644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
33654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point
33664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
33674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_int_32 divisor)
33684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
33694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point result;
33704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&result, a, times, divisor) != 0)
33724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return result;
33734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_warning(png_ptr, "fixed point overflow ignored");
33754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
33764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
33774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
33784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
33804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
33814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point
33824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reciprocal(png_fixed_point a)
33834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
33844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
33854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   double r = floor(1E10/a+.5);
33864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (r <= 2147483647. && r >= -2147483648.)
33884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return (png_fixed_point)r;
33894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
33904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point res;
33914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&res, 100000, 100000, a) != 0)
33934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return res;
33944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
33954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* error/overflow */
33974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
33984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
33994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This is the shared test on whether a gamma value is 'significant' - whether
34004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it is worth doing gamma correction.
34014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
34024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
34034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_significant(png_fixed_point gamma_val)
34044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
34054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
34064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
34074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
34084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
34094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED
34114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
34124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* A local convenience routine. */
34134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_fixed_point
34144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_product2(png_fixed_point a, png_fixed_point b)
34154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
34164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The required result is 1/a * 1/b; the following preserves accuracy. */
34174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
34184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   double r = a * 1E-5;
34194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   r *= b;
34204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   r = floor(r+.5);
34214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (r <= 2147483647. && r >= -2147483648.)
34234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return (png_fixed_point)r;
34244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
34254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point res;
34264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_muldiv(&res, a, b, 100000) != 0)
34284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return res;
34294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
34304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* overflow */
34324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
34334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
34344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The inverse of the above. */
34364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point
34374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reciprocal2(png_fixed_point a, png_fixed_point b)
34384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
34394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The required result is 1/a * 1/b; the following preserves accuracy. */
34404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
34414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (a != 0 && b != 0)
34424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
34434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      double r = 1E15/a;
34444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      r /= b;
34454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      r = floor(r+.5);
34464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (r <= 2147483647. && r >= -2147483648.)
34484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return (png_fixed_point)r;
34494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
34504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
34514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* This may overflow because the range of png_fixed_point isn't symmetric,
34524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * but this API is only used for the product of file and screen gamma so it
34534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * doesn't matter that the smallest number it can produce is 1/21474, not
34544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 1/100000
34554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
34564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_fixed_point res = png_product2(a, b);
34574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (res != 0)
34594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_reciprocal(res);
34604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
34614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0; /* overflow */
34634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
34644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA */
34654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
34664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
34674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
34684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Fixed point gamma.
34694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
34704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The code to calculate the tables used below can be found in the shell script
34714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contrib/tools/intgamma.sh
34724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
34734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * To calculate gamma this code implements fast log() and exp() calls using only
34744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * fixed point arithmetic.  This code has sufficient precision for either 8-bit
34754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or 16-bit sample values.
34764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
34774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The tables used here were calculated using simple 'bc' programs, but C double
34784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * precision floating point arithmetic would work fine.
34794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
34804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8-bit log table
34814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
34824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   255, so it's the base 2 logarithm of a normalized 8-bit floating point
34834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   mantissa.  The numbers are 32-bit fractions.
34844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
34854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_uint_32
34864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_8bit_l2[128] =
34874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
34884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
34894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
34904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
34914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
34924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
34934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
34944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
34954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
34964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
34974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
34984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
34994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
35004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
35014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
35024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
35034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
35044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
35054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
35064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
35074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
35084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
35094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   24347096U, 0U
35104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if 0
35124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* The following are the values for 16-bit tables - these work fine for the
35134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 8-bit conversions but produce very slightly larger errors in the 16-bit
35144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
35154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * use these all the shifts below must be adjusted appropriately.
35164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
35174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
35184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
35194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
35204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
35214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
35224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
35234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
35244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
35254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
35264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
35274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
35284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1119, 744, 372
35294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
35304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
35314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_int_32
35334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_log8bit(unsigned int x)
35344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
35354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   unsigned int lg2 = 0;
35364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
35374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * because the log is actually negate that means adding 1.  The final
35384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
35394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * input), return -1 for the overflow (log 0) case, - so the result is
35404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * always at most 19 bits.
35414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
35424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x &= 0xff) == 0)
35434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return -1;
35444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x & 0xf0) == 0)
35464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2  = 4, x <<= 4;
35474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x & 0xc0) == 0)
35494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2 += 2, x <<= 2;
35504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x & 0x80) == 0)
35524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2 += 1, x <<= 1;
35534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* result is at most 19 bits, so this cast is safe: */
35554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
35564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
35574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
35594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * for 16-bit images we use the most significant 8 bits of the 16-bit value to
35604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * get an approximation then multiply the approximation by a correction factor
35614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * determined by the remaining up to 8 bits.  This requires an additional step
35624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in the 16-bit case.
35634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
35644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * We want log2(value/65535), we have log2(v'/255), where:
35654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
35664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *    value = v' * 256 + v''
35674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *          = v' * f
35684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
35694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
35704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
35714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * than 258.  The final factor also needs to correct for the fact that our 8-bit
35724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
35734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
35744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This gives a final formula using a calculated value 'x' which is value/v' and
35754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * scaling by 65536 to match the above table:
35764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
35774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *   log2(x/257) * 65536
35784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
35794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Since these numbers are so close to '1' we can use simple linear
35804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * interpolation between the two end values 256/257 (result -368.61) and 258/257
35814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (result 367.179).  The values used below are scaled by a further 64 to give
35824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16-bit precision in the interpolation:
35834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
35844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Start (256): -23591
35854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Zero  (257):      0
35864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * End   (258):  23499
35874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
35884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
35894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_int_32
35904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_log16bit(png_uint_32 x)
35914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
35924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   unsigned int lg2 = 0;
35934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* As above, but now the input has 16 bits. */
35954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x &= 0xffff) == 0)
35964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return -1;
35974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
35984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x & 0xff00) == 0)
35994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2  = 8, x <<= 8;
36004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x & 0xf000) == 0)
36024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2 += 4, x <<= 4;
36034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x & 0xc000) == 0)
36054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2 += 2, x <<= 2;
36064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if ((x & 0x8000) == 0)
36084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2 += 1, x <<= 1;
36094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
36114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * value.
36124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
36134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   lg2 <<= 28;
36144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
36154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Now we need to interpolate the factor, this requires a division by the top
36174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 8 bits.  Do this with maximum precision.
36184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
36194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   x = ((x << 16) + (x >> 9)) / (x >> 8);
36204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
36224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
36234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 16 bits to interpolate to get the low bits of the result.  Round the
36244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * answer.  Note that the end point values are scaled by 64 to retain overall
36254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
36264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the overall scaling by 6-12.  Round at every step.
36274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
36284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   x -= 1U << 24;
36294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (x <= 65536U) /* <= '257' */
36314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
36324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
36344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
36354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Safe, because the result can't have more than 20 bits: */
36374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_int_32)((lg2 + 2048) >> 12);
36384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
36394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
36404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The 'exp()' case must invert the above, taking a 20-bit fixed point
36424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * logarithmic value and returning a 16 or 8-bit number as appropriate.  In
36434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * each case only the low 16 bits are relevant - the fraction - since the
36444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * integer bits (the top 4) simply determine a shift.
36454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
36464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The worst case is the 16-bit distinction between 65535 and 65534. This
36474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * requires perhaps spurious accuracy in the decoding of the logarithm to
36484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance
36494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of getting this accuracy in practice.
36504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
36514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * To deal with this the following exp() function works out the exponent of the
36524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * frational part of the logarithm by using an accurate 32-bit value from the
36534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * top four fractional bits then multiplying in the remaining bits.
36544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
36554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_uint_32
36564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_32bit_exp[16] =
36574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
36584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
36594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
36604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
36614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   2553802834U, 2445529972U, 2341847524U, 2242560872U
36624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
36634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Adjustment table; provided to explain the numbers in the code below. */
36654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if 0
36664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannfor (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
36674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   11 44937.64284865548751208448
36684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   10 45180.98734845585101160448
36694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    9 45303.31936980687359311872
36704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    8 45364.65110595323018870784
36714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    7 45395.35850361789624614912
36724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    6 45410.72259715102037508096
36734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    5 45418.40724413220722311168
36744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    4 45422.25021786898173001728
36754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    3 45424.17186732298419044352
36764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    2 45425.13273269940811464704
36774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    1 45425.61317555035558641664
36784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    0 45425.85339951654943850496
36794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
36804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_uint_32
36824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_exp(png_fixed_point x)
36834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
36844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
36854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
36864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Obtain a 4-bit approximation */
36874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];
36884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Incorporate the low 12 bits - these decrease the returned value by
36904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * multiplying by a number less than 1 if the bit is set.  The multiplier
36914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * is determined by the above table and the shift. Notice that the values
36924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * converge on 45426 and this is used to allow linear interpolation of the
36934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * low bits.
36944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
36954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (x & 0x800)
36964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         e -= (((e >> 16) * 44938U) +  16U) >> 5;
36974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
36984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (x & 0x400)
36994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         e -= (((e >> 16) * 45181U) +  32U) >> 6;
37004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (x & 0x200)
37024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         e -= (((e >> 16) * 45303U) +  64U) >> 7;
37034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (x & 0x100)
37054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         e -= (((e >> 16) * 45365U) + 128U) >> 8;
37064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (x & 0x080)
37084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         e -= (((e >> 16) * 45395U) + 256U) >> 9;
37094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (x & 0x040)
37114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         e -= (((e >> 16) * 45410U) + 512U) >> 10;
37124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* And handle the low 6 bits in a single block. */
37144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
37154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Handle the upper bits of x. */
37174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      e >>= x >> 16;
37184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return e;
37194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
37204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Check for overflow */
37224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (x <= 0)
37234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_32bit_exp[0];
37244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Else underflow */
37264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
37274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
37284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_byte
37304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_exp8bit(png_fixed_point lg2)
37314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
37324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Get a 32-bit value: */
37334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 x = png_exp(lg2);
37344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the
37364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * second, rounding, step can't overflow because of the first, subtraction,
37374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * step.
37384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
37394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   x -= x >> 8;
37404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
37414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
37424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
37444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_uint_16
37454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_exp16bit(png_fixed_point lg2)
37464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
37474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Get a 32-bit value: */
37484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 x = png_exp(lg2);
37494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
37514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   x -= x >> 16;
37524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_uint_16)((x + 32767U) >> 16);
37534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
37544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
37554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* FLOATING_ARITHMETIC */
37564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_byte
37584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
37594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
37604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (value > 0 && value < 255)
37614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
37624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
37634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
37644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * convert this to a floating point value.  This includes values that
37654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * would overflow if 'value' were to be converted to 'int'.
37664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
37674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * Apparently GCC, however, does an intermediate conversion to (int)
37684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * on some (ARM) but not all (x86) platforms, possibly because of
37694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * hardware FP limitations.  (E.g. if the hardware conversion always
37704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * assumes the integer register contains a signed value.)  This results
37714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * in ANSI-C undefined behavior for large values.
37724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
37734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * Other implementations on the same machine might actually be ANSI-C90
37744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * conformant and therefore compile spurious extra code for the large
37754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * values.
37764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
37774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * We can be reasonably sure that an unsigned to float conversion
37784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * won't be faster than an int to float one.  Therefore this code
37794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * assumes responsibility for the undefined behavior, which it knows
37804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * can't happen because of the check above.
37814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
37824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * Note the argument to this routine is an (unsigned int) because, on
37834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * 16-bit platforms, it is assigned a value which might be out of
37844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * range for an (int); that would result in undefined behavior in the
37854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * caller if the *argument* ('value') were to be declared (int).
37864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
37874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);
37884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return (png_byte)r;
37894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     else
37904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_int_32 lg2 = png_log8bit(value);
37914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fixed_point res;
37924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
37944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return png_exp8bit(res);
37954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
37964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Overflow. */
37974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         value = 0;
37984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
37994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
38004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_byte)(value & 0xff);
38024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
38034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
38054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_uint_16
38064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
38074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
38084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (value > 0 && value < 65535)
38094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
38104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
38114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* The same (unsigned int)->(double) constraints apply here as above,
38124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * however in this case the (unsigned int) to (int) conversion can
38134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * overflow on an ANSI-C90 compliant system so the cast needs to ensure
38144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * that this is not possible.
38154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
38164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         double r = floor(65535*pow((png_int_32)value/65535.,
38174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                     gamma_val*.00001)+.5);
38184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         return (png_uint_16)r;
38194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     else
38204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_int_32 lg2 = png_log16bit(value);
38214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_fixed_point res;
38224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
38244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            return png_exp16bit(res);
38254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Overflow. */
38274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         value = 0;
38284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
38294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
38304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return (png_uint_16)value;
38324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
38334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
38344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This does the right thing based on the bit_depth field of the
38364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_struct, interpreting values as 8-bit or 16-bit.  While the result
38374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is nominally a 16-bit value if bit depth is 8 then the result is
38384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8-bit (as are the arguments.)
38394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
38404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_uint_16 /* PRIVATE */
38414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_correct(png_structrp png_ptr, unsigned int value,
38424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_fixed_point gamma_val)
38434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
38444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->bit_depth == 8)
38454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_gamma_8bit_correct(value, gamma_val);
38464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
38484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
38494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return png_gamma_16bit_correct(value, gamma_val);
38504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else
38514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* should not reach this */
38524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
38534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
38544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
38554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
38574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Internal function to build a single 16-bit table - the table consists of
38584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
38594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to shift the input values right (or 16-number_of_signifiant_bits).
38604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
38614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The caller is responsible for ensuring that the table gets cleaned up on
38624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
38634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * should be somewhere that will be cleaned.
38644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
38654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
38664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
38674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
38684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
38694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Various values derived from 'shift': */
38704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST unsigned int num = 1U << (8U - shift);
38714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
38724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* CSE the division and work round wacky GCC warnings (see the comments
38734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * in png_gamma_8bit_correct for where these come from.)
38744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
38754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1);
38764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
38774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
38784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
38794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   unsigned int i;
38804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_16pp table = *ptable =
38824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
38834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   for (i = 0; i < num; i++)
38854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
38864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_16p sub_table = table[i] =
38874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));
38884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
38894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* The 'threshold' test is repeated here because it can arise for one of
38904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       * the 16-bit tables even if the others don't hit it.
38914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       */
38924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (png_gamma_significant(gamma_val) != 0)
38934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
38944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* The old code would overflow at the end and this would cause the
38954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * 'pow' function to return a result >1, resulting in an
38964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * arithmetic error.  This code follows the spec exactly; ig is
38974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * the recovered input sample, it always has 8-16 bits.
38984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          *
38994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * We want input * 65535/max, rounded, the arithmetic fits in 32
39004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          * bits (unsigned) so long as max <= 32767.
39014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          */
39024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         unsigned int j;
39034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (j = 0; j < 256; j++)
39044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
39054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 ig = (j << (8-shift)) + i;
39064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
39074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* Inline the 'max' scaling operation: */
39084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               /* See png_gamma_8bit_correct for why the cast to (int) is
39094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                * required here.
39104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                */
39114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);
39124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sub_table[j] = (png_uint_16)d;
39134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#           else
39144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               if (shift != 0)
39154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                  ig = (ig * 65535U + max_by_2)/max;
39164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
39184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#           endif
39194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
39204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
39214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      else
39224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
39234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* We must still build a table, but do it the fast way. */
39244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         unsigned int j;
39254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         for (j = 0; j < 256; j++)
39274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
39284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_uint_32 ig = (j << (8-shift)) + i;
39294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            if (shift != 0)
39314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann               ig = (ig * 65535U + max_by_2)/max;
39324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            sub_table[j] = (png_uint_16)ig;
39344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
39354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
39364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
39374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
39384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* NOTE: this function expects the *inverse* of the overall gamma transformation
39404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required.
39414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
39424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
39434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
39444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
39454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
39464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST unsigned int num = 1U << (8U - shift);
39474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
39484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   unsigned int i;
39494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_32 last;
39504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_uint_16pp table = *ptable =
39524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
39534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* 'num' is the number of tables and also the number of low bits of low
39554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * bits of the input 16-bit value used to select a table.  Each table is
39564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * itself indexed by the high 8 bits of the value.
39574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
39584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   for (i = 0; i < num; i++)
39594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      table[i] = (png_uint_16p)png_malloc(png_ptr,
39604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          256 * (sizeof (png_uint_16)));
39614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* 'gamma_val' is set to the reciprocal of the value calculated above, so
39634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * pow(out,g) is an *input* value.  'last' is the last input value set.
39644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
39654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * In the loop 'i' is used to find output values.  Since the output is
39664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 8-bit there are only 256 possible values.  The tables are set up to
39674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * select the closest possible output value for each input by finding
39684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * the input value at the boundary between each pair of output values
39694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * and filling the table up to that boundary with the lower output
39704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * value.
39714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    *
39724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit
39734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * values the code below uses a 16-bit value in i; the values start at
39744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
39754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * entries are filled with 255).  Start i at 128 and fill all 'last'
39764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * table entries <= 'max'
39774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
39784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   last = 0;
39794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   for (i = 0; i < 255; ++i) /* 8-bit output value */
39804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
39814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Find the corresponding maximum input value */
39824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
39834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Find the boundary value in 16 bits: */
39854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
39864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Adjust (round) to (16-shift) bits: */
39884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      bound = (bound * max + 32768U)/65535U + 1U;
39894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      while (last < bound)
39914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
39924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
39934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         last++;
39944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
39954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
39964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
39974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* And fill in the final entries. */
39984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   while (last < (num << 8))
39994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
40004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
40014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      last++;
40024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
40034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
40044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
40054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
40074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * typically much faster).  Note that libpng currently does no sBIT processing
40084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (apparently contrary to the spec) so a 256-entry table is always generated.
40094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
40104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void
40114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
40124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   PNG_CONST png_fixed_point gamma_val)
40134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
40144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   unsigned int i;
40154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
40164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_gamma_significant(gamma_val) != 0)
40184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i=0; i<256; i++)
40194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         table[i] = png_gamma_8bit_correct(i, gamma_val);
40204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
40224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i=0; i<256; ++i)
40234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         table[i] = (png_byte)(i & 0xff);
40244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
40254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Used from png_read_destroy and below to release the memory used by the gamma
40274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * tables.
40284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
40294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
40304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_destroy_gamma_table(png_structrp png_ptr)
40314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
40324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(png_ptr, png_ptr->gamma_table);
40334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->gamma_table = NULL;
40344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
40364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->gamma_16_table != NULL)
40374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
40384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
40394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int istop = (1 << (8 - png_ptr->gamma_shift));
40404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i = 0; i < istop; i++)
40414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
40424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, png_ptr->gamma_16_table[i]);
40434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
40444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(png_ptr, png_ptr->gamma_16_table);
40454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->gamma_16_table = NULL;
40464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
40474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
40484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
40504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
40514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
40524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(png_ptr, png_ptr->gamma_from_1);
40534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->gamma_from_1 = NULL;
40544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(png_ptr, png_ptr->gamma_to_1);
40554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->gamma_to_1 = NULL;
40564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
40584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->gamma_16_from_1 != NULL)
40594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
40604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
40614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int istop = (1 << (8 - png_ptr->gamma_shift));
40624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i = 0; i < istop; i++)
40634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
40644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
40654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
40664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(png_ptr, png_ptr->gamma_16_from_1);
40674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->gamma_16_from_1 = NULL;
40684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
40694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr->gamma_16_to_1 != NULL)
40704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
40714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int i;
40724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int istop = (1 << (8 - png_ptr->gamma_shift));
40734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (i = 0; i < istop; i++)
40744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
40754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
40764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
40774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(png_ptr, png_ptr->gamma_16_to_1);
40784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_ptr->gamma_16_to_1 = NULL;
40794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
40804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
40814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
40824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
40834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
40854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * tables, we don't make a full table if we are reducing to 8-bit in
40864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the future.  Note also how the gamma_16 tables are segmented so that
40874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * we don't need to allocate > 64K chunks for a full 16-bit table.
40884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
40894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */
40904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_gamma_table(png_structrp png_ptr, int bit_depth)
40914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
40924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  png_debug(1, "in png_build_gamma_table");
40934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
40944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  /* Remove any existing table; this copes with multiple calls to
40954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   * png_read_update_info.  The warning is because building the gamma tables
40964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   * multiple times is a performance hit - it's harmless but the ability to call
40974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
40984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   * to warn if the app introduces such a hit.
40994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   */
41004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
41014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  {
41024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_warning(png_ptr, "gamma table being rebuilt");
41034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    png_destroy_gamma_table(png_ptr);
41044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
41054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (bit_depth <= 8)
41074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  {
41084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
41094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->screen_gamma > 0 ?  png_reciprocal2(png_ptr->colorspace.gamma,
41104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->screen_gamma) : PNG_FP_1);
41114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
41134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
41144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
41154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
41164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     {
41174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
41184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_reciprocal(png_ptr->colorspace.gamma));
41194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
41214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->screen_gamma > 0 ?  png_reciprocal(png_ptr->screen_gamma) :
41224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
41234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     }
41244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
41254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
41264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED
41274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  else
41284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  {
41294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     png_byte shift, sig_bit;
41304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
41324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     {
41334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sig_bit = png_ptr->sig_bit.red;
41344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (png_ptr->sig_bit.green > sig_bit)
41364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           sig_bit = png_ptr->sig_bit.green;
41374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (png_ptr->sig_bit.blue > sig_bit)
41394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           sig_bit = png_ptr->sig_bit.blue;
41404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     }
41414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     else
41424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        sig_bit = png_ptr->sig_bit.gray;
41434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     /* 16-bit gamma code uses this equation:
41454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *
41464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
41474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *
41484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * Where 'iv' is the input color value and 'ov' is the output value -
41494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * pow(iv, gamma).
41504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *
41514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * Thus the gamma table consists of up to 256 256-entry tables.  The table
41524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * is selected by the (8-gamma_shift) most significant of the low 8 bits of
41534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * the color value then indexed by the upper 8 bits:
41544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *
41554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *   table[low bits][high 8 bits]
41564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *
41574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * So the table 'n' corresponds to all those 'iv' of:
41584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *
41594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
41604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      *
41614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      */
41624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     if (sig_bit > 0 && sig_bit < 16U)
41634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /* shift == insignificant bits */
41644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        shift = (png_byte)((16U - sig_bit) & 0xff);
41654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     else
41674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        shift = 0; /* keep all 16 bits */
41684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
41704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     {
41714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
41724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * the significant bits in the *input* when the output will
41734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * eventually be 8 bits.  By default it is 11.
41744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         */
41754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (shift < (16U - PNG_MAX_GAMMA_8))
41764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann           shift = (16U - PNG_MAX_GAMMA_8);
41774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     }
41784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     if (shift > 8U)
41804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        shift = 8U; /* Guarantees at least one table! */
41814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     png_ptr->gamma_shift = shift;
41834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
41854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * PNG_COMPOSE).  This effectively smashed the background calculation for
41864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * 16-bit output because the 8-bit table assumes the result will be reduced
41874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      * to 8 bits.
41884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      */
41894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
41904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
41914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
41924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->screen_gamma) : PNG_FP_1);
41934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     else
41954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
41964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
41974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_ptr->screen_gamma) : PNG_FP_1);
41984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
41994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
42004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
42014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
42024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
42034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     {
42044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
42054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_reciprocal(png_ptr->colorspace.gamma));
42064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        /* Notice that the '16 from 1' table should be full precision, however
42084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * the lookup on this table still uses gamma_shift, so it can't be.
42094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         * TODO: fix this.
42104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         */
42114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
42124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
42134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
42144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann     }
42154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
42164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
42174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */
42184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
42194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA */
42204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* HARDWARE OR SOFTWARE OPTION SUPPORT */
42224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_OPTION_SUPPORTED
42234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI
42244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_option(png_structrp png_ptr, int option, int onoff)
42254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
42264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
42274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (option & 1) == 0)
42284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
42294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int mask = 3 << option;
42304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int setting = (2 + (onoff != 0)) << option;
42314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int current = png_ptr->options;
42324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff);
42344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return (current & mask) >> option;
42364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
42374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return PNG_OPTION_INVALID;
42394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
42404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif
42414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* sRGB support */
42434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
42444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
42454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* sRGB conversion tables; these are machine generated with the code in
42464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
42474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
42484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
42494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
42504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The inverse (linear to sRGB) table has accuracies as follows:
42514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
42524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For all possible (255*65535+1) input values:
42534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
42544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *    error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
42554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
42564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For the input values corresponding to the 65536 16-bit values:
42574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
42584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *    error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
42594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
42604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * In all cases the inexact readings are only off by one.
42614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
42624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
42634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
42644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The convert-to-sRGB table is only currently required for read. */
42654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst png_uint_16 png_sRGB_table[256] =
42664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
42674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   0,20,40,60,80,99,119,139,
42684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   159,179,199,219,241,264,288,313,
42694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   340,367,396,427,458,491,526,562,
42704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   599,637,677,718,761,805,851,898,
42714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   947,997,1048,1101,1156,1212,1270,1330,
42724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1391,1453,1517,1583,1651,1720,1790,1863,
42734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   1937,2013,2090,2170,2250,2333,2418,2504,
42744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   2592,2681,2773,2866,2961,3058,3157,3258,
42754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   3360,3464,3570,3678,3788,3900,4014,4129,
42764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   4247,4366,4488,4611,4736,4864,4993,5124,
42774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   5257,5392,5530,5669,5810,5953,6099,6246,
42784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   6395,6547,6700,6856,7014,7174,7335,7500,
42794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   7666,7834,8004,8177,8352,8528,8708,8889,
42804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   9072,9258,9445,9635,9828,10022,10219,10417,
42814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   10619,10822,11028,11235,11446,11658,11873,12090,
42824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   12309,12530,12754,12980,13209,13440,13673,13909,
42834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   14146,14387,14629,14874,15122,15371,15623,15878,
42844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   16135,16394,16656,16920,17187,17456,17727,18001,
42854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   18277,18556,18837,19121,19407,19696,19987,20281,
42864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   20577,20876,21177,21481,21787,22096,22407,22721,
42874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   23038,23357,23678,24002,24329,24658,24990,25325,
42884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   25662,26001,26344,26688,27036,27386,27739,28094,
42894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   28452,28813,29176,29542,29911,30282,30656,31033,
42904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   31412,31794,32179,32567,32957,33350,33745,34143,
42914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   34544,34948,35355,35764,36176,36591,37008,37429,
42924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   37852,38278,38706,39138,39572,40009,40449,40891,
42934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   41337,41785,42236,42690,43147,43606,44069,44534,
42944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   45002,45473,45947,46423,46903,47385,47871,48359,
42954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   48850,49344,49841,50341,50844,51349,51858,52369,
42964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   52884,53401,53921,54445,54971,55500,56032,56567,
42974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   57105,57646,58190,58737,59287,59840,60396,60955,
42984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   61517,62082,62650,63221,63795,64372,64952,65535
42994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
43004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SIMPLIFIED_READ */
43014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The base/delta tables are required for both read and write (but currently
43034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * only the simplified versions.)
43044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
43054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst png_uint_16 png_sRGB_base[512] =
43064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
43074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   128,1782,3383,4644,5675,6564,7357,8074,
43084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   8732,9346,9921,10463,10977,11466,11935,12384,
43094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   12816,13233,13634,14024,14402,14769,15125,15473,
43104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   15812,16142,16466,16781,17090,17393,17690,17981,
43114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   18266,18546,18822,19093,19359,19621,19879,20133,
43124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   20383,20630,20873,21113,21349,21583,21813,22041,
43134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   22265,22487,22707,22923,23138,23350,23559,23767,
43144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   23972,24175,24376,24575,24772,24967,25160,25352,
43154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   25542,25730,25916,26101,26284,26465,26645,26823,
43164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   27000,27176,27350,27523,27695,27865,28034,28201,
43174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   28368,28533,28697,28860,29021,29182,29341,29500,
43184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   29657,29813,29969,30123,30276,30429,30580,30730,
43194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   30880,31028,31176,31323,31469,31614,31758,31902,
43204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   32045,32186,32327,32468,32607,32746,32884,33021,
43214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   33158,33294,33429,33564,33697,33831,33963,34095,
43224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   34226,34357,34486,34616,34744,34873,35000,35127,
43234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   35253,35379,35504,35629,35753,35876,35999,36122,
43244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   36244,36365,36486,36606,36726,36845,36964,37083,
43254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   37201,37318,37435,37551,37668,37783,37898,38013,
43264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   38127,38241,38354,38467,38580,38692,38803,38915,
43274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   39026,39136,39246,39356,39465,39574,39682,39790,
43284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   39898,40005,40112,40219,40325,40431,40537,40642,
43294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   40747,40851,40955,41059,41163,41266,41369,41471,
43304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   41573,41675,41777,41878,41979,42079,42179,42279,
43314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   42379,42478,42577,42676,42775,42873,42971,43068,
43324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   43165,43262,43359,43456,43552,43648,43743,43839,
43334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   43934,44028,44123,44217,44311,44405,44499,44592,
43344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   44685,44778,44870,44962,45054,45146,45238,45329,
43354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   45420,45511,45601,45692,45782,45872,45961,46051,
43364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   46140,46229,46318,46406,46494,46583,46670,46758,
43374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   46846,46933,47020,47107,47193,47280,47366,47452,
43384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   47538,47623,47709,47794,47879,47964,48048,48133,
43394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   48217,48301,48385,48468,48552,48635,48718,48801,
43404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   48884,48966,49048,49131,49213,49294,49376,49458,
43414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   49539,49620,49701,49782,49862,49943,50023,50103,
43424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   50183,50263,50342,50422,50501,50580,50659,50738,
43434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   50816,50895,50973,51051,51129,51207,51285,51362,
43444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   51439,51517,51594,51671,51747,51824,51900,51977,
43454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   52053,52129,52205,52280,52356,52432,52507,52582,
43464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   52657,52732,52807,52881,52956,53030,53104,53178,
43474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   53252,53326,53400,53473,53546,53620,53693,53766,
43484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   53839,53911,53984,54056,54129,54201,54273,54345,
43494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   54417,54489,54560,54632,54703,54774,54845,54916,
43504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   54987,55058,55129,55199,55269,55340,55410,55480,
43514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   55550,55620,55689,55759,55828,55898,55967,56036,
43524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   56105,56174,56243,56311,56380,56448,56517,56585,
43534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   56653,56721,56789,56857,56924,56992,57059,57127,
43544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   57194,57261,57328,57395,57462,57529,57595,57662,
43554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   57728,57795,57861,57927,57993,58059,58125,58191,
43564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   58256,58322,58387,58453,58518,58583,58648,58713,
43574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   58778,58843,58908,58972,59037,59101,59165,59230,
43584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   59294,59358,59422,59486,59549,59613,59677,59740,
43594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   59804,59867,59930,59993,60056,60119,60182,60245,
43604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   60308,60370,60433,60495,60558,60620,60682,60744,
43614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   60806,60868,60930,60992,61054,61115,61177,61238,
43624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   61300,61361,61422,61483,61544,61605,61666,61727,
43634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   61788,61848,61909,61969,62030,62090,62150,62211,
43644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   62271,62331,62391,62450,62510,62570,62630,62689,
43654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   62749,62808,62867,62927,62986,63045,63104,63163,
43664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   63222,63281,63340,63398,63457,63515,63574,63632,
43674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   63691,63749,63807,63865,63923,63981,64039,64097,
43684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   64155,64212,64270,64328,64385,64443,64500,64557,
43694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   64614,64672,64729,64786,64843,64900,64956,65013,
43704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   65070,65126,65183,65239,65296,65352,65409,65465
43714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
43724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
43734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst png_byte png_sRGB_delta[512] =
43744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
43754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
43764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
43774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
43784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
43794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
43804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
43814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
43824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
43834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
43844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
43854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
43864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
43874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
43884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
43894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
43904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
43914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
43924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
43934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
43944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
43954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
43964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
43974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
43984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
43994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
44004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
44014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
44024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
44034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
44044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
44054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
44064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
44074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
44084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SIMPLIFIED READ/WRITE sRGB support */
44094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* SIMPLIFIED READ/WRITE SUPPORT */
44114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
44124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
44134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int
44144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_free_function(png_voidp argument)
44154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
44164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_imagep image = png_voidcast(png_imagep, argument);
44174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_controlp cp = image->opaque;
44184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_control c;
44194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Double check that we have a png_ptr - it should be impossible to get here
44214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * without one.
44224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
44234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (cp->png_ptr == NULL)
44244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      return 0;
44254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* First free any data held in the control structure. */
44274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  ifdef PNG_STDIO_SUPPORTED
44284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (cp->owned_file != 0)
44294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      {
44304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
44314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         cp->owned_file = 0;
44324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         /* Ignore errors here. */
44344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         if (fp != NULL)
44354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         {
44364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            cp->png_ptr->io_ptr = NULL;
44374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            (void)fclose(fp);
44384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         }
44394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
44404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#  endif
44414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Copy the control structure so that the original, allocated, version can be
44434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * safely freed.  Notice that a png_error here stops the remainder of the
44444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * cleanup, but this is probably fine because that would indicate bad memory
44454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * problems anyway.
44464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
44474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   c = *cp;
44484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   image->opaque = &c;
44494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_free(c.png_ptr, cp);
44504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Then the structures, calling the correct API. */
44524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (c.for_write != 0)
44534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
44544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
44554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
44564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     else
44574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(c.png_ptr, "simplified write not supported");
44584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
44594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
44604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   else
44614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
44624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     ifdef PNG_SIMPLIFIED_READ_SUPPORTED
44634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
44644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     else
44654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann         png_error(c.png_ptr, "simplified read not supported");
44664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#     endif
44674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
44684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Success. */
44704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 1;
44714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
44724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI
44744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_free(png_imagep image)
44754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
44764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Safely call the real function, but only if doing so is safe at this point
44774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * (if not inside an error handling context).  Otherwise assume
44784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    * png_safe_execute will call this API after the return.
44794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    */
44804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   if (image != NULL && image->opaque != NULL &&
44814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      image->opaque->error_buf == NULL)
44824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   {
44834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      /* Ignore errors here: */
44844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      (void)png_safe_execute(image, png_image_free_function, image);
44854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      image->opaque = NULL;
44864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   }
44874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
44884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */
44904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_error(png_imagep image, png_const_charp error_message)
44914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{
44924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   /* Utility to log an error. */
44934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_safecat(image->message, (sizeof image->message), 0, error_message);
44944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   image->warning_or_error |= PNG_IMAGE_ERROR;
44954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   png_image_free(image);
44964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann   return 0;
44974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
44984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
44994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SIMPLIFIED READ/WRITE */
45004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ || WRITE */
4501