PageRenderTime 111ms CodeModel.GetById 19ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 1ms

/src/FreeImage/Source/LibPNG/pngrutil.c

https://bitbucket.org/cabalistic/ogredeps/
C | 4158 lines | 2951 code | 708 blank | 499 comment | 671 complexity | cc8c2e9fc3841b17fc2925daebc2cb4f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1
   2/* pngrutil.c - utilities to read a PNG file
   3 *
   4 * Last changed in libpng 1.5.9 [February 18, 2012]
   5 * Copyright (c) 1998-2012 Glenn Randers-Pehrson
   6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
   7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
   8 *
   9 * This code is released under the libpng license.
  10 * For conditions of distribution and use, see the disclaimer
  11 * and license in png.h
  12 *
  13 * This file contains routines that are only called from within
  14 * libpng itself during the course of reading an image.
  15 */
  16
  17#include "pngpriv.h"
  18
  19#ifdef PNG_READ_SUPPORTED
  20
  21#define png_strtod(p,a,b) strtod(a,b)
  22
  23png_uint_32 PNGAPI
  24png_get_uint_31(png_structp png_ptr, png_const_bytep buf)
  25{
  26   png_uint_32 uval = png_get_uint_32(buf);
  27
  28   if (uval > PNG_UINT_31_MAX)
  29      png_error(png_ptr, "PNG unsigned integer out of range");
  30
  31   return (uval);
  32}
  33
  34#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
  35/* The following is a variation on the above for use with the fixed
  36 * point values used for gAMA and cHRM.  Instead of png_error it
  37 * issues a warning and returns (-1) - an invalid value because both
  38 * gAMA and cHRM use *unsigned* integers for fixed point values.
  39 */
  40#define PNG_FIXED_ERROR (-1)
  41
  42static png_fixed_point /* PRIVATE */
  43png_get_fixed_point(png_structp png_ptr, png_const_bytep buf)
  44{
  45   png_uint_32 uval = png_get_uint_32(buf);
  46
  47   if (uval <= PNG_UINT_31_MAX)
  48      return (png_fixed_point)uval; /* known to be in range */
  49
  50   /* The caller can turn off the warning by passing NULL. */
  51   if (png_ptr != NULL)
  52      png_warning(png_ptr, "PNG fixed point integer out of range");
  53
  54   return PNG_FIXED_ERROR;
  55}
  56#endif
  57
  58#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
  59/* NOTE: the read macros will obscure these definitions, so that if
  60 * PNG_USE_READ_MACROS is set the library will not use them internally,
  61 * but the APIs will still be available externally.
  62 *
  63 * The parentheses around "PNGAPI function_name" in the following three
  64 * functions are necessary because they allow the macros to co-exist with
  65 * these (unused but exported) functions.
  66 */
  67
  68/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
  69png_uint_32 (PNGAPI
  70png_get_uint_32)(png_const_bytep buf)
  71{
  72   png_uint_32 uval =
  73       ((png_uint_32)(*(buf    )) << 24) +
  74       ((png_uint_32)(*(buf + 1)) << 16) +
  75       ((png_uint_32)(*(buf + 2)) <<  8) +
  76       ((png_uint_32)(*(buf + 3))      ) ;
  77
  78   return uval;
  79}
  80
  81/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
  82 * data is stored in the PNG file in two's complement format and there
  83 * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
  84 * the following code does a two's complement to native conversion.
  85 */
  86png_int_32 (PNGAPI
  87png_get_int_32)(png_const_bytep buf)
  88{
  89   png_uint_32 uval = png_get_uint_32(buf);
  90   if ((uval & 0x80000000) == 0) /* non-negative */
  91      return uval;
  92
  93   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
  94   return -(png_int_32)uval;
  95}
  96
  97/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
  98png_uint_16 (PNGAPI
  99png_get_uint_16)(png_const_bytep buf)
 100{
 101   /* ANSI-C requires an int value to accomodate at least 16 bits so this
 102    * works and allows the compiler not to worry about possible narrowing
 103    * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
 104    * than 16 bits either.)
 105    */
 106   unsigned int val =
 107       ((unsigned int)(*buf) << 8) +
 108       ((unsigned int)(*(buf + 1)));
 109
 110   return (png_uint_16)val;
 111}
 112
 113#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
 114
 115/* Read and check the PNG file signature */
 116void /* PRIVATE */
 117png_read_sig(png_structp png_ptr, png_infop info_ptr)
 118{
 119   png_size_t num_checked, num_to_check;
 120
 121   /* Exit if the user application does not expect a signature. */
 122   if (png_ptr->sig_bytes >= 8)
 123      return;
 124
 125   num_checked = png_ptr->sig_bytes;
 126   num_to_check = 8 - num_checked;
 127
 128#ifdef PNG_IO_STATE_SUPPORTED
 129   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
 130#endif
 131
 132   /* The signature must be serialized in a single I/O call. */
 133   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
 134   png_ptr->sig_bytes = 8;
 135
 136   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
 137   {
 138      if (num_checked < 4 &&
 139          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
 140         png_error(png_ptr, "Not a PNG file");
 141      else
 142         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
 143   }
 144   if (num_checked < 3)
 145      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
 146}
 147
 148/* Read the chunk header (length + type name).
 149 * Put the type name into png_ptr->chunk_name, and return the length.
 150 */
 151png_uint_32 /* PRIVATE */
 152png_read_chunk_header(png_structp png_ptr)
 153{
 154   png_byte buf[8];
 155   png_uint_32 length;
 156
 157#ifdef PNG_IO_STATE_SUPPORTED
 158   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
 159#endif
 160
 161   /* Read the length and the chunk name.
 162    * This must be performed in a single I/O call.
 163    */
 164   png_read_data(png_ptr, buf, 8);
 165   length = png_get_uint_31(png_ptr, buf);
 166
 167   /* Put the chunk name into png_ptr->chunk_name. */
 168   png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
 169
 170   png_debug2(0, "Reading %lx chunk, length = %lu",
 171       (unsigned long)png_ptr->chunk_name, (unsigned long)length);
 172
 173   /* Reset the crc and run it over the chunk name. */
 174   png_reset_crc(png_ptr);
 175   png_calculate_crc(png_ptr, buf + 4, 4);
 176
 177   /* Check to see if chunk name is valid. */
 178   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 179
 180#ifdef PNG_IO_STATE_SUPPORTED
 181   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
 182#endif
 183
 184   return length;
 185}
 186
 187/* Read data, and (optionally) run it through the CRC. */
 188void /* PRIVATE */
 189png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
 190{
 191   if (png_ptr == NULL)
 192      return;
 193
 194   png_read_data(png_ptr, buf, length);
 195   png_calculate_crc(png_ptr, buf, length);
 196}
 197
 198/* Optionally skip data and then check the CRC.  Depending on whether we
 199 * are reading a ancillary or critical chunk, and how the program has set
 200 * things up, we may calculate the CRC on the data and print a message.
 201 * Returns '1' if there was a CRC error, '0' otherwise.
 202 */
 203int /* PRIVATE */
 204png_crc_finish(png_structp png_ptr, png_uint_32 skip)
 205{
 206   png_size_t i;
 207   png_size_t istop = png_ptr->zbuf_size;
 208
 209   for (i = (png_size_t)skip; i > istop; i -= istop)
 210   {
 211      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
 212   }
 213
 214   if (i)
 215   {
 216      png_crc_read(png_ptr, png_ptr->zbuf, i);
 217   }
 218
 219   if (png_crc_error(png_ptr))
 220   {
 221      if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ?
 222          !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
 223          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
 224      {
 225         png_chunk_warning(png_ptr, "CRC error");
 226      }
 227
 228      else
 229      {
 230         png_chunk_benign_error(png_ptr, "CRC error");
 231         return (0);
 232      }
 233
 234      return (1);
 235   }
 236
 237   return (0);
 238}
 239
 240/* Compare the CRC stored in the PNG file with that calculated by libpng from
 241 * the data it has read thus far.
 242 */
 243int /* PRIVATE */
 244png_crc_error(png_structp png_ptr)
 245{
 246   png_byte crc_bytes[4];
 247   png_uint_32 crc;
 248   int need_crc = 1;
 249
 250   if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
 251   {
 252      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
 253          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
 254         need_crc = 0;
 255   }
 256
 257   else /* critical */
 258   {
 259      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
 260         need_crc = 0;
 261   }
 262
 263#ifdef PNG_IO_STATE_SUPPORTED
 264   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
 265#endif
 266
 267   /* The chunk CRC must be serialized in a single I/O call. */
 268   png_read_data(png_ptr, crc_bytes, 4);
 269
 270   if (need_crc)
 271   {
 272      crc = png_get_uint_32(crc_bytes);
 273      return ((int)(crc != png_ptr->crc));
 274   }
 275
 276   else
 277      return (0);
 278}
 279
 280#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
 281static png_size_t
 282png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
 283    png_bytep output, png_size_t output_size)
 284{
 285   png_size_t count = 0;
 286
 287   /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
 288    * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
 289    * more".  Consequently it is necessary to chunk the input to zlib.  This
 290    * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
 291    * that can be stored in a uInt.)  It is possible to set ZLIB_IO_MAX to a
 292    * lower value in pngpriv.h and this may sometimes have a performance
 293    * advantage, because it forces access of the input data to be separated from
 294    * at least some of the use by some period of time.
 295    */
 296   png_ptr->zstream.next_in = data;
 297   /* avail_in is set below from 'size' */
 298   png_ptr->zstream.avail_in = 0;
 299
 300   while (1)
 301   {
 302      int ret, avail;
 303
 304      /* The setting of 'avail_in' used to be outside the loop; by setting it
 305       * inside it is possible to chunk the input to zlib and simply rely on
 306       * zlib to advance the 'next_in' pointer.  This allows arbitrary amounts o
 307       * data to be passed through zlib at the unavoidable cost of requiring a
 308       * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
 309       * input bytes.
 310       */
 311      if (png_ptr->zstream.avail_in == 0 && size > 0)
 312      {
 313         if (size <= ZLIB_IO_MAX)
 314         {
 315            /* The value is less than ZLIB_IO_MAX so the cast is safe: */
 316            png_ptr->zstream.avail_in = (uInt)size;
 317            size = 0;
 318         }
 319
 320         else
 321         {
 322            png_ptr->zstream.avail_in = ZLIB_IO_MAX;
 323            size -= ZLIB_IO_MAX;
 324         }
 325      }
 326
 327      /* Reset the output buffer each time round - we empty it
 328       * after every inflate call.
 329       */
 330      png_ptr->zstream.next_out = png_ptr->zbuf;
 331      png_ptr->zstream.avail_out = png_ptr->zbuf_size;
 332
 333      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
 334      avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
 335
 336      /* First copy/count any new output - but only if we didn't
 337       * get an error code.
 338       */
 339      if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
 340      {
 341         png_size_t space = avail; /* > 0, see above */
 342
 343         if (output != 0 && output_size > count)
 344         {
 345            png_size_t copy = output_size - count;
 346
 347            if (space < copy)
 348               copy = space;
 349
 350            png_memcpy(output + count, png_ptr->zbuf, copy);
 351         }
 352         count += space;
 353      }
 354
 355      if (ret == Z_OK)
 356         continue;
 357
 358      /* Termination conditions - always reset the zstream, it
 359       * must be left in inflateInit state.
 360       */
 361      png_ptr->zstream.avail_in = 0;
 362      inflateReset(&png_ptr->zstream);
 363
 364      if (ret == Z_STREAM_END)
 365         return count; /* NOTE: may be zero. */
 366
 367      /* Now handle the error codes - the API always returns 0
 368       * and the error message is dumped into the uncompressed
 369       * buffer if available.
 370       */
 371#     ifdef PNG_WARNINGS_SUPPORTED
 372      {
 373         png_const_charp msg;
 374
 375         if (png_ptr->zstream.msg != 0)
 376            msg = png_ptr->zstream.msg;
 377
 378         else switch (ret)
 379         {
 380            case Z_BUF_ERROR:
 381               msg = "Buffer error in compressed datastream";
 382               break;
 383
 384            case Z_DATA_ERROR:
 385               msg = "Data error in compressed datastream";
 386               break;
 387
 388            default:
 389               msg = "Incomplete compressed datastream";
 390               break;
 391         }
 392
 393         png_chunk_warning(png_ptr, msg);
 394      }
 395#     endif
 396
 397      /* 0 means an error - notice that this code simply ignores
 398       * zero length compressed chunks as a result.
 399       */
 400      return 0;
 401   }
 402}
 403
 404/*
 405 * Decompress trailing data in a chunk.  The assumption is that chunkdata
 406 * points at an allocated area holding the contents of a chunk with a
 407 * trailing compressed part.  What we get back is an allocated area
 408 * holding the original prefix part and an uncompressed version of the
 409 * trailing part (the malloc area passed in is freed).
 410 */
 411void /* PRIVATE */
 412png_decompress_chunk(png_structp png_ptr, int comp_type,
 413    png_size_t chunklength,
 414    png_size_t prefix_size, png_size_t *newlength)
 415{
 416   /* The caller should guarantee this */
 417   if (prefix_size > chunklength)
 418   {
 419      /* The recovery is to delete the chunk. */
 420      png_warning(png_ptr, "invalid chunklength");
 421      prefix_size = 0; /* To delete everything */
 422   }
 423
 424   else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
 425   {
 426      png_size_t expanded_size = png_inflate(png_ptr,
 427          (png_bytep)(png_ptr->chunkdata + prefix_size),
 428          chunklength - prefix_size,
 429          0,            /* output */
 430          0);           /* output size */
 431
 432      /* Now check the limits on this chunk - if the limit fails the
 433       * compressed data will be removed, the prefix will remain.
 434       */
 435      if (prefix_size >= (~(png_size_t)0) - 1 ||
 436         expanded_size >= (~(png_size_t)0) - 1 - prefix_size
 437#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
 438         || (png_ptr->user_chunk_malloc_max &&
 439          (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
 440#else
 441#  ifdef PNG_USER_CHUNK_MALLOC_MAX
 442         || ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
 443          prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
 444#  endif
 445#endif
 446         )
 447         png_warning(png_ptr, "Exceeded size limit while expanding chunk");
 448
 449      /* If the size is zero either there was an error and a message
 450       * has already been output (warning) or the size really is zero
 451       * and we have nothing to do - the code will exit through the
 452       * error case below.
 453       */
 454      else if (expanded_size > 0)
 455      {
 456         /* Success (maybe) - really uncompress the chunk. */
 457         png_size_t new_size = 0;
 458         png_charp text = (png_charp)png_malloc_warn(png_ptr,
 459             prefix_size + expanded_size + 1);
 460
 461         if (text != NULL)
 462         {
 463            png_memcpy(text, png_ptr->chunkdata, prefix_size);
 464            new_size = png_inflate(png_ptr,
 465                (png_bytep)(png_ptr->chunkdata + prefix_size),
 466                chunklength - prefix_size,
 467                (png_bytep)(text + prefix_size), expanded_size);
 468            text[prefix_size + expanded_size] = 0; /* just in case */
 469
 470            if (new_size == expanded_size)
 471            {
 472               png_free(png_ptr, png_ptr->chunkdata);
 473               png_ptr->chunkdata = text;
 474               *newlength = prefix_size + expanded_size;
 475               return; /* The success return! */
 476            }
 477
 478            png_warning(png_ptr, "png_inflate logic error");
 479            png_free(png_ptr, text);
 480         }
 481
 482         else
 483            png_warning(png_ptr, "Not enough memory to decompress chunk");
 484      }
 485   }
 486
 487   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
 488   {
 489      PNG_WARNING_PARAMETERS(p)
 490      png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type);
 491      png_formatted_warning(png_ptr, p, "Unknown compression type @1");
 492
 493      /* The recovery is to simply drop the data. */
 494   }
 495
 496   /* Generic error return - leave the prefix, delete the compressed
 497    * data, reallocate the chunkdata to remove the potentially large
 498    * amount of compressed data.
 499    */
 500   {
 501      png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1);
 502
 503      if (text != NULL)
 504      {
 505         if (prefix_size > 0)
 506            png_memcpy(text, png_ptr->chunkdata, prefix_size);
 507
 508         png_free(png_ptr, png_ptr->chunkdata);
 509         png_ptr->chunkdata = text;
 510
 511         /* This is an extra zero in the 'uncompressed' part. */
 512         *(png_ptr->chunkdata + prefix_size) = 0x00;
 513      }
 514      /* Ignore a malloc error here - it is safe. */
 515   }
 516
 517   *newlength = prefix_size;
 518}
 519#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
 520
 521/* Read and check the IDHR chunk */
 522void /* PRIVATE */
 523png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 524{
 525   png_byte buf[13];
 526   png_uint_32 width, height;
 527   int bit_depth, color_type, compression_type, filter_type;
 528   int interlace_type;
 529
 530   png_debug(1, "in png_handle_IHDR");
 531
 532   if (png_ptr->mode & PNG_HAVE_IHDR)
 533      png_error(png_ptr, "Out of place IHDR");
 534
 535   /* Check the length */
 536   if (length != 13)
 537      png_error(png_ptr, "Invalid IHDR chunk");
 538
 539   png_ptr->mode |= PNG_HAVE_IHDR;
 540
 541   png_crc_read(png_ptr, buf, 13);
 542   png_crc_finish(png_ptr, 0);
 543
 544   width = png_get_uint_31(png_ptr, buf);
 545   height = png_get_uint_31(png_ptr, buf + 4);
 546   bit_depth = buf[8];
 547   color_type = buf[9];
 548   compression_type = buf[10];
 549   filter_type = buf[11];
 550   interlace_type = buf[12];
 551
 552   /* Set internal variables */
 553   png_ptr->width = width;
 554   png_ptr->height = height;
 555   png_ptr->bit_depth = (png_byte)bit_depth;
 556   png_ptr->interlaced = (png_byte)interlace_type;
 557   png_ptr->color_type = (png_byte)color_type;
 558#ifdef PNG_MNG_FEATURES_SUPPORTED
 559   png_ptr->filter_type = (png_byte)filter_type;
 560#endif
 561   png_ptr->compression_type = (png_byte)compression_type;
 562
 563   /* Find number of channels */
 564   switch (png_ptr->color_type)
 565   {
 566      default: /* invalid, png_set_IHDR calls png_error */
 567      case PNG_COLOR_TYPE_GRAY:
 568      case PNG_COLOR_TYPE_PALETTE:
 569         png_ptr->channels = 1;
 570         break;
 571
 572      case PNG_COLOR_TYPE_RGB:
 573         png_ptr->channels = 3;
 574         break;
 575
 576      case PNG_COLOR_TYPE_GRAY_ALPHA:
 577         png_ptr->channels = 2;
 578         break;
 579
 580      case PNG_COLOR_TYPE_RGB_ALPHA:
 581         png_ptr->channels = 4;
 582         break;
 583   }
 584
 585   /* Set up other useful info */
 586   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
 587   png_ptr->channels);
 588   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
 589   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
 590   png_debug1(3, "channels = %d", png_ptr->channels);
 591   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
 592   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
 593       color_type, interlace_type, compression_type, filter_type);
 594}
 595
 596/* Read and check the palette */
 597void /* PRIVATE */
 598png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 599{
 600   png_color palette[PNG_MAX_PALETTE_LENGTH];
 601   int num, i;
 602#ifdef PNG_POINTER_INDEXING_SUPPORTED
 603   png_colorp pal_ptr;
 604#endif
 605
 606   png_debug(1, "in png_handle_PLTE");
 607
 608   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 609      png_error(png_ptr, "Missing IHDR before PLTE");
 610
 611   else if (png_ptr->mode & PNG_HAVE_IDAT)
 612   {
 613      png_warning(png_ptr, "Invalid PLTE after IDAT");
 614      png_crc_finish(png_ptr, length);
 615      return;
 616   }
 617
 618   else if (png_ptr->mode & PNG_HAVE_PLTE)
 619      png_error(png_ptr, "Duplicate PLTE chunk");
 620
 621   png_ptr->mode |= PNG_HAVE_PLTE;
 622
 623   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
 624   {
 625      png_warning(png_ptr,
 626          "Ignoring PLTE chunk in grayscale PNG");
 627      png_crc_finish(png_ptr, length);
 628      return;
 629   }
 630
 631#ifndef PNG_READ_OPT_PLTE_SUPPORTED
 632   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
 633   {
 634      png_crc_finish(png_ptr, length);
 635      return;
 636   }
 637#endif
 638
 639   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
 640   {
 641      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
 642      {
 643         png_warning(png_ptr, "Invalid palette chunk");
 644         png_crc_finish(png_ptr, length);
 645         return;
 646      }
 647
 648      else
 649      {
 650         png_error(png_ptr, "Invalid palette chunk");
 651      }
 652   }
 653
 654   num = (int)length / 3;
 655
 656#ifdef PNG_POINTER_INDEXING_SUPPORTED
 657   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
 658   {
 659      png_byte buf[3];
 660
 661      png_crc_read(png_ptr, buf, 3);
 662      pal_ptr->red = buf[0];
 663      pal_ptr->green = buf[1];
 664      pal_ptr->blue = buf[2];
 665   }
 666#else
 667   for (i = 0; i < num; i++)
 668   {
 669      png_byte buf[3];
 670
 671      png_crc_read(png_ptr, buf, 3);
 672      /* Don't depend upon png_color being any order */
 673      palette[i].red = buf[0];
 674      palette[i].green = buf[1];
 675      palette[i].blue = buf[2];
 676   }
 677#endif
 678
 679   /* If we actually need the PLTE chunk (ie for a paletted image), we do
 680    * whatever the normal CRC configuration tells us.  However, if we
 681    * have an RGB image, the PLTE can be considered ancillary, so
 682    * we will act as though it is.
 683    */
 684#ifndef PNG_READ_OPT_PLTE_SUPPORTED
 685   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 686#endif
 687   {
 688      png_crc_finish(png_ptr, 0);
 689   }
 690
 691#ifndef PNG_READ_OPT_PLTE_SUPPORTED
 692   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
 693   {
 694      /* If we don't want to use the data from an ancillary chunk,
 695       * we have two options: an error abort, or a warning and we
 696       * ignore the data in this chunk (which should be OK, since
 697       * it's considered ancillary for a RGB or RGBA image).
 698       */
 699      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
 700      {
 701         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
 702         {
 703            png_chunk_benign_error(png_ptr, "CRC error");
 704         }
 705
 706         else
 707         {
 708            png_chunk_warning(png_ptr, "CRC error");
 709            return;
 710         }
 711      }
 712
 713      /* Otherwise, we (optionally) emit a warning and use the chunk. */
 714      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
 715      {
 716         png_chunk_warning(png_ptr, "CRC error");
 717      }
 718   }
 719#endif
 720
 721   png_set_PLTE(png_ptr, info_ptr, palette, num);
 722
 723#ifdef PNG_READ_tRNS_SUPPORTED
 724   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 725   {
 726      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
 727      {
 728         if (png_ptr->num_trans > (png_uint_16)num)
 729         {
 730            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
 731            png_ptr->num_trans = (png_uint_16)num;
 732         }
 733
 734         if (info_ptr->num_trans > (png_uint_16)num)
 735         {
 736            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
 737            info_ptr->num_trans = (png_uint_16)num;
 738         }
 739      }
 740   }
 741#endif
 742
 743}
 744
 745void /* PRIVATE */
 746png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 747{
 748   png_debug(1, "in png_handle_IEND");
 749
 750   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
 751   {
 752      png_error(png_ptr, "No image in file");
 753   }
 754
 755   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
 756
 757   if (length != 0)
 758   {
 759      png_warning(png_ptr, "Incorrect IEND chunk length");
 760   }
 761
 762   png_crc_finish(png_ptr, length);
 763
 764   PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
 765}
 766
 767#ifdef PNG_READ_gAMA_SUPPORTED
 768void /* PRIVATE */
 769png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 770{
 771   png_fixed_point igamma;
 772   png_byte buf[4];
 773
 774   png_debug(1, "in png_handle_gAMA");
 775
 776   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 777      png_error(png_ptr, "Missing IHDR before gAMA");
 778
 779   else if (png_ptr->mode & PNG_HAVE_IDAT)
 780   {
 781      png_warning(png_ptr, "Invalid gAMA after IDAT");
 782      png_crc_finish(png_ptr, length);
 783      return;
 784   }
 785
 786   else if (png_ptr->mode & PNG_HAVE_PLTE)
 787      /* Should be an error, but we can cope with it */
 788      png_warning(png_ptr, "Out of place gAMA chunk");
 789
 790   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
 791#ifdef PNG_READ_sRGB_SUPPORTED
 792       && !(info_ptr->valid & PNG_INFO_sRGB)
 793#endif
 794       )
 795   {
 796      png_warning(png_ptr, "Duplicate gAMA chunk");
 797      png_crc_finish(png_ptr, length);
 798      return;
 799   }
 800
 801   if (length != 4)
 802   {
 803      png_warning(png_ptr, "Incorrect gAMA chunk length");
 804      png_crc_finish(png_ptr, length);
 805      return;
 806   }
 807
 808   png_crc_read(png_ptr, buf, 4);
 809
 810   if (png_crc_finish(png_ptr, 0))
 811      return;
 812
 813   igamma = png_get_fixed_point(NULL, buf);
 814
 815   /* Check for zero gamma or an error. */
 816   if (igamma <= 0)
 817   {
 818      png_warning(png_ptr,
 819          "Ignoring gAMA chunk with out of range gamma");
 820
 821      return;
 822   }
 823
 824#  ifdef PNG_READ_sRGB_SUPPORTED
 825   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
 826   {
 827      if (PNG_OUT_OF_RANGE(igamma, 45500, 500))
 828      {
 829         PNG_WARNING_PARAMETERS(p)
 830         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
 831         png_formatted_warning(png_ptr, p,
 832             "Ignoring incorrect gAMA value @1 when sRGB is also present");
 833         return;
 834      }
 835   }
 836#  endif /* PNG_READ_sRGB_SUPPORTED */
 837
 838#  ifdef PNG_READ_GAMMA_SUPPORTED
 839   /* Gamma correction on read is supported. */
 840   png_ptr->gamma = igamma;
 841#  endif
 842   /* And set the 'info' structure members. */
 843   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
 844}
 845#endif
 846
 847#ifdef PNG_READ_sBIT_SUPPORTED
 848void /* PRIVATE */
 849png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 850{
 851   png_size_t truelen;
 852   png_byte buf[4];
 853
 854   png_debug(1, "in png_handle_sBIT");
 855
 856   buf[0] = buf[1] = buf[2] = buf[3] = 0;
 857
 858   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 859      png_error(png_ptr, "Missing IHDR before sBIT");
 860
 861   else if (png_ptr->mode & PNG_HAVE_IDAT)
 862   {
 863      png_warning(png_ptr, "Invalid sBIT after IDAT");
 864      png_crc_finish(png_ptr, length);
 865      return;
 866   }
 867
 868   else if (png_ptr->mode & PNG_HAVE_PLTE)
 869   {
 870      /* Should be an error, but we can cope with it */
 871      png_warning(png_ptr, "Out of place sBIT chunk");
 872   }
 873
 874   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
 875   {
 876      png_warning(png_ptr, "Duplicate sBIT chunk");
 877      png_crc_finish(png_ptr, length);
 878      return;
 879   }
 880
 881   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 882      truelen = 3;
 883
 884   else
 885      truelen = (png_size_t)png_ptr->channels;
 886
 887   if (length != truelen || length > 4)
 888   {
 889      png_warning(png_ptr, "Incorrect sBIT chunk length");
 890      png_crc_finish(png_ptr, length);
 891      return;
 892   }
 893
 894   png_crc_read(png_ptr, buf, truelen);
 895
 896   if (png_crc_finish(png_ptr, 0))
 897      return;
 898
 899   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
 900   {
 901      png_ptr->sig_bit.red = buf[0];
 902      png_ptr->sig_bit.green = buf[1];
 903      png_ptr->sig_bit.blue = buf[2];
 904      png_ptr->sig_bit.alpha = buf[3];
 905   }
 906
 907   else
 908   {
 909      png_ptr->sig_bit.gray = buf[0];
 910      png_ptr->sig_bit.red = buf[0];
 911      png_ptr->sig_bit.green = buf[0];
 912      png_ptr->sig_bit.blue = buf[0];
 913      png_ptr->sig_bit.alpha = buf[1];
 914   }
 915
 916   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
 917}
 918#endif
 919
 920#ifdef PNG_READ_cHRM_SUPPORTED
 921void /* PRIVATE */
 922png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 923{
 924   png_byte buf[32];
 925   png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue,
 926      y_blue;
 927
 928   png_debug(1, "in png_handle_cHRM");
 929
 930   if (!(png_ptr->mode & PNG_HAVE_IHDR))
 931      png_error(png_ptr, "Missing IHDR before cHRM");
 932
 933   else if (png_ptr->mode & PNG_HAVE_IDAT)
 934   {
 935      png_warning(png_ptr, "Invalid cHRM after IDAT");
 936      png_crc_finish(png_ptr, length);
 937      return;
 938   }
 939
 940   else if (png_ptr->mode & PNG_HAVE_PLTE)
 941      /* Should be an error, but we can cope with it */
 942      png_warning(png_ptr, "Out of place cHRM chunk");
 943
 944   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
 945#  ifdef PNG_READ_sRGB_SUPPORTED
 946       && !(info_ptr->valid & PNG_INFO_sRGB)
 947#  endif
 948      )
 949   {
 950      png_warning(png_ptr, "Duplicate cHRM chunk");
 951      png_crc_finish(png_ptr, length);
 952      return;
 953   }
 954
 955   if (length != 32)
 956   {
 957      png_warning(png_ptr, "Incorrect cHRM chunk length");
 958      png_crc_finish(png_ptr, length);
 959      return;
 960   }
 961
 962   png_crc_read(png_ptr, buf, 32);
 963
 964   if (png_crc_finish(png_ptr, 0))
 965      return;
 966
 967   x_white = png_get_fixed_point(NULL, buf);
 968   y_white = png_get_fixed_point(NULL, buf + 4);
 969   x_red   = png_get_fixed_point(NULL, buf + 8);
 970   y_red   = png_get_fixed_point(NULL, buf + 12);
 971   x_green = png_get_fixed_point(NULL, buf + 16);
 972   y_green = png_get_fixed_point(NULL, buf + 20);
 973   x_blue  = png_get_fixed_point(NULL, buf + 24);
 974   y_blue  = png_get_fixed_point(NULL, buf + 28);
 975
 976   if (x_white == PNG_FIXED_ERROR ||
 977       y_white == PNG_FIXED_ERROR ||
 978       x_red   == PNG_FIXED_ERROR ||
 979       y_red   == PNG_FIXED_ERROR ||
 980       x_green == PNG_FIXED_ERROR ||
 981       y_green == PNG_FIXED_ERROR ||
 982       x_blue  == PNG_FIXED_ERROR ||
 983       y_blue  == PNG_FIXED_ERROR)
 984   {
 985      png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities");
 986      return;
 987   }
 988
 989#ifdef PNG_READ_sRGB_SUPPORTED
 990   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
 991   {
 992      if (PNG_OUT_OF_RANGE(x_white, 31270,  1000) ||
 993          PNG_OUT_OF_RANGE(y_white, 32900,  1000) ||
 994          PNG_OUT_OF_RANGE(x_red,   64000,  1000) ||
 995          PNG_OUT_OF_RANGE(y_red,   33000,  1000) ||
 996          PNG_OUT_OF_RANGE(x_green, 30000,  1000) ||
 997          PNG_OUT_OF_RANGE(y_green, 60000,  1000) ||
 998          PNG_OUT_OF_RANGE(x_blue,  15000,  1000) ||
 999          PNG_OUT_OF_RANGE(y_blue,   6000,  1000))
1000      {
1001         PNG_WARNING_PARAMETERS(p)
1002
1003         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white);
1004         png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white);
1005         png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red);
1006         png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red);
1007         png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green);
1008         png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green);
1009         png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue);
1010         png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue);
1011
1012         png_formatted_warning(png_ptr, p,
1013             "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) "
1014             "when sRGB is also present");
1015      }
1016      return;
1017   }
1018#endif /* PNG_READ_sRGB_SUPPORTED */
1019
1020#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1021   /* Store the _white values as default coefficients for the rgb to gray
1022    * operation if it is supported.  Check if the transform is already set to
1023    * avoid destroying the transform values.
1024    */
1025   if (!png_ptr->rgb_to_gray_coefficients_set)
1026   {
1027      /* png_set_background has not been called and we haven't seen an sRGB
1028       * chunk yet.  Find the XYZ of the three end points.
1029       */
1030      png_XYZ XYZ;
1031      png_xy xy;
1032
1033      xy.redx = x_red;
1034      xy.redy = y_red;
1035      xy.greenx = x_green;
1036      xy.greeny = y_green;
1037      xy.bluex = x_blue;
1038      xy.bluey = y_blue;
1039      xy.whitex = x_white;
1040      xy.whitey = y_white;
1041
1042      if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
1043      {
1044         /* The success case, because XYZ_from_xy normalises to a reference
1045          * white Y of 1.0 we just need to scale the numbers.  This should
1046          * always work just fine. It is an internal error if this overflows.
1047          */
1048         {
1049            png_fixed_point r, g, b;
1050            if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) &&
1051               r >= 0 && r <= 32768 &&
1052               png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) &&
1053               g >= 0 && g <= 32768 &&
1054               png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) &&
1055               b >= 0 && b <= 32768 &&
1056               r+g+b <= 32769)
1057            {
1058               /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
1059                * all of the coefficients were rounded up.  Handle this by
1060                * reducing the *largest* coefficient by 1; this matches the
1061                * approach used for the default coefficients in pngrtran.c
1062                */
1063               int add = 0;
1064
1065               if (r+g+b > 32768)
1066                  add = -1;
1067               else if (r+g+b < 32768)
1068                  add = 1;
1069
1070               if (add != 0)
1071               {
1072                  if (g >= r && g >= b)
1073                     g += add;
1074                  else if (r >= g && r >= b)
1075                     r += add;
1076                  else
1077                     b += add;
1078               }
1079
1080               /* Check for an internal error. */
1081               if (r+g+b != 32768)
1082                  png_error(png_ptr,
1083                     "internal error handling cHRM coefficients");
1084
1085               png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
1086               png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
1087            }
1088
1089            /* This is a png_error at present even though it could be ignored -
1090             * it should never happen, but it is important that if it does, the
1091             * bug is fixed.
1092             */
1093            else
1094               png_error(png_ptr, "internal error handling cHRM->XYZ");
1095         }
1096      }
1097   }
1098#endif
1099
1100   png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
1101      x_green, y_green, x_blue, y_blue);
1102}
1103#endif
1104
1105#ifdef PNG_READ_sRGB_SUPPORTED
1106void /* PRIVATE */
1107png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1108{
1109   int intent;
1110   png_byte buf[1];
1111
1112   png_debug(1, "in png_handle_sRGB");
1113
1114   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1115      png_error(png_ptr, "Missing IHDR before sRGB");
1116
1117   else if (png_ptr->mode & PNG_HAVE_IDAT)
1118   {
1119      png_warning(png_ptr, "Invalid sRGB after IDAT");
1120      png_crc_finish(png_ptr, length);
1121      return;
1122   }
1123
1124   else if (png_ptr->mode & PNG_HAVE_PLTE)
1125      /* Should be an error, but we can cope with it */
1126      png_warning(png_ptr, "Out of place sRGB chunk");
1127
1128   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
1129   {
1130      png_warning(png_ptr, "Duplicate sRGB chunk");
1131      png_crc_finish(png_ptr, length);
1132      return;
1133   }
1134
1135   if (length != 1)
1136   {
1137      png_warning(png_ptr, "Incorrect sRGB chunk length");
1138      png_crc_finish(png_ptr, length);
1139      return;
1140   }
1141
1142   png_crc_read(png_ptr, buf, 1);
1143
1144   if (png_crc_finish(png_ptr, 0))
1145      return;
1146
1147   intent = buf[0];
1148
1149   /* Check for bad intent */
1150   if (intent >= PNG_sRGB_INTENT_LAST)
1151   {
1152      png_warning(png_ptr, "Unknown sRGB intent");
1153      return;
1154   }
1155
1156#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
1157   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
1158   {
1159      if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500))
1160      {
1161         PNG_WARNING_PARAMETERS(p)
1162
1163         png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed,
1164            info_ptr->gamma);
1165
1166         png_formatted_warning(png_ptr, p,
1167             "Ignoring incorrect gAMA value @1 when sRGB is also present");
1168      }
1169   }
1170#endif /* PNG_READ_gAMA_SUPPORTED */
1171
1172#ifdef PNG_READ_cHRM_SUPPORTED
1173   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1174      if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270,  1000) ||
1175          PNG_OUT_OF_RANGE(info_ptr->y_white, 32900,  1000) ||
1176          PNG_OUT_OF_RANGE(info_ptr->x_red,   64000,  1000) ||
1177          PNG_OUT_OF_RANGE(info_ptr->y_red,   33000,  1000) ||
1178          PNG_OUT_OF_RANGE(info_ptr->x_green, 30000,  1000) ||
1179          PNG_OUT_OF_RANGE(info_ptr->y_green, 60000,  1000) ||
1180          PNG_OUT_OF_RANGE(info_ptr->x_blue,  15000,  1000) ||
1181          PNG_OUT_OF_RANGE(info_ptr->y_blue,   6000,  1000))
1182      {
1183         png_warning(png_ptr,
1184             "Ignoring incorrect cHRM value when sRGB is also present");
1185      }
1186#endif /* PNG_READ_cHRM_SUPPORTED */
1187
1188   /* This is recorded for use when handling the cHRM chunk above.  An sRGB
1189    * chunk unconditionally overwrites the coefficients for grayscale conversion
1190    * too.
1191    */
1192   png_ptr->is_sRGB = 1;
1193
1194#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1195      /* Don't overwrite user supplied values: */
1196      if (!png_ptr->rgb_to_gray_coefficients_set)
1197      {
1198         /* These numbers come from the sRGB specification (or, since one has to
1199          * pay much money to get a copy, the wikipedia sRGB page) the
1200          * chromaticity values quoted have been inverted to get the reverse
1201          * transformation from RGB to XYZ and the 'Y' coefficients scaled by
1202          * 32768 (then rounded).
1203          *
1204          * sRGB and ITU Rec-709 both truncate the values for the D65 white
1205          * point to four digits and, even though it actually stores five
1206          * digits, the PNG spec gives the truncated value.
1207          *
1208          * This means that when the chromaticities are converted back to XYZ
1209          * end points we end up with (6968,23435,2366), which, as described in
1210          * pngrtran.c, would overflow.  If the five digit precision and up is
1211          * used we get, instead:
1212          *
1213          *    6968*R + 23435*G + 2365*B
1214          *
1215          * (Notice that this rounds the blue coefficient down, rather than the
1216          * choice used in pngrtran.c which is to round the green one down.)
1217          */
1218         png_ptr->rgb_to_gray_red_coeff   =  6968; /* 0.212639005871510 */
1219         png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */
1220         /* png_ptr->rgb_to_gray_blue_coeff  =  2366; 0.072192315360734	*/
1221
1222         /* The following keeps the cHRM chunk from destroying the
1223          * coefficients again in the event that it follows the sRGB chunk.
1224          */
1225         png_ptr->rgb_to_gray_coefficients_set = 1;
1226      }
1227#  endif
1228
1229   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1230}
1231#endif /* PNG_READ_sRGB_SUPPORTED */
1232
1233#ifdef PNG_READ_iCCP_SUPPORTED
1234void /* PRIVATE */
1235png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1236/* Note: this does not properly handle chunks that are > 64K under DOS */
1237{
1238   png_byte compression_type;
1239   png_bytep pC;
1240   png_charp profile;
1241   png_uint_32 skip = 0;
1242   png_uint_32 profile_size;
1243   png_alloc_size_t profile_length;
1244   png_size_t slength, prefix_length, data_length;
1245
1246   png_debug(1, "in png_handle_iCCP");
1247
1248   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1249      png_error(png_ptr, "Missing IHDR before iCCP");
1250
1251   else if (png_ptr->mode & PNG_HAVE_IDAT)
1252   {
1253      png_warning(png_ptr, "Invalid iCCP after IDAT");
1254      png_crc_finish(png_ptr, length);
1255      return;
1256   }
1257
1258   else if (png_ptr->mode & PNG_HAVE_PLTE)
1259      /* Should be an error, but we can cope with it */
1260      png_warning(png_ptr, "Out of place iCCP chunk");
1261
1262   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1263   {
1264      png_warning(png_ptr, "Duplicate iCCP chunk");
1265      png_crc_finish(png_ptr, length);
1266      return;
1267   }
1268
1269#ifdef PNG_MAX_MALLOC_64K
1270   if (length > (png_uint_32)65535L)
1271   {
1272      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1273      skip = length - (png_uint_32)65535L;
1274      length = (png_uint_32)65535L;
1275   }
1276#endif
1277
1278   png_free(png_ptr, png_ptr->chunkdata);
1279   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1280   slength = length;
1281   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1282
1283   if (png_crc_finish(png_ptr, skip))
1284   {
1285      png_free(png_ptr, png_ptr->chunkdata);
1286      png_ptr->chunkdata = NULL;
1287      return;
1288   }
1289
1290   png_ptr->chunkdata[slength] = 0x00;
1291
1292   for (profile = png_ptr->chunkdata; *profile; profile++)
1293      /* Empty loop to find end of name */ ;
1294
1295   ++profile;
1296
1297   /* There should be at least one zero (the compression type byte)
1298    * following the separator, and we should be on it
1299    */
1300   if (profile >= png_ptr->chunkdata + slength - 1)
1301   {
1302      png_free(png_ptr, png_ptr->chunkdata);
1303      png_ptr->chunkdata = NULL;
1304      png_warning(png_ptr, "Malformed iCCP chunk");
1305      return;
1306   }
1307
1308   /* Compression_type should always be zero */
1309   compression_type = *profile++;
1310
1311   if (compression_type)
1312   {
1313      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1314      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
1315                                 wrote nonzero) */
1316   }
1317
1318   prefix_length = profile - png_ptr->chunkdata;
1319   png_decompress_chunk(png_ptr, compression_type,
1320       slength, prefix_length, &data_length);
1321
1322   profile_length = data_length - prefix_length;
1323
1324   if (prefix_length > data_length || profile_length < 4)
1325   {
1326      png_free(png_ptr, png_ptr->chunkdata);
1327      png_ptr->chunkdata = NULL;
1328      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1329      return;
1330   }
1331
1332   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1333   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1334   profile_size = ((*(pC    )) << 24) |
1335                  ((*(pC + 1)) << 16) |
1336                  ((*(pC + 2)) <<  8) |
1337                  ((*(pC + 3))      );
1338
1339   /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
1340    * because profile_size is a 32 bit value.
1341    */
1342   if (profile_size < profile_length)
1343      profile_length = profile_size;
1344
1345   /* And the following guarantees that profile_size == profile_length. */
1346   if (profile_size > profile_length)
1347   {
1348      PNG_WARNING_PARAMETERS(p)
1349
1350      png_free(png_ptr, png_ptr->chunkdata);
1351      png_ptr->chunkdata = NULL;
1352
1353      png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size);
1354      png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length);
1355      png_formatted_warning(png_ptr, p,
1356         "Ignoring iCCP chunk with declared size = @1 and actual length = @2");
1357      return;
1358   }
1359
1360   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1361       compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
1362       profile_size);
1363   png_free(png_ptr, png_ptr->chunkdata);
1364   png_ptr->chunkdata = NULL;
1365}
1366#endif /* PNG_READ_iCCP_SUPPORTED */
1367
1368#ifdef PNG_READ_sPLT_SUPPORTED
1369void /* PRIVATE */
1370png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1371/* Note: this does not properly handle chunks that are > 64K under DOS */
1372{
1373   png_bytep entry_start;
1374   png_sPLT_t new_palette;
1375   png_sPLT_entryp pp;
1376   png_uint_32 data_length;
1377   int entry_size, i;
1378   png_uint_32 skip = 0;
1379   png_size_t slength;
1380   png_uint_32 dl;
1381   png_size_t max_dl;
1382
1383   png_debug(1, "in png_handle_sPLT");
1384
1385#ifdef PNG_USER_LIMITS_SUPPORTED
1386
1387   if (png_ptr->user_chunk_cache_max != 0)
1388   {
1389      if (png_ptr->user_chunk_cache_max == 1)
1390      {
1391         png_crc_finish(png_ptr, length);
1392         return;
1393      }
1394
1395      if (--png_ptr->user_chunk_cache_max == 1)
1396      {
1397         png_warning(png_ptr, "No space in chunk cache for sPLT");
1398         png_crc_finish(png_ptr, length);
1399         return;
1400      }
1401   }
1402#endif
1403
1404   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1405      png_error(png_ptr, "Missing IHDR before sPLT");
1406
1407   else if (png_ptr->mode & PNG_HAVE_IDAT)
1408   {
1409      png_warning(png_ptr, "Invalid sPLT after IDAT");
1410      png_crc_finish(png_ptr, length);
1411      return;
1412   }
1413
1414#ifdef PNG_MAX_MALLOC_64K
1415   if (length > (png_uint_32)65535L)
1416   {
1417      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1418      skip = length - (png_uint_32)65535L;
1419      length = (png_uint_32)65535L;
1420   }
1421#endif
1422
1423   png_free(png_ptr, png_ptr->chunkdata);
1424   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1425
1426   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
1427    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
1428    * potential breakage point if the types in pngconf.h aren't exactly right.
1429    */
1430   slength = length;
1431   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1432
1433   if (png_crc_finish(png_ptr, skip))
1434   {
1435      png_free(png_ptr, png_ptr->chunkdata);
1436      png_ptr->chunkdata = NULL;
1437      return;
1438   }
1439
1440   png_ptr->chunkdata[slength] = 0x00;
1441
1442   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1443       entry_start++)
1444      /* Empty loop to find end of name */ ;
1445
1446   ++entry_start;
1447
1448   /* A sample depth should follow the separator, and we should be on it  */
1449   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1450   {
1451      png_free(png_ptr, png_ptr->chunkdata);
1452      png_ptr->chunkdata = NULL;
1453      png_warning(png_ptr, "malformed sPLT chunk");
1454      return;
1455   }
1456
1457   new_palette.depth = *entry_start++;
1458   entry_size = (new_palette.depth == 8 ? 6 : 10);
1459   /* This must fit in a png_uint_32 because it is derived from the original
1460    * chunk data length (and use 'length', not 'slength' here for clarity -
1461    * they are guaranteed to be the same, see the tests above.)
1462    */
1463   data_length = length - (png_uint_32)(entry_start -
1464      (png_bytep)png_ptr->chunkdata);
1465
1466   /* Integrity-check the data length */
1467   if (data_length % entry_size)
1468   {
1469      png_free(png_ptr, png_ptr->chunkdata);
1470      png_ptr->chunkdata = NULL;
1471      png_warning(png_ptr, "sPLT chunk has bad length");
1472      return;
1473   }
1474
1475   dl = (png_int_32)(data_length / entry_size);
1476   max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry);
1477
1478   if (dl > max_dl)
1479   {
1480       png_warning(png_ptr, "sPLT chunk too long");
1481       return;
1482   }
1483
1484   new_palette.nentries = (png_int_32)(data_length / entry_size);
1485
1486   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1487       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1488
1489   if (new_palette.entries == NULL)
1490   {
1491       png_warning(png_ptr, "sPLT chunk requires too much memory");
1492       return;
1493   }
1494
1495#ifdef PNG_POINTER_INDEXING_SUPPORTED
1496   for (i = 0; i < new_palette.nentries; i++)
1497   {
1498      pp = new_palette.entries + i;
1499
1500      if (new_palette.depth == 8)
1501      {
1502         pp->red = *entry_start++;
1503         pp->green = *entry_start++;
1504         pp->blue = *entry_start++;
1505         pp->alpha = *entry_start++;
1506      }
1507
1508      else
1509      {
1510         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1511         pp->green = png_get_uint_16(entry_start); entry_start += 2;
1512         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1513         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1514      }
1515
1516      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1517   }
1518#else
1519   pp = new_palette.entries;
1520
1521   for (i = 0; i < new_palette.nentries; i++)
1522   {
1523
1524      if (new_palette.depth == 8)
1525      {
1526         pp[i].red   = *entry_start++;
1527         pp[i].green = *entry_start++;
1528         pp[i].blue  = *entry_start++;
1529         pp[i].alpha = *entry_start++;
1530      }
1531
1532      else
1533      {
1534         pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
1535         pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1536         pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
1537         pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1538      }
1539
1540      pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
1541   }
1542#endif
1543
1544   /* Discard all chunk data except the name and stash that */
1545   new_palette.name = png_ptr->chunkdata;
1546
1547   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1548
1549   png_free(png_ptr, png_ptr->chunkdata);
1550   png_ptr->chunkdata = NULL;
1551   png_free(png_ptr, new_palette.entries);
1552}
1553#endif /* PNG_READ_sPLT_SUPPORTED */
1554
1555#ifdef PNG_READ_tRNS_SUPPORTED
1556void /* PRIVATE */
1557png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1558{
1559   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1560
1561   png_debug(1, "in png_handle_tRNS");
1562
1563   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1564      png_error(png_ptr, "Missing IHDR before tRNS");
1565
1566   else if (png_ptr->mode & PNG_HAVE_IDAT)
1567   {
1568      png_warning(png_ptr, "Invalid tRNS after IDAT");
1569      png_crc_finish(png_ptr, length);
1570      return;
1571   }
1572
1573   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1574   {
1575      png_warning(png_ptr, "Duplicate tRNS chunk");
1576      png_crc_finish(png_ptr, length);
1577      return;
1578   }
1579
1580   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1581   {
1582      png_byte buf[2];
1583
1584      if (length != 2)
1585      {
1586         png_warning(png_ptr, "Incorrect tRNS chunk length");
1587         png_crc_finish(png_ptr, length);
1588         return;
1589      }
1590
1591      png_crc_read(png_ptr, buf, 2);
1592      png_ptr->num_trans = 1;
1593      png_ptr->trans_color.gray = png_get_uint_16(buf);
1594   }
1595
1596   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1597   {
1598      png_byte buf[6];
1599
1600      if (length != 6)
1601      {
1602         png_warning(png_ptr, "Incorrect tRNS chunk length");
1603         png_crc_finish(png_ptr, length);
1604         return;
1605      }
1606
1607      png_crc_read(png_ptr, buf, (png_size_t)length);
1608      png_ptr->num_trans = 1;
1609      png_ptr->trans_color.red = png_get_uint_16(buf);
1610      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
1611      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
1612   }
1613
1614   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1615   {
1616      if (!(png_ptr->mode & PNG_HAVE_PLTE))
1617      {
1618         /* Should be an error, but we can cope with it. */
1619         png_warning(png_ptr, "Missing PLTE before tRNS");
1620      }
1621
1622      if (length > (png_uint_32)png_ptr->num_palette ||
1623          length > PNG_MAX_PALETTE_LENGTH)
1624      {
1625         png_warning(png_ptr, "Incorrect tRNS chunk length");
1626         png_crc_finish(png_ptr, length);
1627         return;
1628      }
1629
1630      if (length == 0)
1631      {
1632         png_warning(png_ptr, "Zero length tRNS chunk");
1633         png_crc_finish(png_ptr, length);
1634         return;
1635      }
1636
1637      png_crc_read(png_ptr, readbuf, (png_size_t)length);
1638      png_ptr->num_trans = (png_uint_16)length;
1639   }
1640
1641   else
1642   {
1643      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1644      png_crc_finish(png_ptr, length);
1645      return;
1646   }
1647
1648   if (png_crc_finish(png_ptr, 0))
1649   {
1650      png_ptr->num_trans = 0;
1651      return;
1652   }
1653
1654   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1655       &(png_ptr->trans_color));
1656}
1657#endif
1658
1659#ifdef PNG_READ_bKGD_SUPPORTED
1660void /* PRIVATE */
1661png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1662{
1663   png_size_t truelen;
1664   png_byte buf[6];
1665   png_color_16 background;
1666
1667   png_debug(1, "in png_handle_bKGD");
1668
1669   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1670      png_error(png_ptr, "Missing IHDR before bKGD");
1671
1672   else if (png_ptr->mode & PNG_HAVE_IDAT)
1673   {
1674      png_warning(png_ptr, "Invalid bKGD after IDAT");
1675      png_crc_finish(png_ptr, length);
1676      return;
1677   }
1678
1679   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1680       !(png_ptr->mode & PNG_HAVE_PLTE))
1681   {
1682      png_warning(png_ptr, "Missing PLTE before bKGD");
1683      png_crc_finish(png_ptr, length);
1684      return;
1685   }
1686
1687   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1688   {
1689      png_warning(png_ptr, "Duplicate bKGD chunk");
1690      png_crc_finish(png_ptr, length);
1691   

Large files files are truncated, but you can click here to view the full file