Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. /* pngrutil.c - utilities to read a PNG file
  3.  *
  4.  * Last changed in libpng 1.5.1 [February 3, 2011]
  5.  * Copyright (c) 1998-2011 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.  
  23. png_uint_32 PNGAPI
  24. png_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.  
  42. static png_fixed_point /* PRIVATE */
  43. png_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. */
  69. png_uint_32 (PNGAPI
  70. png_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.  */
  86. png_int_32 (PNGAPI
  87. png_get_int_32)(png_const_bytep buf)
  88. {
  89.    png_uint_32 uval = png_get_uint_32(buf);
  90.    if ((uval & 0x80000000L) == 0) /* non-negative */
  91.       return uval;
  92.  
  93.    uval = (uval ^ 0xffffffffL) + 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. */
  98. png_uint_16 (PNGAPI
  99. png_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 */
  116. void /* PRIVATE */
  117. png_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.  */
  151. png_uint_32 /* PRIVATE */
  152. png_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_memcpy(png_ptr->chunk_name, buf + 4, 4);
  169.  
  170.    png_debug2(0, "Reading %s chunk, length = %u",
  171.        png_ptr->chunk_name, 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, png_ptr->chunk_name, 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. */
  188. void /* PRIVATE */
  189. png_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.  */
  203. int /* PRIVATE */
  204. png_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_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
  222.           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
  223.           (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
  224.           (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
  225.       {
  226.          png_chunk_warning(png_ptr, "CRC error");
  227.       }
  228.  
  229.       else
  230.       {
  231.          png_chunk_benign_error(png_ptr, "CRC error");
  232.          return (0);
  233.       }
  234.  
  235.       return (1);
  236.    }
  237.  
  238.    return (0);
  239. }
  240.  
  241. /* Compare the CRC stored in the PNG file with that calculated by libpng from
  242.  * the data it has read thus far.
  243.  */
  244. int /* PRIVATE */
  245. png_crc_error(png_structp png_ptr)
  246. {
  247.    png_byte crc_bytes[4];
  248.    png_uint_32 crc;
  249.    int need_crc = 1;
  250.  
  251.    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
  252.    {
  253.       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
  254.           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
  255.          need_crc = 0;
  256.    }
  257.  
  258.    else                                                    /* critical */
  259.    {
  260.       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
  261.          need_crc = 0;
  262.    }
  263.  
  264. #ifdef PNG_IO_STATE_SUPPORTED
  265.    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
  266. #endif
  267.  
  268.    /* The chunk CRC must be serialized in a single I/O call. */
  269.    png_read_data(png_ptr, crc_bytes, 4);
  270.  
  271.    if (need_crc)
  272.    {
  273.       crc = png_get_uint_32(crc_bytes);
  274.       return ((int)(crc != png_ptr->crc));
  275.    }
  276.  
  277.    else
  278.       return (0);
  279. }
  280.  
  281. #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
  282.     defined(PNG_READ_iCCP_SUPPORTED)
  283. static png_size_t
  284. png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
  285.     png_bytep output, png_size_t output_size)
  286. {
  287.    png_size_t count = 0;
  288.  
  289.    /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
  290.     * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
  291.     * more".  Consequently it is necessary to chunk the input to zlib.  This
  292.     * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
  293.     * that can be stored in a uInt.)  It is possible to set ZLIB_IO_MAX to a
  294.     * lower value in pngpriv.h and this may sometimes have a performance
  295.     * advantage, because it forces access of the input data to be separated from
  296.     * at least some of the use by some period of time.
  297.     */
  298.    png_ptr->zstream.next_in = data;
  299.    /* avail_in is set below from 'size' */
  300.    png_ptr->zstream.avail_in = 0;
  301.  
  302.    while (1)
  303.    {
  304.       int ret, avail;
  305.  
  306.       /* The setting of 'avail_in' used to be outside the loop, by setting it
  307.        * inside it is possible to chunk the input to zlib and simply rely on
  308.        * zlib to advance the 'next_in' pointer.  This allows arbitrary amounts o
  309.        * data to be passed through zlib at the unavoidable cost of requiring a
  310.        * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
  311.        * input bytes.
  312.        */
  313.       if (png_ptr->zstream.avail_in == 0 && size > 0)
  314.       {
  315.          if (size <= ZLIB_IO_MAX)
  316.          {
  317.             /* The value is less than ZLIB_IO_MAX so the cast is safe: */
  318.             png_ptr->zstream.avail_in = (uInt)size;
  319.             size = 0;
  320.          }
  321.  
  322.          else
  323.          {
  324.             png_ptr->zstream.avail_in = ZLIB_IO_MAX;
  325.             size -= ZLIB_IO_MAX;
  326.          }
  327.       }
  328.  
  329.       /* Reset the output buffer each time round - we empty it
  330.        * after every inflate call.
  331.        */
  332.       png_ptr->zstream.next_out = png_ptr->zbuf;
  333.       png_ptr->zstream.avail_out = png_ptr->zbuf_size;
  334.  
  335.       ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
  336.       avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  337.  
  338.       /* First copy/count any new output - but only if we didn't
  339.        * get an error code.
  340.        */
  341.       if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
  342.       {
  343.          png_size_t space = avail; /* > 0, see above */
  344.  
  345.          if (output != 0 && output_size > count)
  346.          {
  347.             png_size_t copy = output_size - count;
  348.  
  349.             if (space < copy)
  350.                copy = space;
  351.  
  352.             png_memcpy(output + count, png_ptr->zbuf, copy);
  353.          }
  354.          count += space;
  355.       }
  356.  
  357.       if (ret == Z_OK)
  358.          continue;
  359.  
  360.       /* Termination conditions - always reset the zstream, it
  361.        * must be left in inflateInit state.
  362.        */
  363.       png_ptr->zstream.avail_in = 0;
  364.       inflateReset(&png_ptr->zstream);
  365.  
  366.       if (ret == Z_STREAM_END)
  367.          return count; /* NOTE: may be zero. */
  368.  
  369.       /* Now handle the error codes - the API always returns 0
  370.        * and the error message is dumped into the uncompressed
  371.        * buffer if available.
  372.        */
  373.       {
  374.          PNG_CONST char *msg;
  375. #ifdef PNG_CONSOLE_IO_SUPPORTED
  376.          char umsg[52];
  377. #endif
  378.          if (png_ptr->zstream.msg != 0)
  379.             msg = png_ptr->zstream.msg;
  380.  
  381.          else
  382.          {
  383. #ifdef PNG_CONSOLE_IO_SUPPORTED
  384.             switch (ret)
  385.             {
  386.                case Z_BUF_ERROR:
  387.                   msg = "Buffer error in compressed datastream in %s chunk";
  388.                   break;
  389.  
  390.                case Z_DATA_ERROR:
  391.                   msg = "Data error in compressed datastream in %s chunk";
  392.                   break;
  393.  
  394.                default:
  395.                   msg = "Incomplete compressed datastream in %s chunk";
  396.                   break;
  397.             }
  398.  
  399.             png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
  400.             msg = umsg;
  401. #else
  402.             msg = "Damaged compressed datastream in chunk other than IDAT";
  403. #endif
  404.          }
  405.  
  406.          png_warning(png_ptr, msg);
  407.       }
  408.  
  409.       /* 0 means an error - notice that this code simply ignores
  410.        * zero length compressed chunks as a result.
  411.        */
  412.       return 0;
  413.    }
  414. }
  415.  
  416. /*
  417.  * Decompress trailing data in a chunk.  The assumption is that chunkdata
  418.  * points at an allocated area holding the contents of a chunk with a
  419.  * trailing compressed part.  What we get back is an allocated area
  420.  * holding the original prefix part and an uncompressed version of the
  421.  * trailing part (the malloc area passed in is freed).
  422.  */
  423. void /* PRIVATE */
  424. png_decompress_chunk(png_structp png_ptr, int comp_type,
  425.     png_size_t chunklength,
  426.     png_size_t prefix_size, png_size_t *newlength)
  427. {
  428.    /* The caller should guarantee this */
  429.    if (prefix_size > chunklength)
  430.    {
  431.       /* The recovery is to delete the chunk. */
  432.       png_warning(png_ptr, "invalid chunklength");
  433.       prefix_size = 0; /* To delete everything */
  434.    }
  435.  
  436.    else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
  437.    {
  438.       png_size_t expanded_size = png_inflate(png_ptr,
  439.           (png_bytep)(png_ptr->chunkdata + prefix_size),
  440.           chunklength - prefix_size,
  441.           0,            /*output*/
  442.           0);           /*output size*/
  443.  
  444.       /* Now check the limits on this chunk - if the limit fails the
  445.        * compressed data will be removed, the prefix will remain.
  446.        */
  447. #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
  448.       if (png_ptr->user_chunk_malloc_max &&
  449.           (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
  450. #else
  451. #  ifdef PNG_USER_CHUNK_MALLOC_MAX
  452.       if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
  453.           prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
  454. #  endif
  455. #endif
  456.          png_warning(png_ptr, "Exceeded size limit while expanding chunk");
  457.  
  458.       /* If the size is zero either there was an error and a message
  459.        * has already been output (warning) or the size really is zero
  460.        * and we have nothing to do - the code will exit through the
  461.        * error case below.
  462.        */
  463. #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
  464.     defined(PNG_USER_CHUNK_MALLOC_MAX)
  465.       else if (expanded_size > 0)
  466. #else
  467.       if (expanded_size > 0)
  468. #endif
  469.       {
  470.          /* Success (maybe) - really uncompress the chunk. */
  471.          png_size_t new_size = 0;
  472.          png_charp text = png_malloc_warn(png_ptr,
  473.              prefix_size + expanded_size + 1);
  474.  
  475.          if (text != NULL)
  476.          {
  477.             png_memcpy(text, png_ptr->chunkdata, prefix_size);
  478.             new_size = png_inflate(png_ptr,
  479.                 (png_bytep)(png_ptr->chunkdata + prefix_size),
  480.                 chunklength - prefix_size,
  481.                 (png_bytep)(text + prefix_size), expanded_size);
  482.             text[prefix_size + expanded_size] = 0; /* just in case */
  483.  
  484.             if (new_size == expanded_size)
  485.             {
  486.                png_free(png_ptr, png_ptr->chunkdata);
  487.                png_ptr->chunkdata = text;
  488.                *newlength = prefix_size + expanded_size;
  489.                return; /* The success return! */
  490.             }
  491.  
  492.             png_warning(png_ptr, "png_inflate logic error");
  493.             png_free(png_ptr, text);
  494.          }
  495.  
  496.          else
  497.             png_warning(png_ptr, "Not enough memory to decompress chunk");
  498.       }
  499.    }
  500.  
  501.    else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
  502.    {
  503. #ifdef PNG_STDIO_SUPPORTED
  504.       char umsg[50];
  505.  
  506.       png_snprintf(umsg, sizeof umsg,
  507.           "Unknown zTXt compression type %d", comp_type);
  508.       png_warning(png_ptr, umsg);
  509. #else
  510.       png_warning(png_ptr, "Unknown zTXt compression type");
  511. #endif
  512.  
  513.       /* The recovery is to simply drop the data. */
  514.    }
  515.  
  516.    /* Generic error return - leave the prefix, delete the compressed
  517.     * data, reallocate the chunkdata to remove the potentially large
  518.     * amount of compressed data.
  519.     */
  520.    {
  521.       png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
  522.  
  523.       if (text != NULL)
  524.       {
  525.          if (prefix_size > 0)
  526.             png_memcpy(text, png_ptr->chunkdata, prefix_size);
  527.  
  528.          png_free(png_ptr, png_ptr->chunkdata);
  529.          png_ptr->chunkdata = text;
  530.  
  531.          /* This is an extra zero in the 'uncompressed' part. */
  532.          *(png_ptr->chunkdata + prefix_size) = 0x00;
  533.       }
  534.       /* Ignore a malloc error here - it is safe. */
  535.    }
  536.  
  537.    *newlength = prefix_size;
  538. }
  539. #endif
  540.  
  541. /* Read and check the IDHR chunk */
  542. void /* PRIVATE */
  543. png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  544. {
  545.    png_byte buf[13];
  546.    png_uint_32 width, height;
  547.    int bit_depth, color_type, compression_type, filter_type;
  548.    int interlace_type;
  549.  
  550.    png_debug(1, "in png_handle_IHDR");
  551.  
  552.    if (png_ptr->mode & PNG_HAVE_IHDR)
  553.       png_error(png_ptr, "Out of place IHDR");
  554.  
  555.    /* Check the length */
  556.    if (length != 13)
  557.       png_error(png_ptr, "Invalid IHDR chunk");
  558.  
  559.    png_ptr->mode |= PNG_HAVE_IHDR;
  560.  
  561.    png_crc_read(png_ptr, buf, 13);
  562.    png_crc_finish(png_ptr, 0);
  563.  
  564.    width = png_get_uint_31(png_ptr, buf);
  565.    height = png_get_uint_31(png_ptr, buf + 4);
  566.    bit_depth = buf[8];
  567.    color_type = buf[9];
  568.    compression_type = buf[10];
  569.    filter_type = buf[11];
  570.    interlace_type = buf[12];
  571.  
  572.    /* Set internal variables */
  573.    png_ptr->width = width;
  574.    png_ptr->height = height;
  575.    png_ptr->bit_depth = (png_byte)bit_depth;
  576.    png_ptr->interlaced = (png_byte)interlace_type;
  577.    png_ptr->color_type = (png_byte)color_type;
  578. #ifdef PNG_MNG_FEATURES_SUPPORTED
  579.    png_ptr->filter_type = (png_byte)filter_type;
  580. #endif
  581.    png_ptr->compression_type = (png_byte)compression_type;
  582.  
  583.    /* Find number of channels */
  584.    switch (png_ptr->color_type)
  585.    {
  586.       default: /* invalid, png_set_IHDR calls png_error */
  587.       case PNG_COLOR_TYPE_GRAY:
  588.       case PNG_COLOR_TYPE_PALETTE:
  589.          png_ptr->channels = 1;
  590.          break;
  591.  
  592.       case PNG_COLOR_TYPE_RGB:
  593.          png_ptr->channels = 3;
  594.          break;
  595.  
  596.       case PNG_COLOR_TYPE_GRAY_ALPHA:
  597.          png_ptr->channels = 2;
  598.          break;
  599.  
  600.       case PNG_COLOR_TYPE_RGB_ALPHA:
  601.          png_ptr->channels = 4;
  602.          break;
  603.    }
  604.  
  605.    /* Set up other useful info */
  606.    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
  607.    png_ptr->channels);
  608.    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
  609.    png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
  610.    png_debug1(3, "channels = %d", png_ptr->channels);
  611.    png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
  612.    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
  613.        color_type, interlace_type, compression_type, filter_type);
  614. }
  615.  
  616. /* Read and check the palette */
  617. void /* PRIVATE */
  618. png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  619. {
  620.    png_color palette[PNG_MAX_PALETTE_LENGTH];
  621.    int num, i;
  622. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  623.    png_colorp pal_ptr;
  624. #endif
  625.  
  626.    png_debug(1, "in png_handle_PLTE");
  627.  
  628.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  629.       png_error(png_ptr, "Missing IHDR before PLTE");
  630.  
  631.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  632.    {
  633.       png_warning(png_ptr, "Invalid PLTE after IDAT");
  634.       png_crc_finish(png_ptr, length);
  635.       return;
  636.    }
  637.  
  638.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  639.       png_error(png_ptr, "Duplicate PLTE chunk");
  640.  
  641.    png_ptr->mode |= PNG_HAVE_PLTE;
  642.  
  643.    if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
  644.    {
  645.       png_warning(png_ptr,
  646.           "Ignoring PLTE chunk in grayscale PNG");
  647.       png_crc_finish(png_ptr, length);
  648.       return;
  649.    }
  650.  
  651. #ifndef PNG_READ_OPT_PLTE_SUPPORTED
  652.    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  653.    {
  654.       png_crc_finish(png_ptr, length);
  655.       return;
  656.    }
  657. #endif
  658.  
  659.    if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
  660.    {
  661.       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  662.       {
  663.          png_warning(png_ptr, "Invalid palette chunk");
  664.          png_crc_finish(png_ptr, length);
  665.          return;
  666.       }
  667.  
  668.       else
  669.       {
  670.          png_error(png_ptr, "Invalid palette chunk");
  671.       }
  672.    }
  673.  
  674.    num = (int)length / 3;
  675.  
  676. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  677.    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
  678.    {
  679.       png_byte buf[3];
  680.  
  681.       png_crc_read(png_ptr, buf, 3);
  682.       pal_ptr->red = buf[0];
  683.       pal_ptr->green = buf[1];
  684.       pal_ptr->blue = buf[2];
  685.    }
  686. #else
  687.    for (i = 0; i < num; i++)
  688.    {
  689.       png_byte buf[3];
  690.  
  691.       png_crc_read(png_ptr, buf, 3);
  692.       /* Don't depend upon png_color being any order */
  693.       palette[i].red = buf[0];
  694.       palette[i].green = buf[1];
  695.       palette[i].blue = buf[2];
  696.    }
  697. #endif
  698.  
  699.    /* If we actually need the PLTE chunk (ie for a paletted image), we do
  700.     * whatever the normal CRC configuration tells us.  However, if we
  701.     * have an RGB image, the PLTE can be considered ancillary, so
  702.     * we will act as though it is.
  703.     */
  704. #ifndef PNG_READ_OPT_PLTE_SUPPORTED
  705.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  706. #endif
  707.    {
  708.       png_crc_finish(png_ptr, 0);
  709.    }
  710.  
  711. #ifndef PNG_READ_OPT_PLTE_SUPPORTED
  712.    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
  713.    {
  714.       /* If we don't want to use the data from an ancillary chunk,
  715.        * we have two options: an error abort, or a warning and we
  716.        * ignore the data in this chunk (which should be OK, since
  717.        * it's considered ancillary for a RGB or RGBA image).
  718.        */
  719.       if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
  720.       {
  721.          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
  722.          {
  723.             png_chunk_benign_error(png_ptr, "CRC error");
  724.          }
  725.  
  726.          else
  727.          {
  728.             png_chunk_warning(png_ptr, "CRC error");
  729.             return;
  730.          }
  731.       }
  732.  
  733.       /* Otherwise, we (optionally) emit a warning and use the chunk. */
  734.       else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
  735.       {
  736.          png_chunk_warning(png_ptr, "CRC error");
  737.       }
  738.    }
  739. #endif
  740.  
  741.    png_set_PLTE(png_ptr, info_ptr, palette, num);
  742.  
  743. #ifdef PNG_READ_tRNS_SUPPORTED
  744.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  745.    {
  746.       if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  747.       {
  748.          if (png_ptr->num_trans > (png_uint_16)num)
  749.          {
  750.             png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
  751.             png_ptr->num_trans = (png_uint_16)num;
  752.          }
  753.  
  754.          if (info_ptr->num_trans > (png_uint_16)num)
  755.          {
  756.             png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
  757.             info_ptr->num_trans = (png_uint_16)num;
  758.          }
  759.       }
  760.    }
  761. #endif
  762.  
  763. }
  764.  
  765. void /* PRIVATE */
  766. png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  767. {
  768.    png_debug(1, "in png_handle_IEND");
  769.  
  770.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
  771.    {
  772.       png_error(png_ptr, "No image in file");
  773.    }
  774.  
  775.    png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
  776.  
  777.    if (length != 0)
  778.    {
  779.       png_warning(png_ptr, "Incorrect IEND chunk length");
  780.    }
  781.  
  782.    png_crc_finish(png_ptr, length);
  783.  
  784.    PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
  785. }
  786.  
  787. #ifdef PNG_READ_gAMA_SUPPORTED
  788. void /* PRIVATE */
  789. png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  790. {
  791.    png_fixed_point igamma;
  792.    png_byte buf[4];
  793.  
  794.    png_debug(1, "in png_handle_gAMA");
  795.  
  796.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  797.       png_error(png_ptr, "Missing IHDR before gAMA");
  798.  
  799.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  800.    {
  801.       png_warning(png_ptr, "Invalid gAMA after IDAT");
  802.       png_crc_finish(png_ptr, length);
  803.       return;
  804.    }
  805.  
  806.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  807.       /* Should be an error, but we can cope with it */
  808.       png_warning(png_ptr, "Out of place gAMA chunk");
  809.  
  810.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
  811. #ifdef PNG_READ_sRGB_SUPPORTED
  812.        && !(info_ptr->valid & PNG_INFO_sRGB)
  813. #endif
  814.        )
  815.    {
  816.       png_warning(png_ptr, "Duplicate gAMA chunk");
  817.       png_crc_finish(png_ptr, length);
  818.       return;
  819.    }
  820.  
  821.    if (length != 4)
  822.    {
  823.       png_warning(png_ptr, "Incorrect gAMA chunk length");
  824.       png_crc_finish(png_ptr, length);
  825.       return;
  826.    }
  827.  
  828.    png_crc_read(png_ptr, buf, 4);
  829.  
  830.    if (png_crc_finish(png_ptr, 0))
  831.       return;
  832.  
  833.    igamma = png_get_fixed_point(NULL, buf);
  834.  
  835.    /* Check for zero gamma or an error. */
  836.    if (igamma <= 0)
  837.    {
  838.       png_warning(png_ptr,
  839.           "Ignoring gAMA chunk with out of range gamma");
  840.  
  841.       return;
  842.    }
  843.  
  844. #  ifdef PNG_READ_sRGB_SUPPORTED
  845.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
  846.    {
  847.       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
  848.       {
  849.          png_warning(png_ptr,
  850.              "Ignoring incorrect gAMA value when sRGB is also present");
  851.  
  852. #    ifdef PNG_CONSOLE_IO_SUPPORTED
  853.          fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
  854. #    endif
  855.          return;
  856.       }
  857.    }
  858. #  endif /* PNG_READ_sRGB_SUPPORTED */
  859.  
  860. #  ifdef PNG_READ_GAMMA_SUPPORTED
  861.    /* Gamma correction on read is supported. */
  862.    png_ptr->gamma = igamma;
  863. #  endif
  864.    /* And set the 'info' structure members. */
  865.    png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
  866. }
  867. #endif
  868.  
  869. #ifdef PNG_READ_sBIT_SUPPORTED
  870. void /* PRIVATE */
  871. png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  872. {
  873.    png_size_t truelen;
  874.    png_byte buf[4];
  875.  
  876.    png_debug(1, "in png_handle_sBIT");
  877.  
  878.    buf[0] = buf[1] = buf[2] = buf[3] = 0;
  879.  
  880.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  881.       png_error(png_ptr, "Missing IHDR before sBIT");
  882.  
  883.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  884.    {
  885.       png_warning(png_ptr, "Invalid sBIT after IDAT");
  886.       png_crc_finish(png_ptr, length);
  887.       return;
  888.    }
  889.  
  890.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  891.    {
  892.       /* Should be an error, but we can cope with it */
  893.       png_warning(png_ptr, "Out of place sBIT chunk");
  894.    }
  895.  
  896.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
  897.    {
  898.       png_warning(png_ptr, "Duplicate sBIT chunk");
  899.       png_crc_finish(png_ptr, length);
  900.       return;
  901.    }
  902.  
  903.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  904.       truelen = 3;
  905.  
  906.    else
  907.       truelen = (png_size_t)png_ptr->channels;
  908.  
  909.    if (length != truelen || length > 4)
  910.    {
  911.       png_warning(png_ptr, "Incorrect sBIT chunk length");
  912.       png_crc_finish(png_ptr, length);
  913.       return;
  914.    }
  915.  
  916.    png_crc_read(png_ptr, buf, truelen);
  917.  
  918.    if (png_crc_finish(png_ptr, 0))
  919.       return;
  920.  
  921.    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  922.    {
  923.       png_ptr->sig_bit.red = buf[0];
  924.       png_ptr->sig_bit.green = buf[1];
  925.       png_ptr->sig_bit.blue = buf[2];
  926.       png_ptr->sig_bit.alpha = buf[3];
  927.    }
  928.  
  929.    else
  930.    {
  931.       png_ptr->sig_bit.gray = buf[0];
  932.       png_ptr->sig_bit.red = buf[0];
  933.       png_ptr->sig_bit.green = buf[0];
  934.       png_ptr->sig_bit.blue = buf[0];
  935.       png_ptr->sig_bit.alpha = buf[1];
  936.    }
  937.  
  938.    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
  939. }
  940. #endif
  941.  
  942. #ifdef PNG_READ_cHRM_SUPPORTED
  943. void /* PRIVATE */
  944. png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  945. {
  946.    png_byte buf[32];
  947.    png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue,
  948.       y_blue;
  949.  
  950.    png_debug(1, "in png_handle_cHRM");
  951.  
  952.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  953.       png_error(png_ptr, "Missing IHDR before cHRM");
  954.  
  955.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  956.    {
  957.       png_warning(png_ptr, "Invalid cHRM after IDAT");
  958.       png_crc_finish(png_ptr, length);
  959.       return;
  960.    }
  961.  
  962.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  963.       /* Should be an error, but we can cope with it */
  964.       png_warning(png_ptr, "Missing PLTE before cHRM");
  965.  
  966.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
  967. #  ifdef PNG_READ_sRGB_SUPPORTED
  968.        && !(info_ptr->valid & PNG_INFO_sRGB)
  969. #  endif
  970.       )
  971.    {
  972.       png_warning(png_ptr, "Duplicate cHRM chunk");
  973.       png_crc_finish(png_ptr, length);
  974.       return;
  975.    }
  976.  
  977.    if (length != 32)
  978.    {
  979.       png_warning(png_ptr, "Incorrect cHRM chunk length");
  980.       png_crc_finish(png_ptr, length);
  981.       return;
  982.    }
  983.  
  984.    png_crc_read(png_ptr, buf, 32);
  985.  
  986.    if (png_crc_finish(png_ptr, 0))
  987.       return;
  988.  
  989.    x_white = png_get_fixed_point(NULL, buf);
  990.    y_white = png_get_fixed_point(NULL, buf + 4);
  991.    x_red   = png_get_fixed_point(NULL, buf + 8);
  992.    y_red   = png_get_fixed_point(NULL, buf + 12);
  993.    x_green = png_get_fixed_point(NULL, buf + 16);
  994.    y_green = png_get_fixed_point(NULL, buf + 20);
  995.    x_blue  = png_get_fixed_point(NULL, buf + 24);
  996.    y_blue  = png_get_fixed_point(NULL, buf + 28);
  997.  
  998.    if (x_white == PNG_FIXED_ERROR ||
  999.        y_white == PNG_FIXED_ERROR ||
  1000.        x_red   == PNG_FIXED_ERROR ||
  1001.        y_red   == PNG_FIXED_ERROR ||
  1002.        x_green == PNG_FIXED_ERROR ||
  1003.        y_green == PNG_FIXED_ERROR ||
  1004.        x_blue  == PNG_FIXED_ERROR ||
  1005.        y_blue  == PNG_FIXED_ERROR)
  1006.    {
  1007.       png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities");
  1008.       return;
  1009.    }
  1010.  
  1011. #ifdef PNG_READ_sRGB_SUPPORTED
  1012.    if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
  1013.    {
  1014.       if (PNG_OUT_OF_RANGE(x_white, 31270,  1000) ||
  1015.           PNG_OUT_OF_RANGE(y_white, 32900,  1000) ||
  1016.           PNG_OUT_OF_RANGE(x_red,   64000L, 1000) ||
  1017.           PNG_OUT_OF_RANGE(y_red,   33000,  1000) ||
  1018.           PNG_OUT_OF_RANGE(x_green, 30000,  1000) ||
  1019.           PNG_OUT_OF_RANGE(y_green, 60000L, 1000) ||
  1020.           PNG_OUT_OF_RANGE(x_blue,  15000,  1000) ||
  1021.           PNG_OUT_OF_RANGE(y_blue,   6000,  1000))
  1022.       {
  1023.          png_warning(png_ptr,
  1024.              "Ignoring incorrect cHRM value when sRGB is also present");
  1025.  
  1026. #ifdef PNG_CONSOLE_IO_SUPPORTED
  1027.          fprintf(stderr, "wx=%d, wy=%d, rx=%d, ry=%d\n",
  1028.              x_white, y_white, x_red, y_red);
  1029.  
  1030.          fprintf(stderr, "gx=%d, gy=%d, bx=%d, by=%d\n",
  1031.              x_green, y_green, x_blue, y_blue);
  1032. #endif /* PNG_CONSOLE_IO_SUPPORTED */
  1033.       }
  1034.       return;
  1035.    }
  1036. #endif /* PNG_READ_sRGB_SUPPORTED */
  1037.  
  1038.    png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
  1039.       x_green, y_green, x_blue, y_blue);
  1040. }
  1041. #endif
  1042.  
  1043. #ifdef PNG_READ_sRGB_SUPPORTED
  1044. void /* PRIVATE */
  1045. png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1046. {
  1047.    int intent;
  1048.    png_byte buf[1];
  1049.  
  1050.    png_debug(1, "in png_handle_sRGB");
  1051.  
  1052.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1053.       png_error(png_ptr, "Missing IHDR before sRGB");
  1054.  
  1055.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1056.    {
  1057.       png_warning(png_ptr, "Invalid sRGB after IDAT");
  1058.       png_crc_finish(png_ptr, length);
  1059.       return;
  1060.    }
  1061.  
  1062.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  1063.       /* Should be an error, but we can cope with it */
  1064.       png_warning(png_ptr, "Out of place sRGB chunk");
  1065.  
  1066.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
  1067.    {
  1068.       png_warning(png_ptr, "Duplicate sRGB chunk");
  1069.       png_crc_finish(png_ptr, length);
  1070.       return;
  1071.    }
  1072.  
  1073.    if (length != 1)
  1074.    {
  1075.       png_warning(png_ptr, "Incorrect sRGB chunk length");
  1076.       png_crc_finish(png_ptr, length);
  1077.       return;
  1078.    }
  1079.  
  1080.    png_crc_read(png_ptr, buf, 1);
  1081.  
  1082.    if (png_crc_finish(png_ptr, 0))
  1083.       return;
  1084.  
  1085.    intent = buf[0];
  1086.  
  1087.    /* Check for bad intent */
  1088.    if (intent >= PNG_sRGB_INTENT_LAST)
  1089.    {
  1090.       png_warning(png_ptr, "Unknown sRGB intent");
  1091.       return;
  1092.    }
  1093.  
  1094. #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  1095.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
  1096.    {
  1097.       if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500))
  1098.       {
  1099.          png_warning(png_ptr,
  1100.              "Ignoring incorrect gAMA value when sRGB is also present");
  1101. #ifdef PNG_CONSOLE_IO_SUPPORTED
  1102.          fprintf(stderr, "incorrect gamma=(%d/100000)\n", info_ptr->gamma);
  1103. #endif
  1104.       }
  1105.    }
  1106. #endif /* PNG_READ_gAMA_SUPPORTED */
  1107.  
  1108. #ifdef PNG_READ_cHRM_SUPPORTED
  1109.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
  1110.       if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270,  1000) ||
  1111.           PNG_OUT_OF_RANGE(info_ptr->y_white, 32900,  1000) ||
  1112.           PNG_OUT_OF_RANGE(info_ptr->x_red,   64000L, 1000) ||
  1113.           PNG_OUT_OF_RANGE(info_ptr->y_red,   33000,  1000) ||
  1114.           PNG_OUT_OF_RANGE(info_ptr->x_green, 30000,  1000) ||
  1115.           PNG_OUT_OF_RANGE(info_ptr->y_green, 60000L, 1000) ||
  1116.           PNG_OUT_OF_RANGE(info_ptr->x_blue,  15000,  1000) ||
  1117.           PNG_OUT_OF_RANGE(info_ptr->y_blue,   6000,  1000))
  1118.       {
  1119.          png_warning(png_ptr,
  1120.              "Ignoring incorrect cHRM value when sRGB is also present");
  1121.       }
  1122. #endif /* PNG_READ_cHRM_SUPPORTED */
  1123.  
  1124.    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
  1125. }
  1126. #endif /* PNG_READ_sRGB_SUPPORTED */
  1127.  
  1128. #ifdef PNG_READ_iCCP_SUPPORTED
  1129. void /* PRIVATE */
  1130. png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1131. /* Note: this does not properly handle chunks that are > 64K under DOS */
  1132. {
  1133.    png_byte compression_type;
  1134.    png_bytep pC;
  1135.    png_charp profile;
  1136.    png_uint_32 skip = 0;
  1137.    png_uint_32 profile_size;
  1138.    png_alloc_size_t profile_length;
  1139.    png_size_t slength, prefix_length, data_length;
  1140.  
  1141.    png_debug(1, "in png_handle_iCCP");
  1142.  
  1143.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1144.       png_error(png_ptr, "Missing IHDR before iCCP");
  1145.  
  1146.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1147.    {
  1148.       png_warning(png_ptr, "Invalid iCCP after IDAT");
  1149.       png_crc_finish(png_ptr, length);
  1150.       return;
  1151.    }
  1152.  
  1153.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  1154.       /* Should be an error, but we can cope with it */
  1155.       png_warning(png_ptr, "Out of place iCCP chunk");
  1156.  
  1157.    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
  1158.    {
  1159.       png_warning(png_ptr, "Duplicate iCCP chunk");
  1160.       png_crc_finish(png_ptr, length);
  1161.       return;
  1162.    }
  1163.  
  1164. #ifdef PNG_MAX_MALLOC_64K
  1165.    if (length > (png_uint_32)65535L)
  1166.    {
  1167.       png_warning(png_ptr, "iCCP chunk too large to fit in memory");
  1168.       skip = length - (png_uint_32)65535L;
  1169.       length = (png_uint_32)65535L;
  1170.    }
  1171. #endif
  1172.  
  1173.    png_free(png_ptr, png_ptr->chunkdata);
  1174.    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
  1175.    slength = (png_size_t)length;
  1176.    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1177.  
  1178.    if (png_crc_finish(png_ptr, skip))
  1179.    {
  1180.       png_free(png_ptr, png_ptr->chunkdata);
  1181.       png_ptr->chunkdata = NULL;
  1182.       return;
  1183.    }
  1184.  
  1185.    png_ptr->chunkdata[slength] = 0x00;
  1186.  
  1187.    for (profile = png_ptr->chunkdata; *profile; profile++)
  1188.       /* Empty loop to find end of name */ ;
  1189.  
  1190.    ++profile;
  1191.  
  1192.    /* There should be at least one zero (the compression type byte)
  1193.     * following the separator, and we should be on it
  1194.     */
  1195.    if (profile >= png_ptr->chunkdata + slength - 1)
  1196.    {
  1197.       png_free(png_ptr, png_ptr->chunkdata);
  1198.       png_ptr->chunkdata = NULL;
  1199.       png_warning(png_ptr, "Malformed iCCP chunk");
  1200.       return;
  1201.    }
  1202.  
  1203.    /* Compression_type should always be zero */
  1204.    compression_type = *profile++;
  1205.  
  1206.    if (compression_type)
  1207.    {
  1208.       png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
  1209.       compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
  1210.                                  wrote nonzero) */
  1211.    }
  1212.  
  1213.    prefix_length = profile - png_ptr->chunkdata;
  1214.    png_decompress_chunk(png_ptr, compression_type,
  1215.        slength, prefix_length, &data_length);
  1216.  
  1217.    profile_length = data_length - prefix_length;
  1218.  
  1219.    if (prefix_length > data_length || profile_length < 4)
  1220.    {
  1221.       png_free(png_ptr, png_ptr->chunkdata);
  1222.       png_ptr->chunkdata = NULL;
  1223.       png_warning(png_ptr, "Profile size field missing from iCCP chunk");
  1224.       return;
  1225.    }
  1226.  
  1227.    /* Check the profile_size recorded in the first 32 bits of the ICC profile */
  1228.    pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
  1229.    profile_size = ((*(pC    )) << 24) |
  1230.                   ((*(pC + 1)) << 16) |
  1231.                   ((*(pC + 2)) <<  8) |
  1232.                   ((*(pC + 3))      );
  1233.  
  1234.    /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
  1235.     * because profile_size is a 32 bit value.
  1236.     */
  1237.    if (profile_size < profile_length)
  1238.       profile_length = profile_size;
  1239.  
  1240.    /* And the following guarantees that profile_size == profile_length. */
  1241.    if (profile_size > profile_length)
  1242.    {
  1243.       png_free(png_ptr, png_ptr->chunkdata);
  1244.       png_ptr->chunkdata = NULL;
  1245. #ifdef PNG_STDIO_SUPPORTED
  1246.       {
  1247.          char umsg[80];
  1248.  
  1249.          png_snprintf2(umsg, 80,
  1250.              "Ignoring iCCP chunk with declared size = %u "
  1251.               "and actual length = %u",
  1252.               (unsigned int) profile_size,
  1253.               (unsigned int) profile_length);
  1254.          png_warning(png_ptr, umsg);
  1255.       }
  1256. #else
  1257.       png_warning(png_ptr,
  1258.          "Ignoring iCCP chunk with uncompressed size mismatch");
  1259. #endif
  1260.       return;
  1261.    }
  1262.  
  1263.    png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
  1264.        compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
  1265.        profile_size);
  1266.    png_free(png_ptr, png_ptr->chunkdata);
  1267.    png_ptr->chunkdata = NULL;
  1268. }
  1269. #endif /* PNG_READ_iCCP_SUPPORTED */
  1270.  
  1271. #ifdef PNG_READ_sPLT_SUPPORTED
  1272. void /* PRIVATE */
  1273. png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1274. /* Note: this does not properly handle chunks that are > 64K under DOS */
  1275. {
  1276.    png_bytep entry_start;
  1277.    png_sPLT_t new_palette;
  1278. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  1279.    png_sPLT_entryp pp;
  1280. #endif
  1281.    png_uint_32 data_length;
  1282.    int entry_size, i;
  1283.    png_uint_32 skip = 0;
  1284.    png_size_t slength;
  1285.    png_uint_32 dl;
  1286.    png_size_t max_dl;
  1287.  
  1288.    png_debug(1, "in png_handle_sPLT");
  1289.  
  1290. #ifdef PNG_USER_LIMITS_SUPPORTED
  1291.  
  1292.    if (png_ptr->user_chunk_cache_max != 0)
  1293.    {
  1294.       if (png_ptr->user_chunk_cache_max == 1)
  1295.       {
  1296.          png_crc_finish(png_ptr, length);
  1297.          return;
  1298.       }
  1299.  
  1300.       if (--png_ptr->user_chunk_cache_max == 1)
  1301.       {
  1302.          png_warning(png_ptr, "No space in chunk cache for sPLT");
  1303.          png_crc_finish(png_ptr, length);
  1304.          return;
  1305.       }
  1306.    }
  1307. #endif
  1308.  
  1309.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1310.       png_error(png_ptr, "Missing IHDR before sPLT");
  1311.  
  1312.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1313.    {
  1314.       png_warning(png_ptr, "Invalid sPLT after IDAT");
  1315.       png_crc_finish(png_ptr, length);
  1316.       return;
  1317.    }
  1318.  
  1319. #ifdef PNG_MAX_MALLOC_64K
  1320.    if (length > (png_uint_32)65535L)
  1321.    {
  1322.       png_warning(png_ptr, "sPLT chunk too large to fit in memory");
  1323.       skip = length - (png_uint_32)65535L;
  1324.       length = (png_uint_32)65535L;
  1325.    }
  1326. #endif
  1327.  
  1328.    png_free(png_ptr, png_ptr->chunkdata);
  1329.    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
  1330.  
  1331.    /* WARNING: this may break if size_t is less than 32 bits; it is assumed
  1332.     * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
  1333.     * potential breakage point if the types in pngconf.h aren't exactly right.
  1334.     */
  1335.    slength = (png_size_t)length;
  1336.    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1337.  
  1338.    if (png_crc_finish(png_ptr, skip))
  1339.    {
  1340.       png_free(png_ptr, png_ptr->chunkdata);
  1341.       png_ptr->chunkdata = NULL;
  1342.       return;
  1343.    }
  1344.  
  1345.    png_ptr->chunkdata[slength] = 0x00;
  1346.  
  1347.    for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
  1348.        entry_start++)
  1349.       /* Empty loop to find end of name */ ;
  1350.  
  1351.    ++entry_start;
  1352.  
  1353.    /* A sample depth should follow the separator, and we should be on it  */
  1354.    if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
  1355.    {
  1356.       png_free(png_ptr, png_ptr->chunkdata);
  1357.       png_ptr->chunkdata = NULL;
  1358.       png_warning(png_ptr, "malformed sPLT chunk");
  1359.       return;
  1360.    }
  1361.  
  1362.    new_palette.depth = *entry_start++;
  1363.    entry_size = (new_palette.depth == 8 ? 6 : 10);
  1364.    /* This must fit in a png_uint_32 because it is derived from the original
  1365.     * chunk data length (and use 'length', not 'slength' here for clarity -
  1366.     * they are guaranteed to be the same, see the tests above.)
  1367.     */
  1368.    data_length = length - (png_uint_32)(entry_start -
  1369.       (png_bytep)png_ptr->chunkdata);
  1370.  
  1371.    /* Integrity-check the data length */
  1372.    if (data_length % entry_size)
  1373.    {
  1374.       png_free(png_ptr, png_ptr->chunkdata);
  1375.       png_ptr->chunkdata = NULL;
  1376.       png_warning(png_ptr, "sPLT chunk has bad length");
  1377.       return;
  1378.    }
  1379.  
  1380.    dl = (png_int_32)(data_length / entry_size);
  1381.    max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry);
  1382.  
  1383.    if (dl > max_dl)
  1384.    {
  1385.        png_warning(png_ptr, "sPLT chunk too long");
  1386.        return;
  1387.    }
  1388.  
  1389.    new_palette.nentries = (png_int_32)(data_length / entry_size);
  1390.  
  1391.    new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
  1392.        png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
  1393.  
  1394.    if (new_palette.entries == NULL)
  1395.    {
  1396.        png_warning(png_ptr, "sPLT chunk requires too much memory");
  1397.        return;
  1398.    }
  1399.  
  1400. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  1401.    for (i = 0; i < new_palette.nentries; i++)
  1402.    {
  1403.       pp = new_palette.entries + i;
  1404.  
  1405.       if (new_palette.depth == 8)
  1406.       {
  1407.          pp->red = *entry_start++;
  1408.          pp->green = *entry_start++;
  1409.          pp->blue = *entry_start++;
  1410.          pp->alpha = *entry_start++;
  1411.       }
  1412.  
  1413.       else
  1414.       {
  1415.          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
  1416.          pp->green = png_get_uint_16(entry_start); entry_start += 2;
  1417.          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
  1418.          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
  1419.       }
  1420.  
  1421.       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
  1422.    }
  1423. #else
  1424.    pp = new_palette.entries;
  1425.  
  1426.    for (i = 0; i < new_palette.nentries; i++)
  1427.    {
  1428.  
  1429.       if (new_palette.depth == 8)
  1430.       {
  1431.          pp[i].red   = *entry_start++;
  1432.          pp[i].green = *entry_start++;
  1433.          pp[i].blue  = *entry_start++;
  1434.          pp[i].alpha = *entry_start++;
  1435.       }
  1436.  
  1437.       else
  1438.       {
  1439.          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
  1440.          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
  1441.          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
  1442.          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
  1443.       }
  1444.  
  1445.       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
  1446.    }
  1447. #endif
  1448.  
  1449.    /* Discard all chunk data except the name and stash that */
  1450.    new_palette.name = png_ptr->chunkdata;
  1451.  
  1452.    png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
  1453.  
  1454.    png_free(png_ptr, png_ptr->chunkdata);
  1455.    png_ptr->chunkdata = NULL;
  1456.    png_free(png_ptr, new_palette.entries);
  1457. }
  1458. #endif /* PNG_READ_sPLT_SUPPORTED */
  1459.  
  1460. #ifdef PNG_READ_tRNS_SUPPORTED
  1461. void /* PRIVATE */
  1462. png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1463. {
  1464.    png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
  1465.  
  1466.    png_debug(1, "in png_handle_tRNS");
  1467.  
  1468.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1469.       png_error(png_ptr, "Missing IHDR before tRNS");
  1470.  
  1471.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1472.    {
  1473.       png_warning(png_ptr, "Invalid tRNS after IDAT");
  1474.       png_crc_finish(png_ptr, length);
  1475.       return;
  1476.    }
  1477.  
  1478.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  1479.    {
  1480.       png_warning(png_ptr, "Duplicate tRNS chunk");
  1481.       png_crc_finish(png_ptr, length);
  1482.       return;
  1483.    }
  1484.  
  1485.    if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  1486.    {
  1487.       png_byte buf[2];
  1488.  
  1489.       if (length != 2)
  1490.       {
  1491.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  1492.          png_crc_finish(png_ptr, length);
  1493.          return;
  1494.       }
  1495.  
  1496.       png_crc_read(png_ptr, buf, 2);
  1497.       png_ptr->num_trans = 1;
  1498.       png_ptr->trans_color.gray = png_get_uint_16(buf);
  1499.    }
  1500.  
  1501.    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  1502.    {
  1503.       png_byte buf[6];
  1504.  
  1505.       if (length != 6)
  1506.       {
  1507.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  1508.          png_crc_finish(png_ptr, length);
  1509.          return;
  1510.       }
  1511.  
  1512.       png_crc_read(png_ptr, buf, (png_size_t)length);
  1513.       png_ptr->num_trans = 1;
  1514.       png_ptr->trans_color.red = png_get_uint_16(buf);
  1515.       png_ptr->trans_color.green = png_get_uint_16(buf + 2);
  1516.       png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
  1517.    }
  1518.  
  1519.    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1520.    {
  1521.       if (!(png_ptr->mode & PNG_HAVE_PLTE))
  1522.       {
  1523.          /* Should be an error, but we can cope with it. */
  1524.          png_warning(png_ptr, "Missing PLTE before tRNS");
  1525.       }
  1526.  
  1527.       if (length > (png_uint_32)png_ptr->num_palette ||
  1528.           length > PNG_MAX_PALETTE_LENGTH)
  1529.       {
  1530.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  1531.          png_crc_finish(png_ptr, length);
  1532.          return;
  1533.       }
  1534.  
  1535.       if (length == 0)
  1536.       {
  1537.          png_warning(png_ptr, "Zero length tRNS chunk");
  1538.          png_crc_finish(png_ptr, length);
  1539.          return;
  1540.       }
  1541.  
  1542.       png_crc_read(png_ptr, readbuf, (png_size_t)length);
  1543.       png_ptr->num_trans = (png_uint_16)length;
  1544.    }
  1545.  
  1546.    else
  1547.    {
  1548.       png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
  1549.       png_crc_finish(png_ptr, length);
  1550.       return;
  1551.    }
  1552.  
  1553.    if (png_crc_finish(png_ptr, 0))
  1554.    {
  1555.       png_ptr->num_trans = 0;
  1556.       return;
  1557.    }
  1558.  
  1559.    png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
  1560.        &(png_ptr->trans_color));
  1561. }
  1562. #endif
  1563.  
  1564. #ifdef PNG_READ_bKGD_SUPPORTED
  1565. void /* PRIVATE */
  1566. png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1567. {
  1568.    png_size_t truelen;
  1569.    png_byte buf[6];
  1570.  
  1571.    png_debug(1, "in png_handle_bKGD");
  1572.  
  1573.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1574.       png_error(png_ptr, "Missing IHDR before bKGD");
  1575.  
  1576.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1577.    {
  1578.       png_warning(png_ptr, "Invalid bKGD after IDAT");
  1579.       png_crc_finish(png_ptr, length);
  1580.       return;
  1581.    }
  1582.  
  1583.    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  1584.        !(png_ptr->mode & PNG_HAVE_PLTE))
  1585.    {
  1586.       png_warning(png_ptr, "Missing PLTE before bKGD");
  1587.       png_crc_finish(png_ptr, length);
  1588.       return;
  1589.    }
  1590.  
  1591.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
  1592.    {
  1593.       png_warning(png_ptr, "Duplicate bKGD chunk");
  1594.       png_crc_finish(png_ptr, length);
  1595.       return;
  1596.    }
  1597.  
  1598.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1599.       truelen = 1;
  1600.  
  1601.    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1602.       truelen = 6;
  1603.  
  1604.    else
  1605.       truelen = 2;
  1606.  
  1607.    if (length != truelen)
  1608.    {
  1609.       png_warning(png_ptr, "Incorrect bKGD chunk length");
  1610.       png_crc_finish(png_ptr, length);
  1611.       return;
  1612.    }
  1613.  
  1614.    png_crc_read(png_ptr, buf, truelen);
  1615.  
  1616.    if (png_crc_finish(png_ptr, 0))
  1617.       return;
  1618.  
  1619.    /* We convert the index value into RGB components so that we can allow
  1620.     * arbitrary RGB values for background when we have transparency, and
  1621.     * so it is easy to determine the RGB values of the background color
  1622.     * from the info_ptr struct.
  1623.     */
  1624.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1625.    {
  1626.       png_ptr->background.index = buf[0];
  1627.  
  1628.       if (info_ptr && info_ptr->num_palette)
  1629.       {
  1630.          if (buf[0] >= info_ptr->num_palette)
  1631.          {
  1632.             png_warning(png_ptr, "Incorrect bKGD chunk index value");
  1633.             return;
  1634.          }
  1635.  
  1636.          png_ptr->background.red =
  1637.              (png_uint_16)png_ptr->palette[buf[0]].red;
  1638.  
  1639.          png_ptr->background.green =
  1640.              (png_uint_16)png_ptr->palette[buf[0]].green;
  1641.  
  1642.          png_ptr->background.blue =
  1643.              (png_uint_16)png_ptr->palette[buf[0]].blue;
  1644.       }
  1645.    }
  1646.  
  1647.    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
  1648.    {
  1649.       png_ptr->background.red =
  1650.       png_ptr->background.green =
  1651.       png_ptr->background.blue =
  1652.       png_ptr->background.gray = png_get_uint_16(buf);
  1653.    }
  1654.  
  1655.    else
  1656.    {
  1657.       png_ptr->background.red = png_get_uint_16(buf);
  1658.       png_ptr->background.green = png_get_uint_16(buf + 2);
  1659.       png_ptr->background.blue = png_get_uint_16(buf + 4);
  1660.    }
  1661.  
  1662.    png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
  1663. }
  1664. #endif
  1665.  
  1666. #ifdef PNG_READ_hIST_SUPPORTED
  1667. void /* PRIVATE */
  1668. png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1669. {
  1670.    unsigned int num, i;
  1671.    png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
  1672.  
  1673.    png_debug(1, "in png_handle_hIST");
  1674.  
  1675.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1676.       png_error(png_ptr, "Missing IHDR before hIST");
  1677.  
  1678.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1679.    {
  1680.       png_warning(png_ptr, "Invalid hIST after IDAT");
  1681.       png_crc_finish(png_ptr, length);
  1682.       return;
  1683.    }
  1684.  
  1685.    else if (!(png_ptr->mode & PNG_HAVE_PLTE))
  1686.    {
  1687.       png_warning(png_ptr, "Missing PLTE before hIST");
  1688.       png_crc_finish(png_ptr, length);
  1689.       return;
  1690.    }
  1691.  
  1692.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
  1693.    {
  1694.       png_warning(png_ptr, "Duplicate hIST chunk");
  1695.       png_crc_finish(png_ptr, length);
  1696.       return;
  1697.    }
  1698.  
  1699.    num = length / 2 ;
  1700.  
  1701.    if (num != (unsigned int)png_ptr->num_palette || num >
  1702.        (unsigned int)PNG_MAX_PALETTE_LENGTH)
  1703.    {
  1704.       png_warning(png_ptr, "Incorrect hIST chunk length");
  1705.       png_crc_finish(png_ptr, length);
  1706.       return;
  1707.    }
  1708.  
  1709.    for (i = 0; i < num; i++)
  1710.    {
  1711.       png_byte buf[2];
  1712.  
  1713.       png_crc_read(png_ptr, buf, 2);
  1714.       readbuf[i] = png_get_uint_16(buf);
  1715.    }
  1716.  
  1717.    if (png_crc_finish(png_ptr, 0))
  1718.       return;
  1719.  
  1720.    png_set_hIST(png_ptr, info_ptr, readbuf);
  1721. }
  1722. #endif
  1723.  
  1724. #ifdef PNG_READ_pHYs_SUPPORTED
  1725. void /* PRIVATE */
  1726. png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1727. {
  1728.    png_byte buf[9];
  1729.    png_uint_32 res_x, res_y;
  1730.    int unit_type;
  1731.  
  1732.    png_debug(1, "in png_handle_pHYs");
  1733.  
  1734.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1735.       png_error(png_ptr, "Missing IHDR before pHYs");
  1736.  
  1737.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1738.    {
  1739.       png_warning(png_ptr, "Invalid pHYs after IDAT");
  1740.       png_crc_finish(png_ptr, length);
  1741.       return;
  1742.    }
  1743.  
  1744.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  1745.    {
  1746.       png_warning(png_ptr, "Duplicate pHYs chunk");
  1747.       png_crc_finish(png_ptr, length);
  1748.       return;
  1749.    }
  1750.  
  1751.    if (length != 9)
  1752.    {
  1753.       png_warning(png_ptr, "Incorrect pHYs chunk length");
  1754.       png_crc_finish(png_ptr, length);
  1755.       return;
  1756.    }
  1757.  
  1758.    png_crc_read(png_ptr, buf, 9);
  1759.  
  1760.    if (png_crc_finish(png_ptr, 0))
  1761.       return;
  1762.  
  1763.    res_x = png_get_uint_32(buf);
  1764.    res_y = png_get_uint_32(buf + 4);
  1765.    unit_type = buf[8];
  1766.    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
  1767. }
  1768. #endif
  1769.  
  1770. #ifdef PNG_READ_oFFs_SUPPORTED
  1771. void /* PRIVATE */
  1772. png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1773. {
  1774.    png_byte buf[9];
  1775.    png_int_32 offset_x, offset_y;
  1776.    int unit_type;
  1777.  
  1778.    png_debug(1, "in png_handle_oFFs");
  1779.  
  1780.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1781.       png_error(png_ptr, "Missing IHDR before oFFs");
  1782.  
  1783.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1784.    {
  1785.       png_warning(png_ptr, "Invalid oFFs after IDAT");
  1786.       png_crc_finish(png_ptr, length);
  1787.       return;
  1788.    }
  1789.  
  1790.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  1791.    {
  1792.       png_warning(png_ptr, "Duplicate oFFs chunk");
  1793.       png_crc_finish(png_ptr, length);
  1794.       return;
  1795.    }
  1796.  
  1797.    if (length != 9)
  1798.    {
  1799.       png_warning(png_ptr, "Incorrect oFFs chunk length");
  1800.       png_crc_finish(png_ptr, length);
  1801.       return;
  1802.    }
  1803.  
  1804.    png_crc_read(png_ptr, buf, 9);
  1805.  
  1806.    if (png_crc_finish(png_ptr, 0))
  1807.       return;
  1808.  
  1809.    offset_x = png_get_int_32(buf);
  1810.    offset_y = png_get_int_32(buf + 4);
  1811.    unit_type = buf[8];
  1812.    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
  1813. }
  1814. #endif
  1815.  
  1816. #ifdef PNG_READ_pCAL_SUPPORTED
  1817. /* Read the pCAL chunk (described in the PNG Extensions document) */
  1818. void /* PRIVATE */
  1819. png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1820. {
  1821.    png_int_32 X0, X1;
  1822.    png_byte type, nparams;
  1823.    png_charp buf, units, endptr;
  1824.    png_charpp params;
  1825.    png_size_t slength;
  1826.    int i;
  1827.  
  1828.    png_debug(1, "in png_handle_pCAL");
  1829.  
  1830.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1831.       png_error(png_ptr, "Missing IHDR before pCAL");
  1832.  
  1833.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1834.    {
  1835.       png_warning(png_ptr, "Invalid pCAL after IDAT");
  1836.       png_crc_finish(png_ptr, length);
  1837.       return;
  1838.    }
  1839.  
  1840.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
  1841.    {
  1842.       png_warning(png_ptr, "Duplicate pCAL chunk");
  1843.       png_crc_finish(png_ptr, length);
  1844.       return;
  1845.    }
  1846.  
  1847.    png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
  1848.        length + 1);
  1849.    png_free(png_ptr, png_ptr->chunkdata);
  1850.    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  1851.  
  1852.    if (png_ptr->chunkdata == NULL)
  1853.    {
  1854.       png_warning(png_ptr, "No memory for pCAL purpose");
  1855.       return;
  1856.    }
  1857.  
  1858.    slength = (png_size_t)length;
  1859.    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1860.  
  1861.    if (png_crc_finish(png_ptr, 0))
  1862.    {
  1863.       png_free(png_ptr, png_ptr->chunkdata);
  1864.       png_ptr->chunkdata = NULL;
  1865.       return;
  1866.    }
  1867.  
  1868.    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
  1869.  
  1870.    png_debug(3, "Finding end of pCAL purpose string");
  1871.    for (buf = png_ptr->chunkdata; *buf; buf++)
  1872.       /* Empty loop */ ;
  1873.  
  1874.    endptr = png_ptr->chunkdata + slength;
  1875.  
  1876.    /* We need to have at least 12 bytes after the purpose string
  1877.     * in order to get the parameter information.
  1878.     */
  1879.    if (endptr <= buf + 12)
  1880.    {
  1881.       png_warning(png_ptr, "Invalid pCAL data");
  1882.       png_free(png_ptr, png_ptr->chunkdata);
  1883.       png_ptr->chunkdata = NULL;
  1884.       return;
  1885.    }
  1886.  
  1887.    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
  1888.    X0 = png_get_int_32((png_bytep)buf+1);
  1889.    X1 = png_get_int_32((png_bytep)buf+5);
  1890.    type = buf[9];
  1891.    nparams = buf[10];
  1892.    units = buf + 11;
  1893.  
  1894.    png_debug(3, "Checking pCAL equation type and number of parameters");
  1895.    /* Check that we have the right number of parameters for known
  1896.     * equation types.
  1897.     */
  1898.    if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
  1899.        (type == PNG_EQUATION_BASE_E && nparams != 3) ||
  1900.        (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
  1901.        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
  1902.    {
  1903.       png_warning(png_ptr, "Invalid pCAL parameters for equation type");
  1904.       png_free(png_ptr, png_ptr->chunkdata);
  1905.       png_ptr->chunkdata = NULL;
  1906.       return;
  1907.    }
  1908.  
  1909.    else if (type >= PNG_EQUATION_LAST)
  1910.    {
  1911.       png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
  1912.    }
  1913.  
  1914.    for (buf = units; *buf; buf++)
  1915.       /* Empty loop to move past the units string. */ ;
  1916.  
  1917.    png_debug(3, "Allocating pCAL parameters array");
  1918.  
  1919.    params = (png_charpp)png_malloc_warn(png_ptr,
  1920.        (png_size_t)(nparams * png_sizeof(png_charp)));
  1921.  
  1922.    if (params == NULL)
  1923.    {
  1924.       png_free(png_ptr, png_ptr->chunkdata);
  1925.       png_ptr->chunkdata = NULL;
  1926.       png_warning(png_ptr, "No memory for pCAL params");
  1927.       return;
  1928.    }
  1929.  
  1930.    /* Get pointers to the start of each parameter string. */
  1931.    for (i = 0; i < (int)nparams; i++)
  1932.    {
  1933.       buf++; /* Skip the null string terminator from previous parameter. */
  1934.  
  1935.       png_debug1(3, "Reading pCAL parameter %d", i);
  1936.  
  1937.       for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
  1938.          /* Empty loop to move past each parameter string */ ;
  1939.  
  1940.       /* Make sure we haven't run out of data yet */
  1941.       if (buf > endptr)
  1942.       {
  1943.          png_warning(png_ptr, "Invalid pCAL data");
  1944.          png_free(png_ptr, png_ptr->chunkdata);
  1945.          png_ptr->chunkdata = NULL;
  1946.          png_free(png_ptr, params);
  1947.          return;
  1948.       }
  1949.    }
  1950.  
  1951.    png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
  1952.       units, params);
  1953.  
  1954.    png_free(png_ptr, png_ptr->chunkdata);
  1955.    png_ptr->chunkdata = NULL;
  1956.    png_free(png_ptr, params);
  1957. }
  1958. #endif
  1959.  
  1960. #ifdef PNG_READ_sCAL_SUPPORTED
  1961. /* Read the sCAL chunk */
  1962. void /* PRIVATE */
  1963. png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1964. {
  1965.    png_size_t slength, i;
  1966.    int state;
  1967.  
  1968.    png_debug(1, "in png_handle_sCAL");
  1969.  
  1970.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1971.       png_error(png_ptr, "Missing IHDR before sCAL");
  1972.  
  1973.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1974.    {
  1975.       png_warning(png_ptr, "Invalid sCAL after IDAT");
  1976.       png_crc_finish(png_ptr, length);
  1977.       return;
  1978.    }
  1979.  
  1980.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
  1981.    {
  1982.       png_warning(png_ptr, "Duplicate sCAL chunk");
  1983.       png_crc_finish(png_ptr, length);
  1984.       return;
  1985.    }
  1986.  
  1987.    png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
  1988.       length + 1);
  1989.  
  1990.    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  1991.  
  1992.    if (png_ptr->chunkdata == NULL)
  1993.    {
  1994.       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
  1995.       png_crc_finish(png_ptr, length);
  1996.       return;
  1997.    }
  1998.  
  1999.    slength = (png_size_t)length;
  2000.    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  2001.    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
  2002.  
  2003.    if (png_crc_finish(png_ptr, 0))
  2004.    {
  2005.       png_free(png_ptr, png_ptr->chunkdata);
  2006.       png_ptr->chunkdata = NULL;
  2007.       return;
  2008.    }
  2009.  
  2010.    /* Validate the unit. */
  2011.    if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2)
  2012.    {
  2013.       png_warning(png_ptr, "Invalid sCAL ignored: invalid unit");
  2014.       png_free(png_ptr, png_ptr->chunkdata);
  2015.       png_ptr->chunkdata = NULL;
  2016.       return;
  2017.    }
  2018.  
  2019.    /* Validate the ASCII numbers, need two ASCII numbers separated by
  2020.     * a '\0' and they need to fit exactly in the chunk data.
  2021.     */
  2022.    i = 0;
  2023.    state = 0;
  2024.  
  2025.    if (png_ptr->chunkdata[1] == 45 /* negative width */ ||
  2026.        !png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
  2027.        i >= slength || png_ptr->chunkdata[i++] != 0)
  2028.       png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format");
  2029.  
  2030.    else
  2031.    {
  2032.       png_size_t heighti = i;
  2033.  
  2034.       if (png_ptr->chunkdata[i] == 45 /* negative height */ ||
  2035.           !png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
  2036.           i != slength)
  2037.          png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format");
  2038.  
  2039.       else
  2040.          /* This is the (only) success case. */
  2041.          png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0],
  2042.             png_ptr->chunkdata+1, png_ptr->chunkdata+heighti);
  2043.    }
  2044.  
  2045.    /* Clean up - just free the temporarily allocated buffer. */
  2046.    png_free(png_ptr, png_ptr->chunkdata);
  2047.    png_ptr->chunkdata = NULL;
  2048. }
  2049. #endif
  2050.  
  2051. #ifdef PNG_READ_tIME_SUPPORTED
  2052. void /* PRIVATE */
  2053. png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  2054. {
  2055.    png_byte buf[7];
  2056.    png_time mod_time;
  2057.  
  2058.    png_debug(1, "in png_handle_tIME");
  2059.  
  2060.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  2061.       png_error(png_ptr, "Out of place tIME chunk");
  2062.  
  2063.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
  2064.    {
  2065.       png_warning(png_ptr, "Duplicate tIME chunk");
  2066.       png_crc_finish(png_ptr, length);
  2067.       return;
  2068.    }
  2069.  
  2070.    if (png_ptr->mode & PNG_HAVE_IDAT)
  2071.       png_ptr->mode |= PNG_AFTER_IDAT;
  2072.  
  2073.    if (length != 7)
  2074.    {
  2075.       png_warning(png_ptr, "Incorrect tIME chunk length");
  2076.       png_crc_finish(png_ptr, length);
  2077.       return;
  2078.    }
  2079.  
  2080.    png_crc_read(png_ptr, buf, 7);
  2081.  
  2082.    if (png_crc_finish(png_ptr, 0))
  2083.       return;
  2084.  
  2085.    mod_time.second = buf[6];
  2086.    mod_time.minute = buf[5];
  2087.    mod_time.hour = buf[4];
  2088.    mod_time.day = buf[3];
  2089.    mod_time.month = buf[2];
  2090.    mod_time.year = png_get_uint_16(buf);
  2091.  
  2092.    png_set_tIME(png_ptr, info_ptr, &mod_time);
  2093. }
  2094. #endif
  2095.  
  2096. #ifdef PNG_READ_tEXt_SUPPORTED
  2097. /* Note: this does not properly handle chunks that are > 64K under DOS */
  2098. void /* PRIVATE */
  2099. png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  2100. {
  2101.    png_textp text_ptr;
  2102.    png_charp key;
  2103.    png_charp text;
  2104.    png_uint_32 skip = 0;
  2105.    png_size_t slength;
  2106.    int ret;
  2107.  
  2108.    png_debug(1, "in png_handle_tEXt");
  2109.  
  2110. #ifdef PNG_USER_LIMITS_SUPPORTED
  2111.    if (png_ptr->user_chunk_cache_max != 0)
  2112.    {
  2113.       if (png_ptr->user_chunk_cache_max == 1)
  2114.       {
  2115.          png_crc_finish(png_ptr, length);
  2116.          return;
  2117.       }
  2118.  
  2119.       if (--png_ptr->user_chunk_cache_max == 1)
  2120.       {
  2121.          png_warning(png_ptr, "No space in chunk cache for tEXt");
  2122.          png_crc_finish(png_ptr, length);
  2123.          return;
  2124.       }
  2125.    }
  2126. #endif
  2127.  
  2128.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  2129.       png_error(png_ptr, "Missing IHDR before tEXt");
  2130.  
  2131.    if (png_ptr->mode & PNG_HAVE_IDAT)
  2132.       png_ptr->mode |= PNG_AFTER_IDAT;
  2133.  
  2134. #ifdef PNG_MAX_MALLOC_64K
  2135.    if (length > (png_uint_32)65535L)
  2136.    {
  2137.       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  2138.       skip = length - (png_uint_32)65535L;
  2139.       length = (png_uint_32)65535L;
  2140.    }
  2141. #endif
  2142.  
  2143.    png_free(png_ptr, png_ptr->chunkdata);
  2144.  
  2145.    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  2146.  
  2147.    if (png_ptr->chunkdata == NULL)
  2148.    {
  2149.      png_warning(png_ptr, "No memory to process text chunk");
  2150.      return;
  2151.    }
  2152.  
  2153.    slength = (png_size_t)length;
  2154.    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  2155.  
  2156.    if (png_crc_finish(png_ptr, skip))
  2157.    {
  2158.       png_free(png_ptr, png_ptr->chunkdata);
  2159.       png_ptr->chunkdata = NULL;
  2160.       return;
  2161.    }
  2162.  
  2163.    key = png_ptr->chunkdata;
  2164.  
  2165.    key[slength] = 0x00;
  2166.  
  2167.    for (text = key; *text; text++)
  2168.       /* Empty loop to find end of key */ ;
  2169.  
  2170.    if (text != key + slength)
  2171.       text++;
  2172.  
  2173.    text_ptr = (png_textp)png_malloc_warn(png_ptr,
  2174.        png_sizeof(png_text));
  2175.  
  2176.    if (text_ptr == NULL)
  2177.    {
  2178.       png_warning(png_ptr, "Not enough memory to process text chunk");
  2179.       png_free(png_ptr, png_ptr->chunkdata);
  2180.       png_ptr->chunkdata = NULL;
  2181.       return;
  2182.    }
  2183.  
  2184.    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  2185.    text_ptr->key = key;
  2186.    text_ptr->lang = NULL;
  2187.    text_ptr->lang_key = NULL;
  2188.    text_ptr->itxt_length = 0;
  2189.    text_ptr->text = text;
  2190.    text_ptr->text_length = png_strlen(text);
  2191.  
  2192.    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  2193.  
  2194.    png_free(png_ptr, png_ptr->chunkdata);
  2195.    png_ptr->chunkdata = NULL;
  2196.    png_free(png_ptr, text_ptr);
  2197.  
  2198.    if (ret)
  2199.       png_warning(png_ptr, "Insufficient memory to process text chunk");
  2200. }
  2201. #endif
  2202.  
  2203. #ifdef PNG_READ_zTXt_SUPPORTED
  2204. /* Note: this does not correctly handle chunks that are > 64K under DOS */
  2205. void /* PRIVATE */
  2206. png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  2207. {
  2208.    png_textp text_ptr;
  2209.    png_charp text;
  2210.    int comp_type;
  2211.    int ret;
  2212.    png_size_t slength, prefix_len, data_len;
  2213.  
  2214.    png_debug(1, "in png_handle_zTXt");
  2215.  
  2216. #ifdef PNG_USER_LIMITS_SUPPORTED
  2217.    if (png_ptr->user_chunk_cache_max != 0)
  2218.    {
  2219.       if (png_ptr->user_chunk_cache_max == 1)
  2220.       {
  2221.          png_crc_finish(png_ptr, length);
  2222.          return;
  2223.       }
  2224.  
  2225.       if (--png_ptr->user_chunk_cache_max == 1)
  2226.       {
  2227.          png_warning(png_ptr, "No space in chunk cache for zTXt");
  2228.          png_crc_finish(png_ptr, length);
  2229.          return;
  2230.       }
  2231.    }
  2232. #endif
  2233.  
  2234.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  2235.       png_error(png_ptr, "Missing IHDR before zTXt");
  2236.  
  2237.    if (png_ptr->mode & PNG_HAVE_IDAT)
  2238.       png_ptr->mode |= PNG_AFTER_IDAT;
  2239.  
  2240. #ifdef PNG_MAX_MALLOC_64K
  2241.    /* We will no doubt have problems with chunks even half this size, but
  2242.     * there is no hard and fast rule to tell us where to stop.
  2243.     */
  2244.    if (length > (png_uint_32)65535L)
  2245.    {
  2246.       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
  2247.       png_crc_finish(png_ptr, length);
  2248.       return;
  2249.    }
  2250. #endif
  2251.  
  2252.    png_free(png_ptr, png_ptr->chunkdata);
  2253.    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  2254.  
  2255.    if (png_ptr->chunkdata == NULL)
  2256.    {
  2257.       png_warning(png_ptr, "Out of memory processing zTXt chunk");
  2258.       return;
  2259.    }
  2260.  
  2261.    slength = (png_size_t)length;
  2262.    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  2263.  
  2264.    if (png_crc_finish(png_ptr, 0))
  2265.    {
  2266.       png_free(png_ptr, png_ptr->chunkdata);
  2267.       png_ptr->chunkdata = NULL;
  2268.       return;
  2269.    }
  2270.  
  2271.    png_ptr->chunkdata[slength] = 0x00;
  2272.  
  2273.    for (text = png_ptr->chunkdata; *text; text++)
  2274.       /* Empty loop */ ;
  2275.  
  2276.    /* zTXt must have some text after the chunkdataword */
  2277.    if (text >= png_ptr->chunkdata + slength - 2)
  2278.    {
  2279.       png_warning(png_ptr, "Truncated zTXt chunk");
  2280.       png_free(png_ptr, png_ptr->chunkdata);
  2281.       png_ptr->chunkdata = NULL;
  2282.       return;
  2283.    }
  2284.  
  2285.    else
  2286.    {
  2287.        comp_type = *(++text);
  2288.  
  2289.        if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
  2290.        {
  2291.           png_warning(png_ptr, "Unknown compression type in zTXt chunk");
  2292.           comp_type = PNG_TEXT_COMPRESSION_zTXt;
  2293.        }
  2294.  
  2295.        text++;        /* Skip the compression_method byte */
  2296.    }
  2297.  
  2298.    prefix_len = text - png_ptr->chunkdata;
  2299.  
  2300.    png_decompress_chunk(png_ptr, comp_type,
  2301.        (png_size_t)length, prefix_len, &data_len);
  2302.  
  2303.    text_ptr = (png_textp)png_malloc_warn(png_ptr,
  2304.        png_sizeof(png_text));
  2305.  
  2306.    if (text_ptr == NULL)
  2307.    {
  2308.       png_warning(png_ptr, "Not enough memory to process zTXt chunk");
  2309.       png_free(png_ptr, png_ptr->chunkdata);
  2310.       png_ptr->chunkdata = NULL;
  2311.       return;
  2312.    }
  2313.  
  2314.    text_ptr->compression = comp_type;
  2315.    text_ptr->key = png_ptr->chunkdata;
  2316.    text_ptr->lang = NULL;
  2317.    text_ptr->lang_key = NULL;
  2318.    text_ptr->itxt_length = 0;
  2319.    text_ptr->text = png_ptr->chunkdata + prefix_len;
  2320.    text_ptr->text_length = data_len;
  2321.  
  2322.    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  2323.  
  2324.    png_free(png_ptr, text_ptr);
  2325.    png_free(png_ptr, png_ptr->chunkdata);
  2326.    png_ptr->chunkdata = NULL;
  2327.  
  2328.    if (ret)
  2329.       png_error(png_ptr, "Insufficient memory to store zTXt chunk");
  2330. }
  2331. #endif
  2332.  
  2333. #ifdef PNG_READ_iTXt_SUPPORTED
  2334. /* Note: this does not correctly handle chunks that are > 64K under DOS */
  2335. void /* PRIVATE */
  2336. png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  2337. {
  2338.    png_textp text_ptr;
  2339.    png_charp key, lang, text, lang_key;
  2340.    int comp_flag;
  2341.    int comp_type = 0;
  2342.    int ret;
  2343.    png_size_t slength, prefix_len, data_len;
  2344.  
  2345.    png_debug(1, "in png_handle_iTXt");
  2346.  
  2347. #ifdef PNG_USER_LIMITS_SUPPORTED
  2348.    if (png_ptr->user_chunk_cache_max != 0)
  2349.    {
  2350.       if (png_ptr->user_chunk_cache_max == 1)
  2351.       {
  2352.          png_crc_finish(png_ptr, length);
  2353.          return;
  2354.       }
  2355.  
  2356.       if (--png_ptr->user_chunk_cache_max == 1)
  2357.       {
  2358.          png_warning(png_ptr, "No space in chunk cache for iTXt");
  2359.          png_crc_finish(png_ptr, length);
  2360.          return;
  2361.       }
  2362.    }
  2363. #endif
  2364.  
  2365.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  2366.       png_error(png_ptr, "Missing IHDR before iTXt");
  2367.  
  2368.    if (png_ptr->mode & PNG_HAVE_IDAT)
  2369.       png_ptr->mode |= PNG_AFTER_IDAT;
  2370.  
  2371. #ifdef PNG_MAX_MALLOC_64K
  2372.    /* We will no doubt have problems with chunks even half this size, but
  2373.     * there is no hard and fast rule to tell us where to stop.
  2374.     */
  2375.    if (length > (png_uint_32)65535L)
  2376.    {
  2377.       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
  2378.       png_crc_finish(png_ptr, length);
  2379.       return;
  2380.    }
  2381. #endif
  2382.  
  2383.    png_free(png_ptr, png_ptr->chunkdata);
  2384.    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  2385.  
  2386.    if (png_ptr->chunkdata == NULL)
  2387.    {
  2388.       png_warning(png_ptr, "No memory to process iTXt chunk");
  2389.       return;
  2390.    }
  2391.  
  2392.    slength = (png_size_t)length;
  2393.    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  2394.  
  2395.    if (png_crc_finish(png_ptr, 0))
  2396.    {
  2397.       png_free(png_ptr, png_ptr->chunkdata);
  2398.       png_ptr->chunkdata = NULL;
  2399.       return;
  2400.    }
  2401.  
  2402.    png_ptr->chunkdata[slength] = 0x00;
  2403.  
  2404.    for (lang = png_ptr->chunkdata; *lang; lang++)
  2405.       /* Empty loop */ ;
  2406.  
  2407.    lang++;        /* Skip NUL separator */
  2408.  
  2409.    /* iTXt must have a language tag (possibly empty), two compression bytes,
  2410.     * translated keyword (possibly empty), and possibly some text after the
  2411.     * keyword
  2412.     */
  2413.  
  2414.    if (lang >= png_ptr->chunkdata + slength - 3)
  2415.    {
  2416.       png_warning(png_ptr, "Truncated iTXt chunk");
  2417.       png_free(png_ptr, png_ptr->chunkdata);
  2418.       png_ptr->chunkdata = NULL;
  2419.       return;
  2420.    }
  2421.  
  2422.    else
  2423.    {
  2424.       comp_flag = *lang++;
  2425.       comp_type = *lang++;
  2426.    }
  2427.  
  2428.    for (lang_key = lang; *lang_key; lang_key++)
  2429.       /* Empty loop */ ;
  2430.  
  2431.    lang_key++;        /* Skip NUL separator */
  2432.  
  2433.    if (lang_key >= png_ptr->chunkdata + slength)
  2434.    {
  2435.       png_warning(png_ptr, "Truncated iTXt chunk");
  2436.       png_free(png_ptr, png_ptr->chunkdata);
  2437.       png_ptr->chunkdata = NULL;
  2438.       return;
  2439.    }
  2440.  
  2441.    for (text = lang_key; *text; text++)
  2442.       /* Empty loop */ ;
  2443.  
  2444.    text++;        /* Skip NUL separator */
  2445.  
  2446.    if (text >= png_ptr->chunkdata + slength)
  2447.    {
  2448.       png_warning(png_ptr, "Malformed iTXt chunk");
  2449.       png_free(png_ptr, png_ptr->chunkdata);
  2450.       png_ptr->chunkdata = NULL;
  2451.       return;
  2452.    }
  2453.  
  2454.    prefix_len = text - png_ptr->chunkdata;
  2455.  
  2456.    key=png_ptr->chunkdata;
  2457.  
  2458.    if (comp_flag)
  2459.       png_decompress_chunk(png_ptr, comp_type,
  2460.           (size_t)length, prefix_len, &data_len);
  2461.  
  2462.    else
  2463.       data_len = png_strlen(png_ptr->chunkdata + prefix_len);
  2464.  
  2465.    text_ptr = (png_textp)png_malloc_warn(png_ptr,
  2466.        png_sizeof(png_text));
  2467.  
  2468.    if (text_ptr == NULL)
  2469.    {
  2470.       png_warning(png_ptr, "Not enough memory to process iTXt chunk");
  2471.       png_free(png_ptr, png_ptr->chunkdata);
  2472.       png_ptr->chunkdata = NULL;
  2473.       return;
  2474.    }
  2475.  
  2476.    text_ptr->compression = (int)comp_flag + 1;
  2477.    text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
  2478.    text_ptr->lang = png_ptr->chunkdata + (lang - key);
  2479.    text_ptr->itxt_length = data_len;
  2480.    text_ptr->text_length = 0;
  2481.    text_ptr->key = png_ptr->chunkdata;
  2482.    text_ptr->text = png_ptr->chunkdata + prefix_len;
  2483.  
  2484.    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  2485.  
  2486.    png_free(png_ptr, text_ptr);
  2487.    png_free(png_ptr, png_ptr->chunkdata);
  2488.    png_ptr->chunkdata = NULL;
  2489.  
  2490.    if (ret)
  2491.       png_error(png_ptr, "Insufficient memory to store iTXt chunk");
  2492. }
  2493. #endif
  2494.  
  2495. /* This function is called when we haven't found a handler for a
  2496.  * chunk.  If there isn't a problem with the chunk itself (ie bad
  2497.  * chunk name, CRC, or a critical chunk), the chunk is silently ignored
  2498.  * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
  2499.  * case it will be saved away to be written out later.
  2500.  */
  2501. void /* PRIVATE */
  2502. png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  2503. {
  2504.    png_uint_32 skip = 0;
  2505.  
  2506.    png_debug(1, "in png_handle_unknown");
  2507.  
  2508. #ifdef PNG_USER_LIMITS_SUPPORTED
  2509.    if (png_ptr->user_chunk_cache_max != 0)
  2510.    {
  2511.       if (png_ptr->user_chunk_cache_max == 1)
  2512.       {
  2513.          png_crc_finish(png_ptr, length);
  2514.          return;
  2515.       }
  2516.  
  2517.       if (--png_ptr->user_chunk_cache_max == 1)
  2518.       {
  2519.          png_warning(png_ptr, "No space in chunk cache for unknown chunk");
  2520.          png_crc_finish(png_ptr, length);
  2521.          return;
  2522.       }
  2523.    }
  2524. #endif
  2525.  
  2526.    if (png_ptr->mode & PNG_HAVE_IDAT)
  2527.    {
  2528.       PNG_IDAT;
  2529.  
  2530.       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
  2531.          png_ptr->mode |= PNG_AFTER_IDAT;
  2532.    }
  2533.  
  2534.    if (!(png_ptr->chunk_name[0] & 0x20))
  2535.    {
  2536. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  2537.       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  2538.           PNG_HANDLE_CHUNK_ALWAYS
  2539. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  2540.           && png_ptr->read_user_chunk_fn == NULL
  2541. #endif
  2542.           )
  2543. #endif
  2544.          png_chunk_error(png_ptr, "unknown critical chunk");
  2545.    }
  2546.  
  2547. #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  2548.    if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
  2549. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  2550.        || (png_ptr->read_user_chunk_fn != NULL)
  2551. #endif
  2552.        )
  2553.    {
  2554. #ifdef PNG_MAX_MALLOC_64K
  2555.       if (length > (png_uint_32)65535L)
  2556.       {
  2557.          png_warning(png_ptr, "unknown chunk too large to fit in memory");
  2558.          skip = length - (png_uint_32)65535L;
  2559.          length = (png_uint_32)65535L;
  2560.       }
  2561. #endif
  2562.  
  2563.       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
  2564.           (png_charp)png_ptr->chunk_name,
  2565.           png_sizeof(png_ptr->unknown_chunk.name));
  2566.  
  2567.       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
  2568.           = '\0';
  2569.  
  2570.       png_ptr->unknown_chunk.size = (png_size_t)length;
  2571.  
  2572.       if (length == 0)
  2573.          png_ptr->unknown_chunk.data = NULL;
  2574.  
  2575.       else
  2576.       {
  2577.          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
  2578.          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
  2579.       }
  2580.  
  2581. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  2582.       if (png_ptr->read_user_chunk_fn != NULL)
  2583.       {
  2584.          /* Callback to user unknown chunk handler */
  2585.          int ret;
  2586.  
  2587.          ret = (*(png_ptr->read_user_chunk_fn))
  2588.              (png_ptr, &png_ptr->unknown_chunk);
  2589.  
  2590.          if (ret < 0)
  2591.             png_chunk_error(png_ptr, "error in user chunk");
  2592.  
  2593.          if (ret == 0)
  2594.          {
  2595.             if (!(png_ptr->chunk_name[0] & 0x20))
  2596.             {
  2597. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  2598.                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  2599.                    PNG_HANDLE_CHUNK_ALWAYS)
  2600. #endif
  2601.                   png_chunk_error(png_ptr, "unknown critical chunk");
  2602.             }
  2603.  
  2604.             png_set_unknown_chunks(png_ptr, info_ptr,
  2605.                 &png_ptr->unknown_chunk, 1);
  2606.          }
  2607.       }
  2608.  
  2609.       else
  2610. #endif
  2611.          png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
  2612.  
  2613.       png_free(png_ptr, png_ptr->unknown_chunk.data);
  2614.       png_ptr->unknown_chunk.data = NULL;
  2615.    }
  2616.  
  2617.    else
  2618. #endif
  2619.       skip = length;
  2620.  
  2621.    png_crc_finish(png_ptr, skip);
  2622.  
  2623. #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
  2624.    PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
  2625. #endif
  2626. }
  2627.  
  2628. /* This function is called to verify that a chunk name is valid.
  2629.  * This function can't have the "critical chunk check" incorporated
  2630.  * into it, since in the future we will need to be able to call user
  2631.  * functions to handle unknown critical chunks after we check that
  2632.  * the chunk name itself is valid.
  2633.  */
  2634.  
  2635. #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
  2636.  
  2637. void /* PRIVATE */
  2638. png_check_chunk_name(png_structp png_ptr, png_const_bytep chunk_name)
  2639. {
  2640.    png_debug(1, "in png_check_chunk_name");
  2641.    if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
  2642.        isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
  2643.    {
  2644.       png_chunk_error(png_ptr, "invalid chunk type");
  2645.    }
  2646. }
  2647.  
  2648. /* Combines the row recently read in with the existing pixels in the
  2649.  * row.  This routine takes care of alpha and transparency if requested.
  2650.  * This routine also handles the two methods of progressive display
  2651.  * of interlaced images, depending on the mask value.
  2652.  * The mask value describes which pixels are to be combined with
  2653.  * the row.  The pattern always repeats every 8 pixels, so just 8
  2654.  * bits are needed.  A one indicates the pixel is to be combined,
  2655.  * a zero indicates the pixel is to be skipped.  This is in addition
  2656.  * to any alpha or transparency value associated with the pixel.  If
  2657.  * you want all pixels to be combined, pass 0xff (255) in mask.
  2658.  */
  2659.  
  2660. void /* PRIVATE */
  2661. png_combine_row(png_structp png_ptr, png_bytep row, int mask)
  2662. {
  2663.    png_debug(1, "in png_combine_row");
  2664.  
  2665.    if (mask == 0xff)
  2666.    {
  2667.       png_memcpy(row, png_ptr->row_buf + 1,
  2668.           PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
  2669.    }
  2670.  
  2671.    else
  2672.    {
  2673.       switch (png_ptr->row_info.pixel_depth)
  2674.       {
  2675.          case 1:
  2676.          {
  2677.             png_bytep sp = png_ptr->row_buf + 1;
  2678.             png_bytep dp = row;
  2679.             int s_inc, s_start, s_end;
  2680.             int m = 0x80;
  2681.             int shift;
  2682.             png_uint_32 i;
  2683.             png_uint_32 row_width = png_ptr->width;
  2684.  
  2685. #ifdef PNG_READ_PACKSWAP_SUPPORTED
  2686.             if (png_ptr->transformations & PNG_PACKSWAP)
  2687.             {
  2688.                 s_start = 0;
  2689.                 s_end = 7;
  2690.                 s_inc = 1;
  2691.             }
  2692.  
  2693.             else
  2694. #endif
  2695.             {
  2696.                 s_start = 7;
  2697.                 s_end = 0;
  2698.                 s_inc = -1;
  2699.             }
  2700.  
  2701.             shift = s_start;
  2702.  
  2703.             for (i = 0; i < row_width; i++)
  2704.             {
  2705.                if (m & mask)
  2706.                {
  2707.                   int value;
  2708.  
  2709.                   value = (*sp >> shift) & 0x01;
  2710.                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  2711.                   *dp |= (png_byte)(value << shift);
  2712.                }
  2713.  
  2714.                if (shift == s_end)
  2715.                {
  2716.                   shift = s_start;
  2717.                   sp++;
  2718.                   dp++;
  2719.                }
  2720.  
  2721.                else
  2722.                   shift += s_inc;
  2723.  
  2724.                if (m == 1)
  2725.                   m = 0x80;
  2726.  
  2727.                else
  2728.                   m >>= 1;
  2729.             }
  2730.             break;
  2731.          }
  2732.  
  2733.          case 2:
  2734.          {
  2735.             png_bytep sp = png_ptr->row_buf + 1;
  2736.             png_bytep dp = row;
  2737.             int s_start, s_end, s_inc;
  2738.             int m = 0x80;
  2739.             int shift;
  2740.             png_uint_32 i;
  2741.             png_uint_32 row_width = png_ptr->width;
  2742.             int value;
  2743.  
  2744. #ifdef PNG_READ_PACKSWAP_SUPPORTED
  2745.             if (png_ptr->transformations & PNG_PACKSWAP)
  2746.             {
  2747.                s_start = 0;
  2748.                s_end = 6;
  2749.                s_inc = 2;
  2750.             }
  2751.  
  2752.             else
  2753. #endif
  2754.             {
  2755.                s_start = 6;
  2756.                s_end = 0;
  2757.                s_inc = -2;
  2758.             }
  2759.  
  2760.             shift = s_start;
  2761.  
  2762.             for (i = 0; i < row_width; i++)
  2763.             {
  2764.                if (m & mask)
  2765.                {
  2766.                   value = (*sp >> shift) & 0x03;
  2767.                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  2768.                   *dp |= (png_byte)(value << shift);
  2769.                }
  2770.  
  2771.                if (shift == s_end)
  2772.                {
  2773.                   shift = s_start;
  2774.                   sp++;
  2775.                   dp++;
  2776.                }
  2777.  
  2778.                else
  2779.                   shift += s_inc;
  2780.  
  2781.                if (m == 1)
  2782.                   m = 0x80;
  2783.  
  2784.                else
  2785.                   m >>= 1;
  2786.             }
  2787.             break;
  2788.          }
  2789.  
  2790.          case 4:
  2791.          {
  2792.             png_bytep sp = png_ptr->row_buf + 1;
  2793.             png_bytep dp = row;
  2794.             int s_start, s_end, s_inc;
  2795.             int m = 0x80;
  2796.             int shift;
  2797.             png_uint_32 i;
  2798.             png_uint_32 row_width = png_ptr->width;
  2799.             int value;
  2800.  
  2801. #ifdef PNG_READ_PACKSWAP_SUPPORTED
  2802.             if (png_ptr->transformations & PNG_PACKSWAP)
  2803.             {
  2804.                s_start = 0;
  2805.                s_end = 4;
  2806.                s_inc = 4;
  2807.             }
  2808.  
  2809.             else
  2810. #endif
  2811.             {
  2812.                s_start = 4;
  2813.                s_end = 0;
  2814.                s_inc = -4;
  2815.             }
  2816.             shift = s_start;
  2817.  
  2818.             for (i = 0; i < row_width; i++)
  2819.             {
  2820.                if (m & mask)
  2821.                {
  2822.                   value = (*sp >> shift) & 0xf;
  2823.                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  2824.                   *dp |= (png_byte)(value << shift);
  2825.                }
  2826.  
  2827.                if (shift == s_end)
  2828.                {
  2829.                   shift = s_start;
  2830.                   sp++;
  2831.                   dp++;
  2832.                }
  2833.  
  2834.                else
  2835.                   shift += s_inc;
  2836.  
  2837.                if (m == 1)
  2838.                   m = 0x80;
  2839.  
  2840.                else
  2841.                   m >>= 1;
  2842.             }
  2843.             break;
  2844.          }
  2845.  
  2846.          default:
  2847.          {
  2848.             png_bytep sp = png_ptr->row_buf + 1;
  2849.             png_bytep dp = row;
  2850.             png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
  2851.             png_uint_32 i;
  2852.             png_uint_32 row_width = png_ptr->width;
  2853.             png_byte m = 0x80;
  2854.  
  2855.             for (i = 0; i < row_width; i++)
  2856.             {
  2857.                if (m & mask)
  2858.                {
  2859.                   png_memcpy(dp, sp, pixel_bytes);
  2860.                }
  2861.  
  2862.                sp += pixel_bytes;
  2863.                dp += pixel_bytes;
  2864.  
  2865.                if (m == 1)
  2866.                   m = 0x80;
  2867.  
  2868.                else
  2869.                   m >>= 1;
  2870.             }
  2871.             break;
  2872.          }
  2873.       }
  2874.    }
  2875. }
  2876.  
  2877. #ifdef PNG_READ_INTERLACING_SUPPORTED
  2878. void /* PRIVATE */
  2879. png_do_read_interlace(png_structp png_ptr)
  2880. {
  2881.    png_row_infop row_info = &(png_ptr->row_info);
  2882.    png_bytep row = png_ptr->row_buf + 1;
  2883.    int pass = png_ptr->pass;
  2884.    png_uint_32 transformations = png_ptr->transformations;
  2885.    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  2886.    /* Offset to next interlace block */
  2887.    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  2888.  
  2889.    png_debug(1, "in png_do_read_interlace");
  2890.    if (row != NULL && row_info != NULL)
  2891.    {
  2892.       png_uint_32 final_width;
  2893.  
  2894.       final_width = row_info->width * png_pass_inc[pass];
  2895.  
  2896.       switch (row_info->pixel_depth)
  2897.       {
  2898.          case 1:
  2899.          {
  2900.             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2901.             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
  2902.             int sshift, dshift;
  2903.             int s_start, s_end, s_inc;
  2904.             int jstop = png_pass_inc[pass];
  2905.             png_byte v;
  2906.             png_uint_32 i;
  2907.             int j;
  2908.  
  2909. #ifdef PNG_READ_PACKSWAP_SUPPORTED
  2910.             if (transformations & PNG_PACKSWAP)
  2911.             {
  2912.                 sshift = (int)((row_info->width + 7) & 0x07);
  2913.                 dshift = (int)((final_width + 7) & 0x07);
  2914.                 s_start = 7;
  2915.                 s_end = 0;
  2916.                 s_inc = -1;
  2917.             }
  2918.  
  2919.             else
  2920. #endif
  2921.             {
  2922.                 sshift = 7 - (int)((row_info->width + 7) & 0x07);
  2923.                 dshift = 7 - (int)((final_width + 7) & 0x07);
  2924.                 s_start = 0;
  2925.                 s_end = 7;
  2926.                 s_inc = 1;
  2927.             }
  2928.  
  2929.             for (i = 0; i < row_info->width; i++)
  2930.             {
  2931.                v = (png_byte)((*sp >> sshift) & 0x01);
  2932.                for (j = 0; j < jstop; j++)
  2933.                {
  2934.                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
  2935.                   *dp |= (png_byte)(v << dshift);
  2936.  
  2937.                   if (dshift == s_end)
  2938.                   {
  2939.                      dshift = s_start;
  2940.                      dp--;
  2941.                   }
  2942.  
  2943.                   else
  2944.                      dshift += s_inc;
  2945.                }
  2946.  
  2947.                if (sshift == s_end)
  2948.                {
  2949.                   sshift = s_start;
  2950.                   sp--;
  2951.                }
  2952.  
  2953.                else
  2954.                   sshift += s_inc;
  2955.             }
  2956.             break;
  2957.          }
  2958.  
  2959.          case 2:
  2960.          {
  2961.             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
  2962.             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
  2963.             int sshift, dshift;
  2964.             int s_start, s_end, s_inc;
  2965.             int jstop = png_pass_inc[pass];
  2966.             png_uint_32 i;
  2967.  
  2968. #ifdef PNG_READ_PACKSWAP_SUPPORTED
  2969.             if (transformations & PNG_PACKSWAP)
  2970.             {
  2971.                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
  2972.                dshift = (int)(((final_width + 3) & 0x03) << 1);
  2973.                s_start = 6;
  2974.                s_end = 0;
  2975.                s_inc = -2;
  2976.             }
  2977.  
  2978.             else
  2979. #endif
  2980.             {
  2981.                sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
  2982.                dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
  2983.                s_start = 0;
  2984.                s_end = 6;
  2985.                s_inc = 2;
  2986.             }
  2987.  
  2988.             for (i = 0; i < row_info->width; i++)
  2989.             {
  2990.                png_byte v;
  2991.                int j;
  2992.  
  2993.                v = (png_byte)((*sp >> sshift) & 0x03);
  2994.                for (j = 0; j < jstop; j++)
  2995.                {
  2996.                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
  2997.                   *dp |= (png_byte)(v << dshift);
  2998.  
  2999.                   if (dshift == s_end)
  3000.                   {
  3001.                      dshift = s_start;
  3002.                      dp--;
  3003.                   }
  3004.  
  3005.                   else
  3006.                      dshift += s_inc;
  3007.                }
  3008.  
  3009.                if (sshift == s_end)
  3010.                {
  3011.                   sshift = s_start;
  3012.                   sp--;
  3013.                }
  3014.  
  3015.                else
  3016.                   sshift += s_inc;
  3017.             }
  3018.             break;
  3019.          }
  3020.  
  3021.          case 4:
  3022.          {
  3023.             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
  3024.             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
  3025.             int sshift, dshift;
  3026.             int s_start, s_end, s_inc;
  3027.             png_uint_32 i;
  3028.             int jstop = png_pass_inc[pass];
  3029.  
  3030. #ifdef PNG_READ_PACKSWAP_SUPPORTED
  3031.             if (transformations & PNG_PACKSWAP)
  3032.             {
  3033.                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
  3034.                dshift = (int)(((final_width + 1) & 0x01) << 2);
  3035.                s_start = 4;
  3036.                s_end = 0;
  3037.                s_inc = -4;
  3038.             }
  3039.  
  3040.             else
  3041. #endif
  3042.             {
  3043.                sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
  3044.                dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
  3045.                s_start = 0;
  3046.                s_end = 4;
  3047.                s_inc = 4;
  3048.             }
  3049.  
  3050.             for (i = 0; i < row_info->width; i++)
  3051.             {
  3052.                png_byte v = (png_byte)((*sp >> sshift) & 0xf);
  3053.                int j;
  3054.  
  3055.                for (j = 0; j < jstop; j++)
  3056.                {
  3057.                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
  3058.                   *dp |= (png_byte)(v << dshift);
  3059.  
  3060.                   if (dshift == s_end)
  3061.                   {
  3062.                      dshift = s_start;
  3063.                      dp--;
  3064.                   }
  3065.  
  3066.                   else
  3067.                      dshift += s_inc;
  3068.                }
  3069.  
  3070.                if (sshift == s_end)
  3071.                {
  3072.                   sshift = s_start;
  3073.                   sp--;
  3074.                }
  3075.  
  3076.                else
  3077.                   sshift += s_inc;
  3078.             }
  3079.             break;
  3080.          }
  3081.          default:
  3082.          {
  3083.             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
  3084.  
  3085.             png_bytep sp = row + (png_size_t)(row_info->width - 1)
  3086.                 * pixel_bytes;
  3087.  
  3088.             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
  3089.  
  3090.             int jstop = png_pass_inc[pass];
  3091.             png_uint_32 i;
  3092.  
  3093.             for (i = 0; i < row_info->width; i++)
  3094.             {
  3095.                png_byte v[8];
  3096.                int j;
  3097.  
  3098.                png_memcpy(v, sp, pixel_bytes);
  3099.  
  3100.                for (j = 0; j < jstop; j++)
  3101.                {
  3102.                   png_memcpy(dp, v, pixel_bytes);
  3103.                   dp -= pixel_bytes;
  3104.                }
  3105.  
  3106.                sp -= pixel_bytes;
  3107.             }
  3108.             break;
  3109.          }
  3110.       }
  3111.       row_info->width = final_width;
  3112.       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
  3113.    }
  3114. #ifndef PNG_READ_PACKSWAP_SUPPORTED
  3115.    PNG_UNUSED(transformations)  /* Silence compiler warning */
  3116. #endif
  3117. }
  3118. #endif /* PNG_READ_INTERLACING_SUPPORTED */
  3119.  
  3120. void /* PRIVATE */
  3121. png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
  3122.     png_const_bytep prev_row, int filter)
  3123. {
  3124.    png_debug(1, "in png_read_filter_row");
  3125.    png_debug2(2, "row = %u, filter = %d", png_ptr->row_number, filter);
  3126.    switch (filter)
  3127.    {
  3128.       case PNG_FILTER_VALUE_NONE:
  3129.          break;
  3130.  
  3131.       case PNG_FILTER_VALUE_SUB:
  3132.       {
  3133.          png_size_t i;
  3134.          png_size_t istop = row_info->rowbytes;
  3135.          unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
  3136.          png_bytep rp = row + bpp;
  3137.          png_bytep lp = row;
  3138.  
  3139.          for (i = bpp; i < istop; i++)
  3140.          {
  3141.             *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
  3142.             rp++;
  3143.          }
  3144.          break;
  3145.       }
  3146.       case PNG_FILTER_VALUE_UP:
  3147.       {
  3148.          png_size_t i;
  3149.          png_size_t istop = row_info->rowbytes;
  3150.          png_bytep rp = row;
  3151.          png_const_bytep pp = prev_row;
  3152.  
  3153.          for (i = 0; i < istop; i++)
  3154.          {
  3155.             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
  3156.             rp++;
  3157.          }
  3158.          break;
  3159.       }
  3160.       case PNG_FILTER_VALUE_AVG:
  3161.       {
  3162.          png_size_t i;
  3163.          png_bytep rp = row;
  3164.          png_const_bytep pp = prev_row;
  3165.          png_bytep lp = row;
  3166.          unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
  3167.          png_size_t istop = row_info->rowbytes - bpp;
  3168.  
  3169.          for (i = 0; i < bpp; i++)
  3170.          {
  3171.             *rp = (png_byte)(((int)(*rp) +
  3172.                 ((int)(*pp++) / 2 )) & 0xff);
  3173.  
  3174.             rp++;
  3175.          }
  3176.  
  3177.          for (i = 0; i < istop; i++)
  3178.          {
  3179.             *rp = (png_byte)(((int)(*rp) +
  3180.                 (int)(*pp++ + *lp++) / 2 ) & 0xff);
  3181.  
  3182.             rp++;
  3183.          }
  3184.          break;
  3185.       }
  3186.       case PNG_FILTER_VALUE_PAETH:
  3187.       {
  3188.          png_size_t i;
  3189.          png_bytep rp = row;
  3190.          png_const_bytep pp = prev_row;
  3191.          png_bytep lp = row;
  3192.          png_const_bytep cp = prev_row;
  3193.          unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
  3194.          png_size_t istop=row_info->rowbytes - bpp;
  3195.  
  3196.          for (i = 0; i < bpp; i++)
  3197.          {
  3198.             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
  3199.             rp++;
  3200.          }
  3201.  
  3202.          for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
  3203.          {
  3204.             int a, b, c, pa, pb, pc, p;
  3205.  
  3206.             a = *lp++;
  3207.             b = *pp++;
  3208.             c = *cp++;
  3209.  
  3210.             p = b - c;
  3211.             pc = a - c;
  3212.  
  3213. #ifdef PNG_USE_ABS
  3214.             pa = abs(p);
  3215.             pb = abs(pc);
  3216.             pc = abs(p + pc);
  3217. #else
  3218.             pa = p < 0 ? -p : p;
  3219.             pb = pc < 0 ? -pc : pc;
  3220.             pc = (p + pc) < 0 ? -(p + pc) : p + pc;
  3221. #endif
  3222.  
  3223.             /*
  3224.                if (pa <= pb && pa <= pc)
  3225.                   p = a;
  3226.  
  3227.                else if (pb <= pc)
  3228.                   p = b;
  3229.  
  3230.                else
  3231.                   p = c;
  3232.              */
  3233.  
  3234.             p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
  3235.  
  3236.             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
  3237.             rp++;
  3238.          }
  3239.          break;
  3240.       }
  3241.       default:
  3242.          png_error(png_ptr, "Ignoring bad adaptive filter type");
  3243.          /*NOT REACHED */
  3244.          break;
  3245.    }
  3246. }
  3247.  
  3248. #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  3249. void /* PRIVATE */
  3250. png_read_finish_row(png_structp png_ptr)
  3251. {
  3252. #ifdef PNG_READ_INTERLACING_SUPPORTED
  3253.    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  3254.  
  3255.    /* Start of interlace block */
  3256.    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  3257.  
  3258.    /* Offset to next interlace block */
  3259.    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  3260.  
  3261.    /* Start of interlace block in the y direction */
  3262.    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  3263.  
  3264.    /* Offset to next interlace block in the y direction */
  3265.    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  3266. #endif /* PNG_READ_INTERLACING_SUPPORTED */
  3267.  
  3268.    png_debug(1, "in png_read_finish_row");
  3269.    png_ptr->row_number++;
  3270.    if (png_ptr->row_number < png_ptr->num_rows)
  3271.       return;
  3272.  
  3273. #ifdef PNG_READ_INTERLACING_SUPPORTED
  3274.    if (png_ptr->interlaced)
  3275.    {
  3276.       png_ptr->row_number = 0;
  3277.  
  3278.       png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  3279.  
  3280.       do
  3281.       {
  3282.          png_ptr->pass++;
  3283.  
  3284.          if (png_ptr->pass >= 7)
  3285.             break;
  3286.  
  3287.          png_ptr->iwidth = (png_ptr->width +
  3288.             png_pass_inc[png_ptr->pass] - 1 -
  3289.             png_pass_start[png_ptr->pass]) /
  3290.             png_pass_inc[png_ptr->pass];
  3291.  
  3292.          if (!(png_ptr->transformations & PNG_INTERLACE))
  3293.          {
  3294.             png_ptr->num_rows = (png_ptr->height +
  3295.                 png_pass_yinc[png_ptr->pass] - 1 -
  3296.                 png_pass_ystart[png_ptr->pass]) /
  3297.                 png_pass_yinc[png_ptr->pass];
  3298.          }
  3299.  
  3300.          else  /* if (png_ptr->transformations & PNG_INTERLACE) */
  3301.             break; /* libpng deinterlacing sees every row */
  3302.  
  3303.       } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
  3304.  
  3305.       if (png_ptr->pass < 7)
  3306.          return;
  3307.    }
  3308. #endif /* PNG_READ_INTERLACING_SUPPORTED */
  3309.  
  3310.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  3311.    {
  3312.       PNG_IDAT;
  3313.       char extra;
  3314.       int ret;
  3315.  
  3316.       png_ptr->zstream.next_out = (Byte *)&extra;
  3317.       png_ptr->zstream.avail_out = (uInt)1;
  3318.  
  3319.       for (;;)
  3320.       {
  3321.          if (!(png_ptr->zstream.avail_in))
  3322.          {
  3323.             while (!png_ptr->idat_size)
  3324.             {
  3325.                png_crc_finish(png_ptr, 0);
  3326.                png_ptr->idat_size = png_read_chunk_header(png_ptr);
  3327.                if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  3328.                   png_error(png_ptr, "Not enough image data");
  3329.             }
  3330.  
  3331.             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
  3332.             png_ptr->zstream.next_in = png_ptr->zbuf;
  3333.  
  3334.             if (png_ptr->zbuf_size > png_ptr->idat_size)
  3335.                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
  3336.  
  3337.             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
  3338.             png_ptr->idat_size -= png_ptr->zstream.avail_in;
  3339.          }
  3340.  
  3341.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  3342.  
  3343.          if (ret == Z_STREAM_END)
  3344.          {
  3345.             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
  3346.                 png_ptr->idat_size)
  3347.                png_warning(png_ptr, "Extra compressed data");
  3348.  
  3349.             png_ptr->mode |= PNG_AFTER_IDAT;
  3350.             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  3351.             break;
  3352.          }
  3353.  
  3354.          if (ret != Z_OK)
  3355.             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
  3356.                 "Decompression Error");
  3357.  
  3358.          if (!(png_ptr->zstream.avail_out))
  3359.          {
  3360.             png_warning(png_ptr, "Extra compressed data");
  3361.             png_ptr->mode |= PNG_AFTER_IDAT;
  3362.             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  3363.             break;
  3364.          }
  3365.  
  3366.       }
  3367.       png_ptr->zstream.avail_out = 0;
  3368.    }
  3369.  
  3370.    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
  3371.       png_warning(png_ptr, "Extra compression data");
  3372.  
  3373.    inflateReset(&png_ptr->zstream);
  3374.  
  3375.    png_ptr->mode |= PNG_AFTER_IDAT;
  3376. }
  3377. #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
  3378.  
  3379. void /* PRIVATE */
  3380. png_read_start_row(png_structp png_ptr)
  3381. {
  3382. #ifdef PNG_READ_INTERLACING_SUPPORTED
  3383.    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  3384.  
  3385.    /* Start of interlace block */
  3386.    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  3387.  
  3388.    /* Offset to next interlace block */
  3389.    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  3390.  
  3391.    /* Start of interlace block in the y direction */
  3392.    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  3393.  
  3394.    /* Offset to next interlace block in the y direction */
  3395.    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  3396. #endif
  3397.  
  3398.    int max_pixel_depth;
  3399.    png_size_t row_bytes;
  3400.  
  3401.    png_debug(1, "in png_read_start_row");
  3402.    png_ptr->zstream.avail_in = 0;
  3403.    png_init_read_transformations(png_ptr);
  3404. #ifdef PNG_READ_INTERLACING_SUPPORTED
  3405.    if (png_ptr->interlaced)
  3406.    {
  3407.       if (!(png_ptr->transformations & PNG_INTERLACE))
  3408.          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  3409.              png_pass_ystart[0]) / png_pass_yinc[0];
  3410.  
  3411.       else
  3412.          png_ptr->num_rows = png_ptr->height;
  3413.  
  3414.       png_ptr->iwidth = (png_ptr->width +
  3415.           png_pass_inc[png_ptr->pass] - 1 -
  3416.           png_pass_start[png_ptr->pass]) /
  3417.           png_pass_inc[png_ptr->pass];
  3418.    }
  3419.  
  3420.    else
  3421. #endif /* PNG_READ_INTERLACING_SUPPORTED */
  3422.    {
  3423.       png_ptr->num_rows = png_ptr->height;
  3424.       png_ptr->iwidth = png_ptr->width;
  3425.    }
  3426.  
  3427.    max_pixel_depth = png_ptr->pixel_depth;
  3428.  
  3429. #ifdef PNG_READ_PACK_SUPPORTED
  3430.    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
  3431.       max_pixel_depth = 8;
  3432. #endif
  3433.  
  3434. #ifdef PNG_READ_EXPAND_SUPPORTED
  3435.    if (png_ptr->transformations & PNG_EXPAND)
  3436.    {
  3437.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  3438.       {
  3439.          if (png_ptr->num_trans)
  3440.             max_pixel_depth = 32;
  3441.  
  3442.          else
  3443.             max_pixel_depth = 24;
  3444.       }
  3445.  
  3446.       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  3447.       {
  3448.          if (max_pixel_depth < 8)
  3449.             max_pixel_depth = 8;
  3450.  
  3451.          if (png_ptr->num_trans)
  3452.             max_pixel_depth *= 2;
  3453.       }
  3454.  
  3455.       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  3456.       {
  3457.          if (png_ptr->num_trans)
  3458.          {
  3459.             max_pixel_depth *= 4;
  3460.             max_pixel_depth /= 3;
  3461.          }
  3462.       }
  3463.    }
  3464. #endif
  3465.  
  3466. #ifdef PNG_READ_FILLER_SUPPORTED
  3467.    if (png_ptr->transformations & (PNG_FILLER))
  3468.    {
  3469.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  3470.          max_pixel_depth = 32;
  3471.  
  3472.       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  3473.       {
  3474.          if (max_pixel_depth <= 8)
  3475.             max_pixel_depth = 16;
  3476.  
  3477.          else
  3478.             max_pixel_depth = 32;
  3479.       }
  3480.  
  3481.       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  3482.       {
  3483.          if (max_pixel_depth <= 32)
  3484.             max_pixel_depth = 32;
  3485.  
  3486.          else
  3487.             max_pixel_depth = 64;
  3488.       }
  3489.    }
  3490. #endif
  3491.  
  3492. #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
  3493.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  3494.    {
  3495.       if (
  3496. #ifdef PNG_READ_EXPAND_SUPPORTED
  3497.           (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
  3498. #endif
  3499. #ifdef PNG_READ_FILLER_SUPPORTED
  3500.           (png_ptr->transformations & (PNG_FILLER)) ||
  3501. #endif
  3502.           png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  3503.       {
  3504.          if (max_pixel_depth <= 16)
  3505.             max_pixel_depth = 32;
  3506.  
  3507.          else
  3508.             max_pixel_depth = 64;
  3509.       }
  3510.  
  3511.       else
  3512.       {
  3513.          if (max_pixel_depth <= 8)
  3514.          {
  3515.             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  3516.                max_pixel_depth = 32;
  3517.  
  3518.             else
  3519.                max_pixel_depth = 24;
  3520.          }
  3521.  
  3522.          else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  3523.             max_pixel_depth = 64;
  3524.  
  3525.          else
  3526.             max_pixel_depth = 48;
  3527.       }
  3528.    }
  3529. #endif
  3530.  
  3531. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
  3532. defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
  3533.    if (png_ptr->transformations & PNG_USER_TRANSFORM)
  3534.    {
  3535.       int user_pixel_depth = png_ptr->user_transform_depth*
  3536.          png_ptr->user_transform_channels;
  3537.  
  3538.       if (user_pixel_depth > max_pixel_depth)
  3539.          max_pixel_depth=user_pixel_depth;
  3540.    }
  3541. #endif
  3542.  
  3543.    /* Align the width on the next larger 8 pixels.  Mainly used
  3544.     * for interlacing
  3545.     */
  3546.    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
  3547.    /* Calculate the maximum bytes needed, adding a byte and a pixel
  3548.     * for safety's sake
  3549.     */
  3550.    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
  3551.        1 + ((max_pixel_depth + 7) >> 3);
  3552.  
  3553. #ifdef PNG_MAX_MALLOC_64K
  3554.    if (row_bytes > (png_uint_32)65536L)
  3555.       png_error(png_ptr, "This image requires a row greater than 64KB");
  3556. #endif
  3557.  
  3558.    if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
  3559.    {
  3560.      png_free(png_ptr, png_ptr->big_row_buf);
  3561.  
  3562.      if (png_ptr->interlaced)
  3563.         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
  3564.             row_bytes + 48);
  3565.  
  3566.      else
  3567.         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
  3568.             row_bytes + 48);
  3569.  
  3570.      png_ptr->old_big_row_buf_size = row_bytes + 48;
  3571.  
  3572. #ifdef PNG_ALIGNED_MEMORY_SUPPORTED
  3573.      /* Use 16-byte aligned memory for row_buf with at least 16 bytes
  3574.       * of padding before and after row_buf.
  3575.       */
  3576.      png_ptr->row_buf = png_ptr->big_row_buf + 32 -
  3577.          (((png_alloc_size_t)png_ptr->big_row_buf + 15) & 0x0F);
  3578.  
  3579.      png_ptr->old_big_row_buf_size = row_bytes + 48;
  3580. #else
  3581.      /* Use 32 bytes of padding before and 16 bytes after row_buf. */
  3582.      png_ptr->row_buf = png_ptr->big_row_buf + 32;
  3583. #endif
  3584.      png_ptr->old_big_row_buf_size = row_bytes + 48;
  3585.    }
  3586.  
  3587. #ifdef PNG_MAX_MALLOC_64K
  3588.    if (png_ptr->rowbytes > 65535)
  3589.       png_error(png_ptr, "This image requires a row greater than 64KB");
  3590.  
  3591. #endif
  3592.    if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
  3593.       png_error(png_ptr, "Row has too many bytes to allocate in memory");
  3594.  
  3595.    if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size)
  3596.    {
  3597.       png_free(png_ptr, png_ptr->prev_row);
  3598.  
  3599.       png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
  3600.  
  3601.       png_ptr->old_prev_row_size = png_ptr->rowbytes + 1;
  3602.    }
  3603.  
  3604.    png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  3605.  
  3606.    png_debug1(3, "width = %u,", png_ptr->width);
  3607.    png_debug1(3, "height = %u,", png_ptr->height);
  3608.    png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
  3609.    png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
  3610.    png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
  3611.    png_debug1(3, "irowbytes = %lu",
  3612.        (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
  3613.  
  3614.    png_ptr->flags |= PNG_FLAG_ROW_INIT;
  3615. }
  3616. #endif /* PNG_READ_SUPPORTED */
  3617.