home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / pdflib / pdflib-4.0.1.sit / pdflib-4.0.1 / png / pngrutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-04  |  85.4 KB  |  3,004 lines  |  [TEXT/CWIE]

  1.  
  2. /* pngrutil.c - utilities to read a PNG file
  3.  *
  4.  * libpng 1.0.8 - July 24, 2000
  5.  * For conditions of distribution and use, see copyright notice in png.h
  6.  * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
  7.  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  8.  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  9.  *
  10.  * This file contains routines that are only called from within
  11.  * libpng itself during the course of reading an image.
  12.  */
  13.  
  14. /* $Id: pngrutil.c,v 1.3 2001/03/21 16:12:07 tm Exp $ */
  15.  
  16. #define PNG_INTERNAL
  17. #include "png.h"
  18.  
  19. #if defined(_WIN32_WCE)
  20. /* strtod() function is not supported on WindowsCE */
  21. #  ifdef PNG_FLOATING_POINT_SUPPORTED
  22. __inline double strtod(const char *nptr, char **endptr)
  23. {
  24.    double result = 0;
  25.    int len;
  26.    wchar_t *str, *end;
  27.  
  28.    len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
  29.    str = (wchar_t *)malloc(len * sizeof(wchar_t));
  30.    if ( NULL != str )
  31.    {
  32.       MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
  33.       result = wcstod(str, &end);
  34.       len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
  35.       *endptr = (char *)nptr + (strlen(nptr) - len + 1);
  36.       free(str);
  37.    }
  38.    return result;
  39. }
  40. #  endif
  41. #endif
  42.  
  43. #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
  44. /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
  45. png_uint_32 /* PRIVATE */
  46. png_get_uint_32(png_bytep buf)
  47. {
  48.    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
  49.       ((png_uint_32)(*(buf + 1)) << 16) +
  50.       ((png_uint_32)(*(buf + 2)) << 8) +
  51.       (png_uint_32)(*(buf + 3));
  52.  
  53.    return (i);
  54. }
  55.  
  56. #if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
  57. /* Grab a signed 32-bit integer from a buffer in big-endian format.  The
  58.  * data is stored in the PNG file in two's complement format, and it is
  59.  * assumed that the machine format for signed integers is the same. */
  60. png_int_32 /* PRIVATE */
  61. png_get_int_32(png_bytep buf)
  62. {
  63.    png_int_32 i = ((png_int_32)(*buf) << 24) +
  64.       ((png_int_32)(*(buf + 1)) << 16) +
  65.       ((png_int_32)(*(buf + 2)) << 8) +
  66.       (png_int_32)(*(buf + 3));
  67.  
  68.    return (i);
  69. }
  70. #endif /* PNG_READ_pCAL_SUPPORTED */
  71.  
  72. /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
  73. png_uint_16 /* PRIVATE */
  74. png_get_uint_16(png_bytep buf)
  75. {
  76.    png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
  77.       (png_uint_16)(*(buf + 1)));
  78.  
  79.    return (i);
  80. }
  81. #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
  82.  
  83. /* Read data, and (optionally) run it through the CRC. */
  84. void /* PRIVATE */
  85. png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
  86. {
  87.    png_read_data(png_ptr, buf, length);
  88.    png_calculate_crc(png_ptr, buf, length);
  89. }
  90.  
  91. /* Optionally skip data and then check the CRC.  Depending on whether we
  92.    are reading a ancillary or critical chunk, and how the program has set
  93.    things up, we may calculate the CRC on the data and print a message.
  94.    Returns '1' if there was a CRC error, '0' otherwise. */
  95. int /* PRIVATE */
  96. png_crc_finish(png_structp png_ptr, png_uint_32 skip)
  97. {
  98.    png_size_t i;
  99.    png_size_t istop = png_ptr->zbuf_size;
  100.  
  101.    for (i = (png_size_t)skip; i > istop; i -= istop)
  102.    {
  103.       png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  104.    }
  105.    if (i)
  106.    {
  107.       png_crc_read(png_ptr, png_ptr->zbuf, i);
  108.    }
  109.  
  110.    if (png_crc_error(png_ptr))
  111.    {
  112.       if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
  113.            !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
  114.           (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
  115.           (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
  116.       {
  117.          png_chunk_warning(png_ptr, "CRC error");
  118.       }
  119.       else
  120.       {
  121.          png_chunk_error(png_ptr, "CRC error");
  122.       }
  123.       return (1);
  124.    }
  125.  
  126.    return (0);
  127. }
  128.  
  129. /* Compare the CRC stored in the PNG file with that calculated by libpng from
  130.    the data it has read thus far. */
  131. int /* PRIVATE */
  132. png_crc_error(png_structp png_ptr)
  133. {
  134.    png_byte crc_bytes[4];
  135.    png_uint_32 crc;
  136.    int need_crc = 1;
  137.  
  138.    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
  139.    {
  140.       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
  141.           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
  142.          need_crc = 0;
  143.    }
  144.    else                                                    /* critical */
  145.    {
  146.       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
  147.          need_crc = 0;
  148.    }
  149.  
  150.    png_read_data(png_ptr, crc_bytes, 4);
  151.  
  152.    if (need_crc)
  153.    {
  154.       crc = png_get_uint_32(crc_bytes);
  155.       return ((int)(crc != png_ptr->crc));
  156.    }
  157.    else
  158.       return (0);
  159. }
  160.  
  161. #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
  162.     defined(PNG_READ_iCCP_SUPPORTED)
  163. /*
  164.  * Decompress trailing data in a chunk.  The assumption is that chunkdata
  165.  * points at an allocated area holding the contents of a chunk with a
  166.  * trailing compressed part.  What we get back is an allocated area
  167.  * holding the original prefix part and an uncompressed version of the
  168.  * trailing part (the malloc area passed in is freed).
  169.  */
  170. png_charp /* PRIVATE */
  171. png_decompress_chunk(png_structp png_ptr, int comp_type,
  172.                               png_charp chunkdata, png_size_t chunklength,
  173.                               png_size_t prefix_size, png_size_t *newlength)
  174. {
  175.    static char msg[] = "Error decoding compressed text";
  176.    png_charp text = NULL;
  177.    png_size_t text_size;
  178.  
  179.    if (comp_type == PNG_TEXT_COMPRESSION_zTXt)
  180.    {
  181.       int ret = Z_OK;
  182.       png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
  183.       png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
  184.       png_ptr->zstream.next_out = png_ptr->zbuf;
  185.       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  186.  
  187.       text_size = 0;
  188.       text = NULL;
  189.  
  190.       while (png_ptr->zstream.avail_in)
  191.       {
  192.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  193.          if (ret != Z_OK && ret != Z_STREAM_END)
  194.          {
  195.             if (png_ptr->zstream.msg != NULL)
  196.                png_warning(png_ptr, png_ptr->zstream.msg);
  197.             else
  198.                png_warning(png_ptr, msg);
  199.             inflateReset(&png_ptr->zstream);
  200.             png_ptr->zstream.avail_in = 0;
  201.  
  202.             if (text ==  NULL)
  203.             {
  204.                text_size = prefix_size + sizeof(msg) + 1;
  205.                text = (png_charp)png_malloc(png_ptr, text_size);
  206.                png_memcpy(text, chunkdata, prefix_size);
  207.             }
  208.  
  209.             text[text_size - 1] = 0x00;
  210.  
  211.             /* Copy what we can of the error message into the text chunk */
  212.             text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
  213.             text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
  214.             png_memcpy(text + prefix_size, msg, text_size + 1);
  215.             break;
  216.          }
  217.          if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
  218.          {
  219.             if (text == NULL)
  220.             {
  221.                text_size = prefix_size +
  222.                    png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  223.                text = (png_charp)png_malloc(png_ptr, text_size + 1);
  224.                png_memcpy(text + prefix_size, png_ptr->zbuf,
  225.                           text_size - prefix_size);
  226.                png_memcpy(text, chunkdata, prefix_size);
  227.                *(text + text_size) = 0x00;
  228.             }
  229.             else
  230.             {
  231.                png_charp tmp;
  232.  
  233.                tmp = text;
  234.                text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
  235.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
  236.                png_memcpy(text, tmp, text_size);
  237.                png_free(png_ptr, tmp);
  238.                png_memcpy(text + text_size, png_ptr->zbuf,
  239.                   (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
  240.                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  241.                *(text + text_size) = 0x00;
  242.             }
  243.             if (ret == Z_STREAM_END)
  244.                break;
  245.             else
  246.             {
  247.                png_ptr->zstream.next_out = png_ptr->zbuf;
  248.                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  249.             }
  250.          }
  251.       }
  252.       if (ret != Z_STREAM_END)
  253.       {
  254. #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
  255.          char umsg[50];
  256.  
  257.          if (ret == Z_BUF_ERROR)
  258.             sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
  259.                 png_ptr->chunk_name);
  260.          else if (ret == Z_DATA_ERROR)
  261.             sprintf(umsg,"Data error in compressed datastream in %s chunk",
  262.                 png_ptr->chunk_name);
  263.          else
  264.             sprintf(umsg,"Incomplete compressed datastream in %s chunk",
  265.                 png_ptr->chunk_name);
  266.          png_warning(png_ptr, umsg);
  267. #else
  268.          png_warning(png_ptr,
  269.             "Incomplete compressed datastream in chunk other than IDAT");
  270. #endif
  271.       }
  272.  
  273.       inflateReset(&png_ptr->zstream);
  274.       png_ptr->zstream.avail_in = 0;
  275.  
  276.       png_free(png_ptr, chunkdata);
  277.       chunkdata = text;
  278.       *newlength=text_size;
  279.    }
  280.    else /* if (comp_type != PNG_TEXT_COMPRESSION_zTXt) */
  281.    {
  282. #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
  283.       char umsg[50];
  284.  
  285.       sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
  286.       png_warning(png_ptr, umsg);
  287. #else
  288.       png_warning(png_ptr, "Unknown zTXt compression type");
  289. #endif
  290.  
  291.       /* Copy what we can of the error message into the text chunk */
  292.       text_size = (png_size_t)(chunklength - (text - chunkdata));
  293.       text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
  294.       png_memcpy(text, msg, text_size);
  295.    }
  296.  
  297.    return chunkdata;
  298. }
  299. #endif
  300.  
  301. /* read and check the IDHR chunk */
  302. void /* PRIVATE */
  303. png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  304. {
  305.    png_byte buf[13];
  306.    png_uint_32 width, height;
  307.    int bit_depth, color_type, compression_type, filter_type;
  308.    int interlace_type;
  309.  
  310.    png_debug(1, "in png_handle_IHDR\n");
  311.  
  312.    if (png_ptr->mode & PNG_HAVE_IHDR)
  313.       png_error(png_ptr, "Out of place IHDR");
  314.  
  315.    /* check the length */
  316.    if (length != 13)
  317.       png_error(png_ptr, "Invalid IHDR chunk");
  318.  
  319.    png_ptr->mode |= PNG_HAVE_IHDR;
  320.  
  321.    png_crc_read(png_ptr, buf, 13);
  322.    png_crc_finish(png_ptr, 0);
  323.  
  324.    width = png_get_uint_32(buf);
  325.    height = png_get_uint_32(buf + 4);
  326.    bit_depth = buf[8];
  327.    color_type = buf[9];
  328.    compression_type = buf[10];
  329.    filter_type = buf[11];
  330.    interlace_type = buf[12];
  331.  
  332.    /* check for width and height valid values */
  333.    if (width == 0 || width > PNG_MAX_UINT || height == 0 ||
  334.         height > PNG_MAX_UINT)
  335.       png_error(png_ptr, "Invalid image size in IHDR");
  336.  
  337.    /* check other values */
  338.    if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
  339.       bit_depth != 8 && bit_depth != 16)
  340.       png_error(png_ptr, "Invalid bit depth in IHDR");
  341.  
  342.    if (color_type < 0 || color_type == 1 ||
  343.       color_type == 5 || color_type > 6)
  344.       png_error(png_ptr, "Invalid color type in IHDR");
  345.  
  346.    if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
  347.        ((color_type == PNG_COLOR_TYPE_RGB ||
  348.          color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
  349.          color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
  350.       png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
  351.  
  352.    if (interlace_type >= PNG_INTERLACE_LAST)
  353.       png_error(png_ptr, "Unknown interlace method in IHDR");
  354.  
  355.    if (compression_type != PNG_COMPRESSION_TYPE_BASE)
  356.       png_error(png_ptr, "Unknown compression method in IHDR");
  357.  
  358.    if (filter_type != PNG_FILTER_TYPE_BASE)
  359.       png_error(png_ptr, "Unknown filter method in IHDR");
  360.  
  361.    /* set internal variables */
  362.    png_ptr->width = width;
  363.    png_ptr->height = height;
  364.    png_ptr->bit_depth = (png_byte)bit_depth;
  365.    png_ptr->interlaced = (png_byte)interlace_type;
  366.    png_ptr->color_type = (png_byte)color_type;
  367.  
  368.    /* find number of channels */
  369.    switch (png_ptr->color_type)
  370.    {
  371.       case PNG_COLOR_TYPE_GRAY:
  372.       case PNG_COLOR_TYPE_PALETTE:
  373.          png_ptr->channels = 1;
  374.          break;
  375.       case PNG_COLOR_TYPE_RGB:
  376.          png_ptr->channels = 3;
  377.          break;
  378.       case PNG_COLOR_TYPE_GRAY_ALPHA:
  379.          png_ptr->channels = 2;
  380.          break;
  381.       case PNG_COLOR_TYPE_RGB_ALPHA:
  382.          png_ptr->channels = 4;
  383.          break;
  384.    }
  385.  
  386.    /* set up other useful info */
  387.    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
  388.    png_ptr->channels);
  389.    png_ptr->rowbytes = ((png_ptr->width *
  390.       (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
  391.    png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
  392.    png_debug1(3,"channels = %d\n", png_ptr->channels);
  393.    png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
  394.    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
  395.       color_type, interlace_type, compression_type, filter_type);
  396. }
  397.  
  398. /* read and check the palette */
  399. void /* PRIVATE */
  400. png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  401. {
  402.    png_colorp palette;
  403.    int num, i;
  404. #ifndef PNG_NO_POINTER_INDEXING
  405.    png_colorp pal_ptr;
  406. #endif
  407.  
  408.    png_debug(1, "in png_handle_PLTE\n");
  409.  
  410.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  411.       png_error(png_ptr, "Missing IHDR before PLTE");
  412.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  413.    {
  414.       png_warning(png_ptr, "Invalid PLTE after IDAT");
  415.       png_crc_finish(png_ptr, length);
  416.       return;
  417.    }
  418.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  419.       png_error(png_ptr, "Duplicate PLTE chunk");
  420.  
  421.    png_ptr->mode |= PNG_HAVE_PLTE;
  422.  
  423. #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
  424.    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  425.    {
  426.       png_crc_finish(png_ptr, length);
  427.       return;
  428.    }
  429. #endif
  430.  
  431.    if (length > 768 || length % 3)
  432.    {
  433.       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  434.       {
  435.          png_warning(png_ptr, "Invalid palette chunk");
  436.          png_crc_finish(png_ptr, length);
  437.          return;
  438.       }
  439.       else
  440.       {
  441.          png_error(png_ptr, "Invalid palette chunk");
  442.       }
  443.    }
  444.  
  445.    num = (int)length / 3;
  446.  
  447.    palette = (png_colorp)png_zalloc(png_ptr, (uInt)num, sizeof (png_color));
  448.  
  449. #ifndef PNG_NO_POINTER_INDEXING
  450.    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
  451.    {
  452.       png_byte buf[3];
  453.  
  454.       png_crc_read(png_ptr, buf, 3);
  455.       pal_ptr->red = buf[0];
  456.       pal_ptr->green = buf[1];
  457.       pal_ptr->blue = buf[2];
  458.    }
  459. #else
  460.    for (i = 0; i < num; i++)
  461.    {
  462.       png_byte buf[3];
  463.  
  464.       png_crc_read(png_ptr, buf, 3);
  465.       /* don't depend upon png_color being any order */
  466.       palette[i].red = buf[0];
  467.       palette[i].green = buf[1];
  468.       palette[i].blue = buf[2];
  469.    }
  470. #endif
  471.  
  472.    /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
  473.       whatever the normal CRC configuration tells us.  However, if we
  474.       have an RGB image, the PLTE can be considered ancillary, so
  475.       we will act as though it is. */
  476. #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
  477.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  478. #endif
  479.    {
  480.       png_crc_finish(png_ptr, 0);
  481.    }
  482. #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
  483.    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
  484.    {
  485.       /* If we don't want to use the data from an ancillary chunk,
  486.          we have two options: an error abort, or a warning and we
  487.          ignore the data in this chunk (which should be OK, since
  488.          it's considered ancillary for a RGB or RGBA image). */
  489.       if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
  490.       {
  491.          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
  492.          {
  493.             png_chunk_error(png_ptr, "CRC error");
  494.          }
  495.          else
  496.          {
  497.             png_chunk_warning(png_ptr, "CRC error");
  498.             png_zfree(png_ptr, palette);
  499.             return;
  500.          }
  501.       }
  502.       /* Otherwise, we (optionally) emit a warning and use the chunk. */
  503.       else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
  504.       {
  505.          png_chunk_warning(png_ptr, "CRC error");
  506.       }
  507.    }
  508. #endif
  509.    png_ptr->palette = palette;
  510.    png_ptr->num_palette = (png_uint_16)num;
  511.  
  512. #ifdef PNG_FREE_ME_SUPPORTED
  513.    png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
  514.    png_ptr->free_me |= PNG_FREE_PLTE;
  515. #else
  516.    png_ptr->flags |= PNG_FLAG_FREE_PLTE;
  517. #endif
  518.    png_set_PLTE(png_ptr, info_ptr, palette, num);
  519.  
  520. #if defined(PNG_READ_tRNS_SUPPORTED)
  521.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  522.    {
  523.       if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  524.       {
  525.          if (png_ptr->num_trans > (png_uint_16)num)
  526.          {
  527.             png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
  528.             png_ptr->num_trans = (png_uint_16)num;
  529.          }
  530.          if (info_ptr->num_trans > (png_uint_16)num)
  531.          {
  532.             png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
  533.             info_ptr->num_trans = (png_uint_16)num;
  534.          }
  535.       }
  536.    }
  537. #endif
  538.  
  539. }
  540.  
  541. void /* PRIVATE */
  542. png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  543. {
  544.    png_debug(1, "in png_handle_IEND\n");
  545.  
  546.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
  547.    {
  548.       png_error(png_ptr, "No image in file");
  549.  
  550.       /* to quiet compiler warnings about unused info_ptr */
  551.       if (info_ptr == NULL)
  552.          return;
  553.    }
  554.  
  555.    png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
  556.  
  557.    if (length != 0)
  558.    {
  559.       png_warning(png_ptr, "Incorrect IEND chunk length");
  560.    }
  561.    png_crc_finish(png_ptr, length);
  562. }
  563.  
  564. #if defined(PNG_READ_gAMA_SUPPORTED)
  565. void /* PRIVATE */
  566. png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  567. {
  568.    png_fixed_point igamma;
  569. #ifdef PNG_FLOATING_POINT_SUPPORTED
  570.    float file_gamma;
  571. #endif
  572.    png_byte buf[4];
  573.  
  574.    png_debug(1, "in png_handle_gAMA\n");
  575.  
  576.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  577.       png_error(png_ptr, "Missing IHDR before gAMA");
  578.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  579.    {
  580.       png_warning(png_ptr, "Invalid gAMA after IDAT");
  581.       png_crc_finish(png_ptr, length);
  582.       return;
  583.    }
  584.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  585.       /* Should be an error, but we can cope with it */
  586.       png_warning(png_ptr, "Out of place gAMA chunk");
  587.  
  588.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
  589. #if defined(PNG_READ_sRGB_SUPPORTED)
  590.       && !(info_ptr->valid & PNG_INFO_sRGB)
  591. #endif
  592.       )
  593.    {
  594.       png_warning(png_ptr, "Duplicate gAMA chunk");
  595.       png_crc_finish(png_ptr, length);
  596.       return;
  597.    }
  598.  
  599.    if (length != 4)
  600.    {
  601.       png_warning(png_ptr, "Incorrect gAMA chunk length");
  602.       png_crc_finish(png_ptr, length);
  603.       return;
  604.    }
  605.  
  606.    png_crc_read(png_ptr, buf, 4);
  607.    if (png_crc_finish(png_ptr, 0))
  608.       return;
  609.  
  610.    igamma = (png_fixed_point)png_get_uint_32(buf);
  611.    /* check for zero gamma */
  612.    if (igamma == 0)
  613.       return;
  614.  
  615. #if defined(PNG_READ_sRGB_SUPPORTED)
  616.    if (info_ptr->valid & PNG_INFO_sRGB)
  617.       if(igamma < 45000L || igamma > 46000L)
  618.       {
  619.          png_warning(png_ptr,
  620.            "Ignoring incorrect gAMA value when sRGB is also present");
  621. #ifndef PNG_NO_CONSOLE_IO
  622.          fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
  623. #endif
  624.          return;
  625.       }
  626. #endif /* PNG_READ_sRGB_SUPPORTED */
  627.  
  628. #ifdef PNG_FLOATING_POINT_SUPPORTED
  629.    file_gamma = (float)igamma / (float)100000.0;
  630. #  ifdef PNG_READ_GAMMA_SUPPORTED
  631.      png_ptr->gamma = file_gamma;
  632. #  endif
  633.      png_set_gAMA(png_ptr, info_ptr, file_gamma);
  634. #endif
  635. #ifdef PNG_FIXED_POINT_SUPPORTED
  636.    png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
  637. #endif
  638. }
  639. #endif
  640.  
  641. #if defined(PNG_READ_sBIT_SUPPORTED)
  642. void /* PRIVATE */
  643. png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  644. {
  645.    png_size_t truelen;
  646.    png_byte buf[4];
  647.  
  648.    png_debug(1, "in png_handle_sBIT\n");
  649.  
  650.    buf[0] = buf[1] = buf[2] = buf[3] = 0;
  651.  
  652.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  653.       png_error(png_ptr, "Missing IHDR before sBIT");
  654.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  655.    {
  656.       png_warning(png_ptr, "Invalid sBIT after IDAT");
  657.       png_crc_finish(png_ptr, length);
  658.       return;
  659.    }
  660.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  661.    {
  662.       /* Should be an error, but we can cope with it */
  663.       png_warning(png_ptr, "Out of place sBIT chunk");
  664.    }
  665.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
  666.    {
  667.       png_warning(png_ptr, "Duplicate sBIT chunk");
  668.       png_crc_finish(png_ptr, length);
  669.       return;
  670.    }
  671.  
  672.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  673.       truelen = 3;
  674.    else
  675.       truelen = (png_size_t)png_ptr->channels;
  676.  
  677.    if (length != truelen)
  678.    {
  679.       png_warning(png_ptr, "Incorrect sBIT chunk length");
  680.       png_crc_finish(png_ptr, length);
  681.       return;
  682.    }
  683.  
  684.    png_crc_read(png_ptr, buf, truelen);
  685.    if (png_crc_finish(png_ptr, 0))
  686.       return;
  687.  
  688.    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  689.    {
  690.       png_ptr->sig_bit.red = buf[0];
  691.       png_ptr->sig_bit.green = buf[1];
  692.       png_ptr->sig_bit.blue = buf[2];
  693.       png_ptr->sig_bit.alpha = buf[3];
  694.    }
  695.    else
  696.    {
  697.       png_ptr->sig_bit.gray = buf[0];
  698.       png_ptr->sig_bit.red = buf[0];
  699.       png_ptr->sig_bit.green = buf[0];
  700.       png_ptr->sig_bit.blue = buf[0];
  701.       png_ptr->sig_bit.alpha = buf[1];
  702.    }
  703.    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
  704. }
  705. #endif
  706.  
  707. #if defined(PNG_READ_cHRM_SUPPORTED)
  708. void /* PRIVATE */
  709. png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  710. {
  711.    png_byte buf[4];
  712. #ifdef PNG_FLOATING_POINT_SUPPORTED
  713.    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
  714. #endif
  715.    png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
  716.       int_y_green, int_x_blue, int_y_blue;
  717.  
  718.    png_debug(1, "in png_handle_cHRM\n");
  719.  
  720.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  721.       png_error(png_ptr, "Missing IHDR before cHRM");
  722.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  723.    {
  724.       png_warning(png_ptr, "Invalid cHRM after IDAT");
  725.       png_crc_finish(png_ptr, length);
  726.       return;
  727.    }
  728.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  729.       /* Should be an error, but we can cope with it */
  730.       png_warning(png_ptr, "Missing PLTE before cHRM");
  731.  
  732.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
  733. #if defined(PNG_READ_sRGB_SUPPORTED)
  734.       && !(info_ptr->valid & PNG_INFO_sRGB)
  735. #endif
  736.       )
  737.    {
  738.       png_warning(png_ptr, "Duplicate cHRM chunk");
  739.       png_crc_finish(png_ptr, length);
  740.       return;
  741.    }
  742.  
  743.    if (length != 32)
  744.    {
  745.       png_warning(png_ptr, "Incorrect cHRM chunk length");
  746.       png_crc_finish(png_ptr, length);
  747.       return;
  748.    }
  749.  
  750.    png_crc_read(png_ptr, buf, 4);
  751.    int_x_white = (png_fixed_point)png_get_uint_32(buf);
  752.  
  753.    png_crc_read(png_ptr, buf, 4);
  754.    int_y_white = (png_fixed_point)png_get_uint_32(buf);
  755.  
  756.    if (int_x_white > 80000L || int_y_white > 80000L ||
  757.       int_x_white + int_y_white > 100000L)
  758.    {
  759.       png_warning(png_ptr, "Invalid cHRM white point");
  760.       png_crc_finish(png_ptr, 24);
  761.       return;
  762.    }
  763.  
  764.    png_crc_read(png_ptr, buf, 4);
  765.    int_x_red = (png_fixed_point)png_get_uint_32(buf);
  766.  
  767.    png_crc_read(png_ptr, buf, 4);
  768.    int_y_red = (png_fixed_point)png_get_uint_32(buf);
  769.  
  770.    if (int_x_red > 80000L || int_y_red > 80000L ||
  771.       int_x_red + int_y_red > 100000L)
  772.    {
  773.       png_warning(png_ptr, "Invalid cHRM red point");
  774.       png_crc_finish(png_ptr, 16);
  775.       return;
  776.    }
  777.  
  778.    png_crc_read(png_ptr, buf, 4);
  779.    int_x_green = (png_fixed_point)png_get_uint_32(buf);
  780.  
  781.    png_crc_read(png_ptr, buf, 4);
  782.    int_y_green = (png_fixed_point)png_get_uint_32(buf);
  783.  
  784.    if (int_x_green > 80000L || int_y_green > 80000L ||
  785.       int_x_green + int_y_green > 100000L)
  786.    {
  787.       png_warning(png_ptr, "Invalid cHRM green point");
  788.       png_crc_finish(png_ptr, 8);
  789.       return;
  790.    }
  791.  
  792.    png_crc_read(png_ptr, buf, 4);
  793.    int_x_blue = (png_fixed_point)png_get_uint_32(buf);
  794.  
  795.    png_crc_read(png_ptr, buf, 4);
  796.    int_y_blue = (png_fixed_point)png_get_uint_32(buf);
  797.  
  798.    if (int_x_blue > 80000L || int_y_blue > 80000L ||
  799.       int_x_blue + int_y_blue > 100000L)
  800.    {
  801.       png_warning(png_ptr, "Invalid cHRM blue point");
  802.       png_crc_finish(png_ptr, 0);
  803.       return;
  804.    }
  805. #ifdef PNG_FLOATING_POINT_SUPPORTED
  806.    white_x = (float)int_x_white / (float)100000.0;
  807.    white_y = (float)int_y_white / (float)100000.0;
  808.    red_x   = (float)int_x_red   / (float)100000.0;
  809.    red_y   = (float)int_y_red   / (float)100000.0;
  810.    green_x = (float)int_x_green / (float)100000.0;
  811.    green_y = (float)int_y_green / (float)100000.0;
  812.    blue_x  = (float)int_x_blue  / (float)100000.0;
  813.    blue_y  = (float)int_y_blue  / (float)100000.0;
  814. #endif
  815.  
  816. #if defined(PNG_READ_sRGB_SUPPORTED)
  817.    if (info_ptr->valid & PNG_INFO_sRGB)
  818.       {
  819.       if (abs(int_x_white - 31270L) > 1000 ||
  820.           abs(int_y_white - 32900L) > 1000 ||
  821.           abs(  int_x_red - 64000L) > 1000 ||
  822.           abs(  int_y_red - 33000L) > 1000 ||
  823.           abs(int_x_green - 30000L) > 1000 ||
  824.           abs(int_y_green - 60000L) > 1000 ||
  825.           abs( int_x_blue - 15000L) > 1000 ||
  826.           abs( int_y_blue -  6000L) > 1000)
  827.          {
  828.  
  829.             png_warning(png_ptr,
  830.               "Ignoring incorrect cHRM value when sRGB is also present");
  831. #ifndef PNG_NO_CONSOLE_IO
  832. #ifdef PNG_FLOATING_POINT_SUPPORTED
  833.             fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
  834.                white_x, white_y, red_x, red_y);
  835.             fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
  836.                green_x, green_y, blue_x, blue_y);
  837. #else
  838.             fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
  839.                int_x_white, int_y_white, int_x_red, int_y_red);
  840.             fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
  841.                int_x_green, int_y_green, int_x_blue, int_y_blue);
  842. #endif
  843. #endif /* PNG_NO_CONSOLE_IO */
  844.          }
  845.          png_crc_finish(png_ptr, 0);
  846.          return;
  847.       }
  848. #endif /* PNG_READ_sRGB_SUPPORTED */
  849.  
  850. #ifdef PNG_FLOATING_POINT_SUPPORTED
  851.    png_set_cHRM(png_ptr, info_ptr,
  852.       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
  853. #endif
  854. #ifdef PNG_FIXED_POINT_SUPPORTED
  855.    png_set_cHRM_fixed(png_ptr, info_ptr,
  856.       int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
  857.       int_y_green, int_x_blue, int_y_blue);
  858. #endif
  859.    if (png_crc_finish(png_ptr, 0))
  860.       return;
  861. }
  862. #endif
  863.  
  864. #if defined(PNG_READ_sRGB_SUPPORTED)
  865. void /* PRIVATE */
  866. png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  867. {
  868.    int intent;
  869.    png_byte buf[1];
  870.  
  871.    png_debug(1, "in png_handle_sRGB\n");
  872.  
  873.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  874.       png_error(png_ptr, "Missing IHDR before sRGB");
  875.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  876.    {
  877.       png_warning(png_ptr, "Invalid sRGB after IDAT");
  878.       png_crc_finish(png_ptr, length);
  879.       return;
  880.    }
  881.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  882.       /* Should be an error, but we can cope with it */
  883.       png_warning(png_ptr, "Out of place sRGB chunk");
  884.  
  885.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
  886.    {
  887.       png_warning(png_ptr, "Duplicate sRGB chunk");
  888.       png_crc_finish(png_ptr, length);
  889.       return;
  890.    }
  891.  
  892.    if (length != 1)
  893.    {
  894.       png_warning(png_ptr, "Incorrect sRGB chunk length");
  895.       png_crc_finish(png_ptr, length);
  896.       return;
  897.    }
  898.  
  899.    png_crc_read(png_ptr, buf, 1);
  900.    if (png_crc_finish(png_ptr, 0))
  901.       return;
  902.  
  903.    intent = buf[0];
  904.    /* check for bad intent */
  905.    if (intent >= PNG_sRGB_INTENT_LAST)
  906.    {
  907.       png_warning(png_ptr, "Unknown sRGB intent");
  908.       return;
  909.    }
  910.  
  911. #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  912.    if ((info_ptr->valid & PNG_INFO_gAMA))
  913.    {
  914.    int igamma;
  915. #ifdef PNG_FIXED_POINT_SUPPORTED
  916.       igamma=(int)info_ptr->int_gamma;
  917. #else
  918. #  ifdef PNG_FLOATING_POINT_SUPPORTED
  919.       igamma=(int)(info_ptr->gamma * 100000.);
  920. #  endif
  921. #endif
  922. #if 0 && defined(PNG_cHRM_SUPPORTED) && !defined(PNG_FIXED_POINT_SUPPORTED)
  923. /* We need to define these here because they aren't in png.h */
  924.    png_fixed_point int_x_white;
  925.    png_fixed_point int_y_white;
  926.    png_fixed_point int_x_red;
  927.    png_fixed_point int_y_red;
  928.    png_fixed_point int_x_green;
  929.    png_fixed_point int_y_green;
  930.    png_fixed_point int_x_blue;
  931.    png_fixed_point int_y_blue;
  932. #endif
  933.       if(igamma < 45000L || igamma > 46000L)
  934.       {
  935.          png_warning(png_ptr,
  936.            "Ignoring incorrect gAMA value when sRGB is also present");
  937. #ifndef PNG_NO_CONSOLE_IO
  938. #  ifdef PNG_FIXED_POINT_SUPPORTED
  939.         fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
  940. #  else
  941. #    ifdef PNG_FLOATING_POINT_SUPPORTED
  942.          fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
  943. #    endif
  944. #  endif
  945. #endif
  946.       }
  947.    }
  948. #endif /* PNG_READ_gAMA_SUPPORTED */
  949.  
  950. #ifdef PNG_READ_cHRM_SUPPORTED
  951. #ifdef PNG_FIXED_POINT_SUPPORTED
  952.    if (info_ptr->valid & PNG_INFO_cHRM)
  953.       if (abs(info_ptr->int_x_white - 31270L) > 1000 ||
  954.           abs(info_ptr->int_y_white - 32900L) > 1000 ||
  955.           abs(  info_ptr->int_x_red - 64000L) > 1000 ||
  956.           abs(  info_ptr->int_y_red - 33000L) > 1000 ||
  957.           abs(info_ptr->int_x_green - 30000L) > 1000 ||
  958.           abs(info_ptr->int_y_green - 60000L) > 1000 ||
  959.           abs( info_ptr->int_x_blue - 15000L) > 1000 ||
  960.           abs( info_ptr->int_y_blue -  6000L) > 1000)
  961.          {
  962.             png_warning(png_ptr,
  963.               "Ignoring incorrect cHRM value when sRGB is also present");
  964.          }
  965. #endif /* PNG_FIXED_POINT_SUPPORTED */
  966. #endif /* PNG_READ_cHRM_SUPPORTED */
  967.  
  968.    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
  969. }
  970. #endif /* PNG_READ_sRGB_SUPPORTED */
  971.  
  972. #if defined(PNG_READ_iCCP_SUPPORTED)
  973. void /* PRIVATE */
  974. png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  975. /* Note: this does not properly handle chunks that are > 64K under DOS */
  976. {
  977.    png_charp chunkdata;
  978.    png_byte compression_type;
  979.    png_charp profile;
  980.    png_uint_32 skip = 0;
  981.    png_size_t slength, prefix_length, data_length;
  982.  
  983.    png_debug(1, "in png_handle_iCCP\n");
  984.  
  985.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  986.       png_error(png_ptr, "Missing IHDR before iCCP");
  987.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  988.    {
  989.       png_warning(png_ptr, "Invalid iCCP after IDAT");
  990.       png_crc_finish(png_ptr, length);
  991.       return;
  992.    }
  993.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  994.       /* Should be an error, but we can cope with it */
  995.       png_warning(png_ptr, "Out of place iCCP chunk");
  996.  
  997.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
  998.    {
  999.       png_warning(png_ptr, "Duplicate iCCP chunk");
  1000.       png_crc_finish(png_ptr, length);
  1001.       return;
  1002.    }
  1003.  
  1004. #ifdef PNG_MAX_MALLOC_64K
  1005.    if (length > (png_uint_32)65535L)
  1006.    {
  1007.       png_warning(png_ptr, "iCCP chunk too large to fit in memory");
  1008.       skip = length - (png_uint_32)65535L;
  1009.       length = (png_uint_32)65535L;
  1010.    }
  1011. #endif
  1012.  
  1013.    chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
  1014.    slength = (png_size_t)length;
  1015.    png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
  1016.  
  1017.    if (png_crc_finish(png_ptr, skip))
  1018.    {
  1019.       png_free(png_ptr, chunkdata);
  1020.       return;
  1021.    }
  1022.  
  1023.    chunkdata[slength] = 0x00;
  1024.  
  1025.    for (profile = chunkdata; *profile; profile++)
  1026.       /* empty loop to find end of name */ ;
  1027.  
  1028.    ++profile;
  1029.  
  1030.    /* there should be at least one zero (the compression type byte)
  1031.       following the separator, and we should be on it  */
  1032.    if (*profile || profile >= chunkdata + slength)
  1033.    {
  1034.       png_free(png_ptr, chunkdata);
  1035.       png_warning(png_ptr, "malformed iCCP chunk");
  1036.       return;
  1037.    }
  1038.  
  1039.    /* compression_type should always be zero */
  1040.    compression_type = *profile++;
  1041.  
  1042.    prefix_length = profile - chunkdata;
  1043.    chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
  1044.                                     slength, prefix_length, &data_length);
  1045.  
  1046.    png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
  1047.                 chunkdata + prefix_length, data_length);
  1048.    png_free(png_ptr, chunkdata);
  1049. }
  1050. #endif /* PNG_READ_iCCP_SUPPORTED */
  1051.  
  1052. #if defined(PNG_READ_sPLT_SUPPORTED)
  1053. void /* PRIVATE */
  1054. png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1055. /* Note: this does not properly handle chunks that are > 64K under DOS */
  1056. {
  1057.    png_bytep chunkdata;
  1058.    png_bytep entry_start;
  1059.    png_sPLT_t new_palette;
  1060. #ifdef PNG_NO_POINTER_INDEXING
  1061.    png_sPLT_entryp pp;
  1062. #endif
  1063.    int data_length, entry_size, i;
  1064.    png_uint_32 skip = 0;
  1065.    png_size_t slength;
  1066.  
  1067.    png_debug(1, "in png_handle_sPLT\n");
  1068.  
  1069.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1070.       png_error(png_ptr, "Missing IHDR before sPLT");
  1071.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1072.    {
  1073.       png_warning(png_ptr, "Invalid sPLT after IDAT");
  1074.       png_crc_finish(png_ptr, length);
  1075.       return;
  1076.    }
  1077.  
  1078. #ifdef PNG_MAX_MALLOC_64K
  1079.    if (length > (png_uint_32)65535L)
  1080.    {
  1081.       png_warning(png_ptr, "sPLT chunk too large to fit in memory");
  1082.       skip = length - (png_uint_32)65535L;
  1083.       length = (png_uint_32)65535L;
  1084.    }
  1085. #endif
  1086.  
  1087.    chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
  1088.    slength = (png_size_t)length;
  1089.    png_crc_read(png_ptr, chunkdata, slength);
  1090.  
  1091.    if (png_crc_finish(png_ptr, skip))
  1092.    {
  1093.       png_free(png_ptr, chunkdata);
  1094.       return;
  1095.    }
  1096.  
  1097.    chunkdata[slength] = 0x00;
  1098.  
  1099.    for (entry_start = chunkdata; *entry_start; entry_start++)
  1100.       /* empty loop to find end of name */ ;
  1101.    ++entry_start;
  1102.  
  1103.    /* a sample depth should follow the separator, and we should be on it  */
  1104.    if (entry_start > chunkdata + slength)
  1105.    {
  1106.       png_free(png_ptr, chunkdata);
  1107.       png_warning(png_ptr, "malformed sPLT chunk");
  1108.       return;
  1109.    }
  1110.  
  1111.    new_palette.depth = *entry_start++;
  1112.    entry_size = (new_palette.depth == 8 ? 6 : 10);
  1113.    data_length = (slength - (entry_start - chunkdata));
  1114.  
  1115.    /* integrity-check the data length */
  1116.    if (data_length % entry_size)
  1117.    {
  1118.       png_free(png_ptr, chunkdata);
  1119.       png_error(png_ptr, "sPLT chunk has bad length");
  1120.    }
  1121.  
  1122.    new_palette.nentries = data_length / entry_size;
  1123.    new_palette.entries = (png_sPLT_entryp)png_malloc(
  1124.        png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
  1125.  
  1126. #ifndef PNG_NO_POINTER_INDEXING
  1127.    for (i = 0; i < new_palette.nentries; i++)
  1128.    {
  1129.       png_sPLT_entryp pp = new_palette.entries + i;
  1130.  
  1131.       if (new_palette.depth == 8)
  1132.       {
  1133.           pp->red = *entry_start++;
  1134.           pp->green = *entry_start++;
  1135.           pp->blue = *entry_start++;
  1136.           pp->alpha = *entry_start++;
  1137.       }
  1138.       else
  1139.       {
  1140.           pp->red   = png_get_uint_16(entry_start); entry_start += 2;
  1141.           pp->green = png_get_uint_16(entry_start); entry_start += 2;
  1142.           pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
  1143.           pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
  1144.       }
  1145.       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
  1146.    }
  1147. #else
  1148.    pp = new_palette.entries;
  1149.    for (i = 0; i < new_palette.nentries; i++)
  1150.    {
  1151.  
  1152.       if (new_palette.depth == 8)
  1153.       {
  1154.           pp[i].red   = *entry_start++;
  1155.           pp[i].green = *entry_start++;
  1156.           pp[i].blue  = *entry_start++;
  1157.           pp[i].alpha = *entry_start++;
  1158.       }
  1159.       else
  1160.       {
  1161.           pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
  1162.           pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
  1163.           pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
  1164.           pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
  1165.       }
  1166.       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
  1167.    }
  1168. #endif
  1169.  
  1170.    /* discard all chunk data except the name and stash that */
  1171.    new_palette.name = (png_charp)chunkdata;
  1172.  
  1173.    png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
  1174.  
  1175.    png_free(png_ptr, chunkdata);
  1176.    png_free(png_ptr, new_palette.entries);
  1177. }
  1178. #endif /* PNG_READ_sPLT_SUPPORTED */
  1179.  
  1180. #if defined(PNG_READ_tRNS_SUPPORTED)
  1181. void /* PRIVATE */
  1182. png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1183. {
  1184.    png_debug(1, "in png_handle_tRNS\n");
  1185.  
  1186.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1187.       png_error(png_ptr, "Missing IHDR before tRNS");
  1188.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1189.    {
  1190.       png_warning(png_ptr, "Invalid tRNS after IDAT");
  1191.       png_crc_finish(png_ptr, length);
  1192.       return;
  1193.    }
  1194.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  1195.    {
  1196.       png_warning(png_ptr, "Duplicate tRNS chunk");
  1197.       png_crc_finish(png_ptr, length);
  1198.       return;
  1199.    }
  1200.  
  1201.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1202.    {
  1203.       if (!(png_ptr->mode & PNG_HAVE_PLTE))
  1204.       {
  1205.          /* Should be an error, but we can cope with it */
  1206.          png_warning(png_ptr, "Missing PLTE before tRNS");
  1207.       }
  1208.       else if (length > (png_uint_32)png_ptr->num_palette)
  1209.       {
  1210.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  1211.          png_crc_finish(png_ptr, length);
  1212.          return;
  1213.       }
  1214.       if (length == 0)
  1215.       {
  1216.          png_warning(png_ptr, "Zero length tRNS chunk");
  1217.          png_crc_finish(png_ptr, length);
  1218.          return;
  1219.       }
  1220.  
  1221.       png_ptr->trans = (png_bytep)png_malloc(png_ptr, length);
  1222.       png_crc_read(png_ptr, png_ptr->trans, (png_size_t)length);
  1223.       png_ptr->num_trans = (png_uint_16)length;
  1224.    }
  1225.    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  1226.    {
  1227.       png_byte buf[6];
  1228.  
  1229.       if (length != 6)
  1230.       {
  1231.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  1232.          png_crc_finish(png_ptr, length);
  1233.          return;
  1234.       }
  1235.  
  1236.       png_crc_read(png_ptr, buf, (png_size_t)length);
  1237.       png_ptr->num_trans = 1;
  1238.       png_ptr->trans_values.red = png_get_uint_16(buf);
  1239.       png_ptr->trans_values.green = png_get_uint_16(buf + 2);
  1240.       png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
  1241.    }
  1242.    else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  1243.    {
  1244.       png_byte buf[6];
  1245.  
  1246.       if (length != 2)
  1247.       {
  1248.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  1249.          png_crc_finish(png_ptr, length);
  1250.          return;
  1251.       }
  1252.  
  1253.       png_crc_read(png_ptr, buf, 2);
  1254.       png_ptr->num_trans = 1;
  1255.       png_ptr->trans_values.gray = png_get_uint_16(buf);
  1256.    }
  1257.    else
  1258.    {
  1259.       png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
  1260.       png_crc_finish(png_ptr, length);
  1261.       return;
  1262.    }
  1263.  
  1264.    if (png_crc_finish(png_ptr, 0))
  1265.       return;
  1266.  
  1267. #ifdef PNG_FREE_ME_SUPPORTED
  1268.    png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
  1269.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1270.       png_ptr->free_me |= PNG_FREE_TRNS;
  1271. #else
  1272.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1273.       png_ptr->flags |= PNG_FLAG_FREE_TRNS;
  1274. #endif
  1275.    png_set_tRNS(png_ptr, info_ptr, png_ptr->trans, png_ptr->num_trans,
  1276.       &(png_ptr->trans_values));
  1277. }
  1278. #endif
  1279.  
  1280. #if defined(PNG_READ_bKGD_SUPPORTED)
  1281. void /* PRIVATE */
  1282. png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1283. {
  1284.    png_size_t truelen;
  1285.    png_byte buf[6];
  1286.  
  1287.    png_debug(1, "in png_handle_bKGD\n");
  1288.  
  1289.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1290.       png_error(png_ptr, "Missing IHDR before bKGD");
  1291.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1292.    {
  1293.       png_warning(png_ptr, "Invalid bKGD after IDAT");
  1294.       png_crc_finish(png_ptr, length);
  1295.       return;
  1296.    }
  1297.    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  1298.             !(png_ptr->mode & PNG_HAVE_PLTE))
  1299.    {
  1300.       png_warning(png_ptr, "Missing PLTE before bKGD");
  1301.       png_crc_finish(png_ptr, length);
  1302.       return;
  1303.    }
  1304.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
  1305.    {
  1306.       png_warning(png_ptr, "Duplicate bKGD chunk");
  1307.       png_crc_finish(png_ptr, length);
  1308.       return;
  1309.    }
  1310.  
  1311.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1312.       truelen = 1;
  1313.    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1314.       truelen = 6;
  1315.    else
  1316.       truelen = 2;
  1317.  
  1318.    if (length != truelen)
  1319.    {
  1320.       png_warning(png_ptr, "Incorrect bKGD chunk length");
  1321.       png_crc_finish(png_ptr, length);
  1322.       return;
  1323.    }
  1324.  
  1325.    png_crc_read(png_ptr, buf, truelen);
  1326.    if (png_crc_finish(png_ptr, 0))
  1327.       return;
  1328.  
  1329.    /* We convert the index value into RGB components so that we can allow
  1330.     * arbitrary RGB values for background when we have transparency, and
  1331.     * so it is easy to determine the RGB values of the background color
  1332.     * from the info_ptr struct. */
  1333.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1334.    {
  1335.       png_ptr->background.index = buf[0];
  1336.       if(info_ptr->num_palette)
  1337.       {
  1338.           if(buf[0] > info_ptr->num_palette)
  1339.           {
  1340.              png_warning(png_ptr, "Incorrect bKGD chunk index value");
  1341.              png_crc_finish(png_ptr, length);
  1342.              return;
  1343.           }
  1344.           png_ptr->background.red =
  1345.              (png_uint_16)png_ptr->palette[buf[0]].red;
  1346.           png_ptr->background.green =
  1347.              (png_uint_16)png_ptr->palette[buf[0]].green;
  1348.           png_ptr->background.blue =
  1349.              (png_uint_16)png_ptr->palette[buf[0]].blue;
  1350.       }
  1351.    }
  1352.    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
  1353.    {
  1354.       png_ptr->background.red =
  1355.       png_ptr->background.green =
  1356.       png_ptr->background.blue =
  1357.       png_ptr->background.gray = png_get_uint_16(buf);
  1358.    }
  1359.    else
  1360.    {
  1361.       png_ptr->background.red = png_get_uint_16(buf);
  1362.       png_ptr->background.green = png_get_uint_16(buf + 2);
  1363.       png_ptr->background.blue = png_get_uint_16(buf + 4);
  1364.    }
  1365.  
  1366.    png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
  1367. }
  1368. #endif
  1369.  
  1370. #if defined(PNG_READ_hIST_SUPPORTED)
  1371. void /* PRIVATE */
  1372. png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1373. {
  1374.    int num, i;
  1375.  
  1376.    png_debug(1, "in png_handle_hIST\n");
  1377.  
  1378.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1379.       png_error(png_ptr, "Missing IHDR before hIST");
  1380.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1381.    {
  1382.       png_warning(png_ptr, "Invalid hIST after IDAT");
  1383.       png_crc_finish(png_ptr, length);
  1384.       return;
  1385.    }
  1386.    else if (!(png_ptr->mode & PNG_HAVE_PLTE))
  1387.    {
  1388.       png_warning(png_ptr, "Missing PLTE before hIST");
  1389.       png_crc_finish(png_ptr, length);
  1390.       return;
  1391.    }
  1392.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
  1393.    {
  1394.       png_warning(png_ptr, "Duplicate hIST chunk");
  1395.       png_crc_finish(png_ptr, length);
  1396.       return;
  1397.    }
  1398.  
  1399.    if (length != (png_uint_32)(2 * png_ptr->num_palette))
  1400.    {
  1401.       png_warning(png_ptr, "Incorrect hIST chunk length");
  1402.       png_crc_finish(png_ptr, length);
  1403.       return;
  1404.    }
  1405.  
  1406.    num = (int)length / 2 ;
  1407.    png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
  1408.       (png_uint_32)(num * sizeof (png_uint_16)));
  1409.    for (i = 0; i < num; i++)
  1410.    {
  1411.       png_byte buf[2];
  1412.  
  1413.       png_crc_read(png_ptr, buf, 2);
  1414.       png_ptr->hist[i] = png_get_uint_16(buf);
  1415.    }
  1416.  
  1417.    if (png_crc_finish(png_ptr, 0))
  1418.       return;
  1419.  
  1420. #ifdef PNG_FREE_ME_SUPPORTED
  1421.    png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
  1422.    png_ptr->free_me |= PNG_FREE_HIST;
  1423. #else
  1424.    png_ptr->flags |= PNG_FLAG_FREE_HIST;
  1425. #endif
  1426.    png_set_hIST(png_ptr, info_ptr, png_ptr->hist);
  1427. }
  1428. #endif
  1429.  
  1430. #if defined(PNG_READ_pHYs_SUPPORTED)
  1431. void /* PRIVATE */
  1432. png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1433. {
  1434.    png_byte buf[9];
  1435.    png_uint_32 res_x, res_y;
  1436.    int unit_type;
  1437.  
  1438.    png_debug(1, "in png_handle_pHYs\n");
  1439.  
  1440.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1441.       png_error(png_ptr, "Missing IHDR before pHYs");
  1442.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1443.    {
  1444.       png_warning(png_ptr, "Invalid pHYs after IDAT");
  1445.       png_crc_finish(png_ptr, length);
  1446.       return;
  1447.    }
  1448.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  1449.    {
  1450.       png_warning(png_ptr, "Duplicate pHYs chunk");
  1451.       png_crc_finish(png_ptr, length);
  1452.       return;
  1453.    }
  1454.  
  1455.    if (length != 9)
  1456.    {
  1457.       png_warning(png_ptr, "Incorrect pHYs chunk length");
  1458.       png_crc_finish(png_ptr, length);
  1459.       return;
  1460.    }
  1461.  
  1462.    png_crc_read(png_ptr, buf, 9);
  1463.    if (png_crc_finish(png_ptr, 0))
  1464.       return;
  1465.  
  1466.    res_x = png_get_uint_32(buf);
  1467.    res_y = png_get_uint_32(buf + 4);
  1468.    unit_type = buf[8];
  1469.    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
  1470. }
  1471. #endif
  1472.  
  1473. #if defined(PNG_READ_oFFs_SUPPORTED)
  1474. void /* PRIVATE */
  1475. png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1476. {
  1477.    png_byte buf[9];
  1478.    png_int_32 offset_x, offset_y;
  1479.    int unit_type;
  1480.  
  1481.    png_debug(1, "in png_handle_oFFs\n");
  1482.  
  1483.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1484.       png_error(png_ptr, "Missing IHDR before oFFs");
  1485.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1486.    {
  1487.       png_warning(png_ptr, "Invalid oFFs after IDAT");
  1488.       png_crc_finish(png_ptr, length);
  1489.       return;
  1490.    }
  1491.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  1492.    {
  1493.       png_warning(png_ptr, "Duplicate oFFs chunk");
  1494.       png_crc_finish(png_ptr, length);
  1495.       return;
  1496.    }
  1497.  
  1498.    if (length != 9)
  1499.    {
  1500.       png_warning(png_ptr, "Incorrect oFFs chunk length");
  1501.       png_crc_finish(png_ptr, length);
  1502.       return;
  1503.    }
  1504.  
  1505.    png_crc_read(png_ptr, buf, 9);
  1506.    if (png_crc_finish(png_ptr, 0))
  1507.       return;
  1508.  
  1509.    offset_x = png_get_int_32(buf);
  1510.    offset_y = png_get_int_32(buf + 4);
  1511.    unit_type = buf[8];
  1512.    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
  1513. }
  1514. #endif
  1515.  
  1516. #if defined(PNG_READ_pCAL_SUPPORTED)
  1517. /* read the pCAL chunk (described in the PNG Extensions document) */
  1518. void /* PRIVATE */
  1519. png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1520. {
  1521.    png_charp purpose;
  1522.    png_int_32 X0, X1;
  1523.    png_byte type, nparams;
  1524.    png_charp buf, units, endptr;
  1525.    png_charpp params;
  1526.    png_size_t slength;
  1527.    int i;
  1528.  
  1529.    png_debug(1, "in png_handle_pCAL\n");
  1530.  
  1531.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1532.       png_error(png_ptr, "Missing IHDR before pCAL");
  1533.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1534.    {
  1535.       png_warning(png_ptr, "Invalid pCAL after IDAT");
  1536.       png_crc_finish(png_ptr, length);
  1537.       return;
  1538.    }
  1539.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
  1540.    {
  1541.       png_warning(png_ptr, "Duplicate pCAL chunk");
  1542.       png_crc_finish(png_ptr, length);
  1543.       return;
  1544.    }
  1545.  
  1546.    png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
  1547.       length + 1);
  1548.    purpose = (png_charp)png_malloc(png_ptr, length + 1);
  1549.    slength = (png_size_t)length;
  1550.    png_crc_read(png_ptr, (png_bytep)purpose, slength);
  1551.  
  1552.    if (png_crc_finish(png_ptr, 0))
  1553.    {
  1554.       png_free(png_ptr, purpose);
  1555.       return;
  1556.    }
  1557.  
  1558.    purpose[slength] = 0x00; /* null terminate the last string */
  1559.  
  1560.    png_debug(3, "Finding end of pCAL purpose string\n");
  1561.    for (buf = purpose; *buf; buf++)
  1562.       /* empty loop */ ;
  1563.  
  1564.    endptr = purpose + slength;
  1565.  
  1566.    /* We need to have at least 12 bytes after the purpose string
  1567.       in order to get the parameter information. */
  1568.    if (endptr <= buf + 12)
  1569.    {
  1570.       png_warning(png_ptr, "Invalid pCAL data");
  1571.       png_free(png_ptr, purpose);
  1572.       return;
  1573.    }
  1574.  
  1575.    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
  1576.    X0 = png_get_int_32((png_bytep)buf+1);
  1577.    X1 = png_get_int_32((png_bytep)buf+5);
  1578.    type = buf[9];
  1579.    nparams = buf[10];
  1580.    units = buf + 11;
  1581.  
  1582.    png_debug(3, "Checking pCAL equation type and number of parameters\n");
  1583.    /* Check that we have the right number of parameters for known
  1584.       equation types. */
  1585.    if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
  1586.        (type == PNG_EQUATION_BASE_E && nparams != 3) ||
  1587.        (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
  1588.        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
  1589.    {
  1590.       png_warning(png_ptr, "Invalid pCAL parameters for equation type");
  1591.       png_free(png_ptr, purpose);
  1592.       return;
  1593.    }
  1594.    else if (type >= PNG_EQUATION_LAST)
  1595.    {
  1596.       png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
  1597.    }
  1598.  
  1599.    for (buf = units; *buf; buf++)
  1600.       /* Empty loop to move past the units string. */ ;
  1601.  
  1602.    png_debug(3, "Allocating pCAL parameters array\n");
  1603.    params = (png_charpp)png_malloc(png_ptr, (png_uint_32)(nparams
  1604.       *sizeof(png_charp))) ;
  1605.  
  1606.    /* Get pointers to the start of each parameter string. */
  1607.    for (i = 0; i < (int)nparams; i++)
  1608.    {
  1609.       buf++; /* Skip the null string terminator from previous parameter. */
  1610.  
  1611.       png_debug1(3, "Reading pCAL parameter %d\n", i);
  1612.       for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
  1613.          /* Empty loop to move past each parameter string */ ;
  1614.  
  1615.       /* Make sure we haven't run out of data yet */
  1616.       if (buf > endptr)
  1617.       {
  1618.          png_warning(png_ptr, "Invalid pCAL data");
  1619.          png_free(png_ptr, purpose);
  1620.          png_free(png_ptr, params);
  1621.          return;
  1622.       }
  1623.    }
  1624.  
  1625.    png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
  1626.       units, params);
  1627.  
  1628.    png_free(png_ptr, purpose);
  1629.    png_free(png_ptr, params);
  1630. }
  1631. #endif
  1632.  
  1633. #if defined(PNG_READ_sCAL_SUPPORTED)
  1634. /* read the sCAL chunk */
  1635. void /* PRIVATE */
  1636. png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1637. {
  1638.    png_charp buffer, ep;
  1639. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1640.    double width, height;
  1641.    png_charp vp;
  1642. #else
  1643. #ifdef PNG_FIXED_POINT_SUPPORTED
  1644.    png_charp swidth, sheight;
  1645. #endif
  1646. #endif
  1647.    png_size_t slength;
  1648.  
  1649.    png_debug(1, "in png_handle_sCAL\n");
  1650.  
  1651.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1652.       png_error(png_ptr, "Missing IHDR before sCAL");
  1653.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  1654.    {
  1655.       png_warning(png_ptr, "Invalid sCAL after IDAT");
  1656.       png_crc_finish(png_ptr, length);
  1657.       return;
  1658.    }
  1659.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
  1660.    {
  1661.       png_warning(png_ptr, "Duplicate sCAL chunk");
  1662.       png_crc_finish(png_ptr, length);
  1663.       return;
  1664.    }
  1665.  
  1666.    png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
  1667.       length + 1);
  1668.    buffer = (png_charp)png_malloc(png_ptr, length + 1);
  1669.    slength = (png_size_t)length;
  1670.    png_crc_read(png_ptr, (png_bytep)buffer, slength);
  1671.  
  1672.    if (png_crc_finish(png_ptr, 0))
  1673.    {
  1674.       png_free(png_ptr, buffer);
  1675.       return;
  1676.    }
  1677.  
  1678.    buffer[slength] = 0x00; /* null terminate the last string */
  1679.  
  1680.    ep = buffer + 1;        /* skip unit byte */
  1681.  
  1682. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1683.    width = strtod(ep, &vp);
  1684.    if (*vp)
  1685.    {
  1686.        png_warning(png_ptr, "malformed width string in sCAL chunk");
  1687.        return;
  1688.    }
  1689. #else
  1690. #ifdef PNG_FIXED_POINT_SUPPORTED
  1691.    swidth = (png_charp)png_malloc(png_ptr, strlen(ep) + 1);
  1692.    png_memcpy(swidth, ep, (png_size_t)strlen(ep));
  1693. #endif
  1694. #endif
  1695.  
  1696.    for (ep = buffer; *ep; ep++)
  1697.       /* empty loop */ ;
  1698.    ep++;
  1699.  
  1700. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1701.    height = strtod(ep, &vp);
  1702.    if (*vp)
  1703.    {
  1704.        png_warning(png_ptr, "malformed height string in sCAL chunk");
  1705.        return;
  1706.    }
  1707. #else
  1708. #ifdef PNG_FIXED_POINT_SUPPORTED
  1709.    sheight = (png_charp)png_malloc(png_ptr, strlen(ep) + 1);
  1710.    png_memcpy(sheight, ep, (png_size_t)strlen(ep));
  1711. #endif
  1712. #endif
  1713.  
  1714.    if (buffer + slength < ep
  1715. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1716.       || width <= 0. || height <= 0.
  1717. #endif
  1718.       )
  1719.    {
  1720.       png_warning(png_ptr, "Invalid sCAL data");
  1721.       png_free(png_ptr, buffer);
  1722. #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
  1723.       png_free(png_ptr, swidth);
  1724.       png_free(png_ptr, sheight);
  1725. #endif
  1726.       return;
  1727.    }
  1728.  
  1729.  
  1730. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1731.    png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
  1732. #else
  1733. #ifdef PNG_FIXED_POINT_SUPPORTED
  1734.    png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
  1735. #endif
  1736. #endif
  1737.  
  1738.    png_free(png_ptr, buffer);
  1739. #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
  1740.    png_free(png_ptr, swidth);
  1741.    png_free(png_ptr, sheight);
  1742. #endif
  1743. }
  1744. #endif
  1745.  
  1746. #if defined(PNG_READ_tIME_SUPPORTED)
  1747. void /* PRIVATE */
  1748. png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1749. {
  1750.    png_byte buf[7];
  1751.    png_time mod_time;
  1752.  
  1753.    png_debug(1, "in png_handle_tIME\n");
  1754.  
  1755.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1756.       png_error(png_ptr, "Out of place tIME chunk");
  1757.    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
  1758.    {
  1759.       png_warning(png_ptr, "Duplicate tIME chunk");
  1760.       png_crc_finish(png_ptr, length);
  1761.       return;
  1762.    }
  1763.  
  1764.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1765.       png_ptr->mode |= PNG_AFTER_IDAT;
  1766.  
  1767.    if (length != 7)
  1768.    {
  1769.       png_warning(png_ptr, "Incorrect tIME chunk length");
  1770.       png_crc_finish(png_ptr, length);
  1771.       return;
  1772.    }
  1773.  
  1774.    png_crc_read(png_ptr, buf, 7);
  1775.    if (png_crc_finish(png_ptr, 0))
  1776.       return;
  1777.  
  1778.    mod_time.second = buf[6];
  1779.    mod_time.minute = buf[5];
  1780.    mod_time.hour = buf[4];
  1781.    mod_time.day = buf[3];
  1782.    mod_time.month = buf[2];
  1783.    mod_time.year = png_get_uint_16(buf);
  1784.  
  1785.    png_set_tIME(png_ptr, info_ptr, &mod_time);
  1786. }
  1787. #endif
  1788.  
  1789. #if defined(PNG_READ_tEXt_SUPPORTED)
  1790. /* Note: this does not properly handle chunks that are > 64K under DOS */
  1791. void /* PRIVATE */
  1792. png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1793. {
  1794.    png_textp text_ptr;
  1795.    png_charp key;
  1796.    png_charp text;
  1797.    png_uint_32 skip = 0;
  1798.    png_size_t slength;
  1799.  
  1800.    png_debug(1, "in png_handle_tEXt\n");
  1801.  
  1802.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1803.       png_error(png_ptr, "Missing IHDR before tEXt");
  1804.  
  1805.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1806.       png_ptr->mode |= PNG_AFTER_IDAT;
  1807.  
  1808. #ifdef PNG_MAX_MALLOC_64K
  1809.    if (length > (png_uint_32)65535L)
  1810.    {
  1811.       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  1812.       skip = length - (png_uint_32)65535L;
  1813.       length = (png_uint_32)65535L;
  1814.    }
  1815. #endif
  1816.  
  1817.    key = (png_charp)png_malloc(png_ptr, length + 1);
  1818.    slength = (png_size_t)length;
  1819.    png_crc_read(png_ptr, (png_bytep)key, slength);
  1820.  
  1821.    if (png_crc_finish(png_ptr, skip))
  1822.    {
  1823.       png_free(png_ptr, key);
  1824.       return;
  1825.    }
  1826.  
  1827.    key[slength] = 0x00;
  1828.  
  1829.    for (text = key; *text; text++)
  1830.       /* empty loop to find end of key */ ;
  1831.  
  1832.    if (text != key + slength)
  1833.       text++;
  1834.  
  1835.    text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
  1836.    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  1837.    text_ptr->key = key;
  1838. #ifdef PNG_iTXt_SUPPORTED
  1839.    text_ptr->lang = NULL;
  1840.    text_ptr->lang_key = NULL;
  1841.    text_ptr->itxt_length = 0;
  1842. #endif
  1843.    text_ptr->text = text;
  1844.    text_ptr->text_length = png_strlen(text);
  1845.  
  1846.    png_set_text(png_ptr, info_ptr, text_ptr, 1);
  1847.  
  1848.    png_free(png_ptr, key);
  1849.    png_free(png_ptr, text_ptr);
  1850. }
  1851. #endif
  1852.  
  1853. #if defined(PNG_READ_zTXt_SUPPORTED)
  1854. /* note: this does not correctly handle chunks that are > 64K under DOS */
  1855. void /* PRIVATE */
  1856. png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1857. {
  1858.    png_textp text_ptr;
  1859.    png_charp chunkdata;
  1860.    png_charp text;
  1861.    int comp_type;
  1862.    png_size_t slength, prefix_len, data_len;
  1863.  
  1864.    png_debug(1, "in png_handle_zTXt\n");
  1865.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1866.       png_error(png_ptr, "Missing IHDR before zTXt");
  1867.  
  1868.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1869.       png_ptr->mode |= PNG_AFTER_IDAT;
  1870.  
  1871. #ifdef PNG_MAX_MALLOC_64K
  1872.    /* We will no doubt have problems with chunks even half this size, but
  1873.       there is no hard and fast rule to tell us where to stop. */
  1874.    if (length > (png_uint_32)65535L)
  1875.    {
  1876.      png_warning(png_ptr,"zTXt chunk too large to fit in memory");
  1877.      png_crc_finish(png_ptr, length);
  1878.      return;
  1879.    }
  1880. #endif
  1881.  
  1882.    chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
  1883.    slength = (png_size_t)length;
  1884.    png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
  1885.    if (png_crc_finish(png_ptr, 0))
  1886.    {
  1887.       png_free(png_ptr, chunkdata);
  1888.       return;
  1889.    }
  1890.  
  1891.    chunkdata[slength] = 0x00;
  1892.  
  1893.    for (text = chunkdata; *text; text++)
  1894.       /* empty loop */ ;
  1895.  
  1896.    /* zTXt must have some text after the chunkdataword */
  1897.    if (text == chunkdata + slength)
  1898.    {
  1899.       comp_type = PNG_TEXT_COMPRESSION_NONE;
  1900.       png_warning(png_ptr, "Zero length zTXt chunk");
  1901.    }
  1902.    else
  1903.    {
  1904.        comp_type = *(++text);
  1905.        text++;        /* skip the compression_method byte */
  1906.    }
  1907.    prefix_len = text - chunkdata;
  1908.  
  1909.    chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
  1910.                                     (png_size_t)length, prefix_len, &data_len);
  1911.  
  1912.    text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
  1913.    text_ptr->compression = comp_type;
  1914.    text_ptr->key = chunkdata;
  1915. #ifdef PNG_iTXt_SUPPORTED
  1916.    text_ptr->lang = NULL;
  1917.    text_ptr->lang_key = NULL;
  1918.    text_ptr->itxt_length = 0;
  1919. #endif
  1920.    text_ptr->text = chunkdata + prefix_len;
  1921.    text_ptr->text_length = data_len;
  1922.  
  1923.    png_set_text(png_ptr, info_ptr, text_ptr, 1);
  1924.  
  1925.    png_free(png_ptr, text_ptr);
  1926.    png_free(png_ptr, chunkdata);
  1927. }
  1928. #endif
  1929.  
  1930. #if defined(PNG_READ_iTXt_SUPPORTED)
  1931. /* note: this does not correctly handle chunks that are > 64K under DOS */
  1932. void /* PRIVATE */
  1933. png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1934. {
  1935.    png_textp text_ptr;
  1936.    png_charp chunkdata;
  1937.    png_charp key, lang, text, lang_key;
  1938.    int comp_flag;
  1939.    int comp_type = 0;
  1940.    png_size_t slength, prefix_len, data_len;
  1941.  
  1942.    png_debug(1, "in png_handle_iTXt\n");
  1943.  
  1944.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1945.       png_error(png_ptr, "Missing IHDR before iTXt");
  1946.  
  1947.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1948.       png_ptr->mode |= PNG_AFTER_IDAT;
  1949.  
  1950. #ifdef PNG_MAX_MALLOC_64K
  1951.    /* We will no doubt have problems with chunks even half this size, but
  1952.       there is no hard and fast rule to tell us where to stop. */
  1953.    if (length > (png_uint_32)65535L)
  1954.    {
  1955.      png_warning(png_ptr,"iTXt chunk too large to fit in memory");
  1956.      png_crc_finish(png_ptr, length);
  1957.      return;
  1958.    }
  1959. #endif
  1960.  
  1961.    chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
  1962.    slength = (png_size_t)length;
  1963.    png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
  1964.    if (png_crc_finish(png_ptr, 0))
  1965.    {
  1966.       png_free(png_ptr, chunkdata);
  1967.       return;
  1968.    }
  1969.  
  1970.    chunkdata[slength] = 0x00;
  1971.  
  1972.    for (lang = chunkdata; *lang; lang++)
  1973.       /* empty loop */ ;
  1974.    lang++;        /* skip NUL separator */
  1975.  
  1976.    /* iTXt must have a language tag (possibly empty), two compression bytes,
  1977.       translated keyword (possibly empty), and possibly some text after the
  1978.       keyword */
  1979.  
  1980.    if (lang >= chunkdata + slength)
  1981.    {
  1982.       comp_flag = PNG_TEXT_COMPRESSION_NONE;
  1983.       png_warning(png_ptr, "Zero length iTXt chunk");
  1984.    }
  1985.    else
  1986.    {
  1987.        comp_flag = *lang++;
  1988.        comp_type = *lang++;
  1989.    }
  1990.  
  1991.    for (lang_key = lang; *lang_key; lang_key++)
  1992.       /* empty loop */ ;
  1993.    lang_key++;        /* skip NUL separator */
  1994.  
  1995.    for (text = lang_key; *text; text++)
  1996.       /* empty loop */ ;
  1997.    text++;        /* skip NUL separator */
  1998.  
  1999.    prefix_len = text - chunkdata;
  2000.  
  2001.    key=chunkdata;
  2002.    if (comp_flag)
  2003.        chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
  2004.           (size_t)length, prefix_len, &data_len);
  2005.    else
  2006.        data_len=png_strlen(chunkdata + prefix_len);
  2007.    text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
  2008.    text_ptr->compression = (int)comp_flag + 1;
  2009.    text_ptr->lang_key = chunkdata+(lang_key-key);
  2010.    text_ptr->lang = chunkdata+(lang-key);
  2011.    text_ptr->itxt_length = data_len;
  2012.    text_ptr->text_length = 0;
  2013.    text_ptr->key = chunkdata;
  2014.    text_ptr->text = chunkdata + prefix_len;
  2015.  
  2016.    png_set_text(png_ptr, info_ptr, text_ptr, 1);
  2017.  
  2018.    png_free(png_ptr, text_ptr);
  2019.    png_free(png_ptr, chunkdata);
  2020. }
  2021. #endif
  2022.  
  2023. /* This function is called when we haven't found a handler for a
  2024.    chunk.  If there isn't a problem with the chunk itself (ie bad
  2025.    chunk name, CRC, or a critical chunk), the chunk is silently ignored
  2026.    -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
  2027.    case it will be saved away to be written out later. */
  2028. void /* PRIVATE */
  2029. png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  2030. {
  2031.    png_uint_32 skip = 0;
  2032.  
  2033.    png_debug(1, "in png_handle_unknown\n");
  2034.  
  2035.    if (png_ptr->mode & PNG_HAVE_IDAT)
  2036.    {
  2037. #ifdef PNG_USE_LOCAL_ARRAYS
  2038.       PNG_IDAT;
  2039. #endif
  2040.       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* not an IDAT */
  2041.          png_ptr->mode |= PNG_AFTER_IDAT;
  2042.    }
  2043.  
  2044.    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  2045.  
  2046.    if (!(png_ptr->chunk_name[0] & 0x20))
  2047.    {
  2048. #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  2049.       if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  2050.            HANDLE_CHUNK_ALWAYS
  2051. #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  2052.            && png_ptr->read_user_chunk_fn == (png_user_chunk_ptr)NULL
  2053. #endif
  2054.         )
  2055. #endif
  2056.           png_chunk_error(png_ptr, "unknown critical chunk");
  2057.    }
  2058.  
  2059. #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  2060.    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
  2061.    {
  2062.        png_unknown_chunk chunk;
  2063.  
  2064. #ifdef PNG_MAX_MALLOC_64K
  2065.        if (length > (png_uint_32)65535L)
  2066.        {
  2067.            png_warning(png_ptr, "unknown chunk too large to fit in memory");
  2068.            skip = length - (png_uint_32)65535L;
  2069.            length = (png_uint_32)65535L;
  2070.        }
  2071. #endif
  2072.        strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
  2073.        chunk.data = (png_bytep)png_malloc(png_ptr, length);
  2074.        png_crc_read(png_ptr, chunk.data, length);
  2075.        chunk.size = length;
  2076. #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  2077.        if(png_ptr->read_user_chunk_fn != (png_user_chunk_ptr)NULL)
  2078.        {
  2079.           /* callback to user unknown chunk handler */
  2080.           if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
  2081.           {
  2082.              if (!(png_ptr->chunk_name[0] & 0x20))
  2083.                 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  2084.                      HANDLE_CHUNK_ALWAYS)
  2085.                    png_chunk_error(png_ptr, "unknown critical chunk");
  2086.              png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
  2087.           }
  2088.        }
  2089.        else
  2090. #endif
  2091.           png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
  2092.        png_free(png_ptr, chunk.data);
  2093.    }
  2094.    else
  2095. #endif
  2096.       skip = length;
  2097.  
  2098.    png_crc_finish(png_ptr, skip);
  2099.  
  2100. #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  2101.    if (info_ptr == NULL)
  2102.      /* quiet compiler warnings about unused info_ptr */ ;
  2103. #endif
  2104. }
  2105.  
  2106. /* This function is called to verify that a chunk name is valid.
  2107.    This function can't have the "critical chunk check" incorporated
  2108.    into it, since in the future we will need to be able to call user
  2109.    functions to handle unknown critical chunks after we check that
  2110.    the chunk name itself is valid. */
  2111.  
  2112. #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
  2113.  
  2114. void /* PRIVATE */
  2115. png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
  2116. {
  2117.    png_debug(1, "in png_check_chunk_name\n");
  2118.    if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
  2119.        isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
  2120.    {
  2121.       png_chunk_error(png_ptr, "invalid chunk type");
  2122.    }
  2123. }
  2124.  
  2125. /* Combines the row recently read in with the existing pixels in the
  2126.    row.  This routine takes care of alpha and transparency if requested.
  2127.    This routine also handles the two methods of progressive display
  2128.    of interlaced images, depending on the mask value.
  2129.    The mask value describes which pixels are to be combined with
  2130.    the row.  The pattern always repeats every 8 pixels, so just 8
  2131.    bits are needed.  A one indicates the pixel is to be combined,
  2132.    a zero indicates the pixel is to be skipped.  This is in addition
  2133.    to any alpha or transparency value associated with the pixel.  If
  2134.    you want all pixels to be combined, pass 0xff (255) in mask.  */
  2135. void /* PRIVATE */
  2136. #ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
  2137. png_combine_row_c
  2138. #else
  2139. png_combine_row
  2140. #endif /* PNG_HAVE_ASSEMBLER_COMBINE_ROW */
  2141.    (png_structp png_ptr, png_bytep row, int mask)
  2142. {
  2143.    png_debug(1,"in png_combine_row\n");
  2144.    if (mask == 0xff)
  2145.    {
  2146.       png_memcpy(row, png_ptr->row_buf + 1,
  2147.          (png_size_t)((png_ptr->width *
  2148.          png_ptr->row_info.pixel_depth + 7) >> 3));
  2149.    }
  2150.    else
  2151.    {
  2152.       switch (png_ptr->row_info.pixel_depth)
  2153.       {
  2154.          case 1:
  2155.          {
  2156.             png_bytep sp = png_ptr->row_buf + 1;
  2157.             png_bytep dp = row;
  2158.             int s_inc, s_start, s_end;
  2159.             int m = 0x80;
  2160.             int shift;
  2161.             png_uint_32 i;
  2162.             png_uint_32 row_width = png_ptr->width;
  2163.  
  2164. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  2165.             if (png_ptr->transformations & PNG_PACKSWAP)
  2166.             {
  2167.                 s_start = 0;
  2168.                 s_end = 7;
  2169.                 s_inc = 1;
  2170.             }
  2171.             else
  2172. #endif
  2173.             {
  2174.                 s_start = 7;
  2175.                 s_end = 0;
  2176.                 s_inc = -1;
  2177.             }
  2178.  
  2179.             shift = s_start;
  2180.  
  2181.             for (i = 0; i < row_width; i++)
  2182.             {
  2183.                if (m & mask)
  2184.                {
  2185.                   int value;
  2186.  
  2187.                   value = (*sp >> shift) & 0x01;
  2188.                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  2189.                   *dp |= (png_byte)(value << shift);
  2190.                }
  2191.  
  2192.                if (shift == s_end)
  2193.                {
  2194.                   shift = s_start;
  2195.                   sp++;
  2196.                   dp++;
  2197.                }
  2198.                else
  2199.                   shift += s_inc;
  2200.  
  2201.                if (m == 1)
  2202.                   m = 0x80;
  2203.                else
  2204.                   m >>= 1;
  2205.             }
  2206.             break;
  2207.          }
  2208.          case 2:
  2209.          {
  2210.             png_bytep sp = png_ptr->row_buf + 1;
  2211.             png_bytep dp = row;
  2212.             int s_start, s_end, s_inc;
  2213.             int m = 0x80;
  2214.             int shift;
  2215.             png_uint_32 i;
  2216.             png_uint_32 row_width = png_ptr->width;
  2217.             int value;
  2218.  
  2219. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  2220.             if (png_ptr->transformations & PNG_PACKSWAP)
  2221.             {
  2222.                s_start = 0;
  2223.                s_end = 6;
  2224.                s_inc = 2;
  2225.             }
  2226.             else
  2227. #endif
  2228.             {
  2229.                s_start = 6;
  2230.                s_end = 0;
  2231.                s_inc = -2;
  2232.             }
  2233.  
  2234.             shift = s_start;
  2235.  
  2236.             for (i = 0; i < row_width; i++)
  2237.             {
  2238.                if (m & mask)
  2239.                {
  2240.                   value = (*sp >> shift) & 0x03;
  2241.                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  2242.                   *dp |= (png_byte)(value << shift);
  2243.                }
  2244.  
  2245.                if (shift == s_end)
  2246.                {
  2247.                   shift = s_start;
  2248.                   sp++;
  2249.                   dp++;
  2250.                }
  2251.                else
  2252.                   shift += s_inc;
  2253.                if (m == 1)
  2254.                   m = 0x80;
  2255.                else
  2256.                   m >>= 1;
  2257.             }
  2258.             break;
  2259.          }
  2260.          case 4:
  2261.          {
  2262.             png_bytep sp = png_ptr->row_buf + 1;
  2263.             png_bytep dp = row;
  2264.             int s_start, s_end, s_inc;
  2265.             int m = 0x80;
  2266.             int shift;
  2267.             png_uint_32 i;
  2268.             png_uint_32 row_width = png_ptr->width;
  2269.             int value;
  2270.  
  2271. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  2272.             if (png_ptr->transformations & PNG_PACKSWAP)
  2273.             {
  2274.                s_start = 0;
  2275.                s_end = 4;
  2276.                s_inc = 4;
  2277.             }
  2278.             else
  2279. #endif
  2280.             {
  2281.                s_start = 4;
  2282.                s_end = 0;
  2283.                s_inc = -4;
  2284.             }
  2285.             shift = s_start;
  2286.  
  2287.             for (i = 0; i < row_width; i++)
  2288.             {
  2289.                if (m & mask)
  2290.                {
  2291.                   value = (*sp >> shift) & 0xf;
  2292.                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  2293.                   *dp |= (png_byte)(value << shift);
  2294.                }
  2295.  
  2296.                if (shift == s_end)
  2297.                {
  2298.                   shift = s_start;
  2299.                   sp++;
  2300.                   dp++;
  2301.                }
  2302.                else
  2303.                   shift += s_inc;
  2304.                if (m == 1)
  2305.                   m = 0x80;
  2306.                else
  2307.                   m >>= 1;
  2308.             }
  2309.             break;
  2310.          }
  2311.          default:
  2312.          {
  2313.             png_bytep sp = png_ptr->row_buf + 1;
  2314.             png_bytep dp = row;
  2315.             png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
  2316.             png_uint_32 i;
  2317.             png_uint_32 row_width = png_ptr->width;
  2318.             png_byte m = 0x80;
  2319.  
  2320.  
  2321.             for (i = 0; i < row_width; i++)
  2322.             {
  2323.                if (m & mask)
  2324.                {
  2325.                   png_memcpy(dp, sp, pixel_bytes);
  2326.                }
  2327.  
  2328.                sp += pixel_bytes;
  2329.                dp += pixel_bytes;
  2330.  
  2331.                if (m == 1)
  2332.                   m = 0x80;
  2333.                else
  2334.                   m >>= 1;
  2335.             }
  2336.             break;
  2337.          }
  2338.       }
  2339.    }
  2340. }
  2341.  
  2342. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  2343. void /* PRIVATE */
  2344. #ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
  2345. png_do_read_interlace_c
  2346. #else
  2347. png_do_read_interlace
  2348. #endif /* PNG_HAVE_ASSEMBLER_READ_INTERLACE */
  2349.    (png_row_infop row_info, png_bytep row, int pass,
  2350.    png_uint_32 transformations)
  2351. {
  2352. #ifdef PNG_USE_LOCAL_ARRAYS
  2353.    /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  2354.  
  2355.    /* offset to next interlace block */
  2356.    const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  2357. #endif
  2358.  
  2359.    png_debug(1,"in png_do_read_interlace\n");
  2360.    if (row != NULL && row_info != NULL)
  2361.    {
  2362.       png_uint_32 final_width;
  2363.  
  2364.       final_width = row_info->width * png_pass_inc[pass];
  2365.  
  2366.       switch (row_info->pixel_depth)
  2367.       {
  2368.          case 1:
  2369.          {
  2370.             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
  2371.             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
  2372.             int sshift, dshift;
  2373.             int s_start, s_end, s_inc;
  2374.             int jstop = png_pass_inc[pass];
  2375.             png_byte v;
  2376.             png_uint_32 i;
  2377.             int j;
  2378.  
  2379. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  2380.             if (transformations & PNG_PACKSWAP)
  2381.             {
  2382.                 sshift = (int)((row_info->width + 7) & 0x07);
  2383.                 dshift = (int)((final_width + 7) & 0x07);
  2384.                 s_start = 7;
  2385.                 s_end = 0;
  2386.                 s_inc = -1;
  2387.             }
  2388.             else
  2389. #endif
  2390.             {
  2391.                 sshift = 7 - (int)((row_info->width + 7) & 0x07);
  2392.                 dshift = 7 - (int)((final_width + 7) & 0x07);
  2393.                 s_start = 0;
  2394.                 s_end = 7;
  2395.                 s_inc = 1;
  2396.             }
  2397.  
  2398.             for (i = 0; i < row_info->width; i++)
  2399.             {
  2400.                v = (png_byte)((*sp >> sshift) & 0x01);
  2401.                for (j = 0; j < jstop; j++)
  2402.                {
  2403.                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
  2404.                   *dp |= (png_byte)(v << dshift);
  2405.                   if (dshift == s_end)
  2406.                   {
  2407.                      dshift = s_start;
  2408.                      dp--;
  2409.                   }
  2410.                   else
  2411.                      dshift += s_inc;
  2412.                }
  2413.                if (sshift == s_end)
  2414.                {
  2415.                   sshift = s_start;
  2416.                   sp--;
  2417.                }
  2418.                else
  2419.                   sshift += s_inc;
  2420.             }
  2421.             break;
  2422.          }
  2423.          case 2:
  2424.          {
  2425.             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
  2426.             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
  2427.             int sshift, dshift;
  2428.             int s_start, s_end, s_inc;
  2429.             int jstop = png_pass_inc[pass];
  2430.             png_uint_32 i;
  2431.  
  2432. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  2433.             if (transformations & PNG_PACKSWAP)
  2434.             {
  2435.                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
  2436.                dshift = (int)(((final_width + 3) & 0x03) << 1);
  2437.                s_start = 6;
  2438.                s_end = 0;
  2439.                s_inc = -2;
  2440.             }
  2441.             else
  2442. #endif
  2443.             {
  2444.                sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
  2445.                dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
  2446.                s_start = 0;
  2447.                s_end = 6;
  2448.                s_inc = 2;
  2449.             }
  2450.  
  2451.             for (i = 0; i < row_info->width; i++)
  2452.             {
  2453.                png_byte v;
  2454.                int j;
  2455.  
  2456.                v = (png_byte)((*sp >> sshift) & 0x03);
  2457.                for (j = 0; j < jstop; j++)
  2458.                {
  2459.                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
  2460.                   *dp |= (png_byte)(v << dshift);
  2461.                   if (dshift == s_end)
  2462.                   {
  2463.                      dshift = s_start;
  2464.                      dp--;
  2465.                   }
  2466.                   else
  2467.                      dshift += s_inc;
  2468.                }
  2469.                if (sshift == s_end)
  2470.                {
  2471.                   sshift = s_start;
  2472.                   sp--;
  2473.                }
  2474.                else
  2475.                   sshift += s_inc;
  2476.             }
  2477.             break;
  2478.          }
  2479.          case 4:
  2480.          {
  2481.             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
  2482.             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
  2483.             int sshift, dshift;
  2484.             int s_start, s_end, s_inc;
  2485.             png_uint_32 i;
  2486.             int jstop = png_pass_inc[pass];
  2487.  
  2488. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  2489.             if (transformations & PNG_PACKSWAP)
  2490.             {
  2491.                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
  2492.                dshift = (int)(((final_width + 1) & 0x01) << 2);
  2493.                s_start = 4;
  2494.                s_end = 0;
  2495.                s_inc = -4;
  2496.             }
  2497.             else
  2498. #endif
  2499.             {
  2500.                sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
  2501.                dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
  2502.                s_start = 0;
  2503.                s_end = 4;
  2504.                s_inc = 4;
  2505.             }
  2506.  
  2507.             for (i = 0; i < row_info->width; i++)
  2508.             {
  2509.                png_byte v = (png_byte)((*sp >> sshift) & 0xf);
  2510.                int j;
  2511.  
  2512.                for (j = 0; j < jstop; j++)
  2513.                {
  2514.                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
  2515.                   *dp |= (png_byte)(v << dshift);
  2516.                   if (dshift == s_end)
  2517.                   {
  2518.                      dshift = s_start;
  2519.                      dp--;
  2520.                   }
  2521.                   else
  2522.                      dshift += s_inc;
  2523.                }
  2524.                if (sshift == s_end)
  2525.                {
  2526.                   sshift = s_start;
  2527.                   sp--;
  2528.                }
  2529.                else
  2530.                   sshift += s_inc;
  2531.             }
  2532.             break;
  2533.          }
  2534.          default:
  2535.          {
  2536.             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
  2537.             png_bytep sp = row + (png_size_t)(row_info->width - 1) *pixel_bytes;
  2538.             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
  2539.  
  2540.             int jstop = png_pass_inc[pass];
  2541.             png_uint_32 i;
  2542.  
  2543.             for (i = 0; i < row_info->width; i++)
  2544.             {
  2545.                png_byte v[8];
  2546.                int j;
  2547.  
  2548.                png_memcpy(v, sp, pixel_bytes);
  2549.                for (j = 0; j < jstop; j++)
  2550.                {
  2551.                   png_memcpy(dp, v, pixel_bytes);
  2552.                   dp -= pixel_bytes;
  2553.                }
  2554.                sp -= pixel_bytes;
  2555.             }
  2556.             break;
  2557.          }
  2558.       }
  2559.       row_info->width = final_width;
  2560.       row_info->rowbytes = ((final_width *
  2561.          (png_uint_32)row_info->pixel_depth + 7) >> 3);
  2562.    }
  2563. #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
  2564.    /* silence compiler warning */
  2565.    if (transformations)
  2566.       return;
  2567. #endif
  2568. }
  2569. #endif
  2570.  
  2571. void /* PRIVATE */
  2572. #ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
  2573. png_read_filter_row_c
  2574. #else
  2575. png_read_filter_row
  2576. #endif /* PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
  2577.    (png_structp png_ptr, png_row_infop row_info, png_bytep row,
  2578.    png_bytep prev_row, int filter)
  2579. {
  2580.    png_debug(1, "in png_read_filter_row\n");
  2581.    png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
  2582.    switch (filter)
  2583.    {
  2584.       case PNG_FILTER_VALUE_NONE:
  2585.          break;
  2586.       case PNG_FILTER_VALUE_SUB:
  2587.       {
  2588.          png_uint_32 i;
  2589.          png_uint_32 istop = row_info->rowbytes;
  2590.          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
  2591.          png_bytep rp = row + bpp;
  2592.          png_bytep lp = row;
  2593.  
  2594.          for (i = bpp; i < istop; i++)
  2595.          {
  2596.             *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
  2597.             rp++;
  2598.          }
  2599.          break;
  2600.       }
  2601.       case PNG_FILTER_VALUE_UP:
  2602.       {
  2603.          png_uint_32 i;
  2604.          png_uint_32 istop = row_info->rowbytes;
  2605.          png_bytep rp = row;
  2606.          png_bytep pp = prev_row;
  2607.  
  2608.          for (i = 0; i < istop; i++)
  2609.          {
  2610.             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
  2611.             rp++;
  2612.          }
  2613.          break;
  2614.       }
  2615.       case PNG_FILTER_VALUE_AVG:
  2616.       {
  2617.          png_uint_32 i;
  2618.          png_bytep rp = row;
  2619.          png_bytep pp = prev_row;
  2620.          png_bytep lp = row;
  2621.          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
  2622.          png_uint_32 istop = row_info->rowbytes - bpp;
  2623.  
  2624.          for (i = 0; i < bpp; i++)
  2625.          {
  2626.             *rp = (png_byte)(((int)(*rp) +
  2627.                ((int)(*pp++) / 2 )) & 0xff);
  2628.             rp++;
  2629.          }
  2630.  
  2631.          for (i = 0; i < istop; i++)
  2632.          {
  2633.             *rp = (png_byte)(((int)(*rp) +
  2634.                (int)(*pp++ + *lp++) / 2 ) & 0xff);
  2635.             rp++;
  2636.          }
  2637.          break;
  2638.       }
  2639.       case PNG_FILTER_VALUE_PAETH:
  2640.       {
  2641.          png_uint_32 i;
  2642.          png_bytep rp = row;
  2643.          png_bytep pp = prev_row;
  2644.          png_bytep lp = row;
  2645.          png_bytep cp = prev_row;
  2646.          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
  2647.          png_uint_32 istop=row_info->rowbytes - bpp;
  2648.  
  2649.          for (i = 0; i < bpp; i++)
  2650.          {
  2651.             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
  2652.             rp++;
  2653.          }
  2654.  
  2655.          for (i = 0; i < istop; i++)   /* use leftover rp,pp */
  2656.          {
  2657.             int a, b, c, pa, pb, pc, p;
  2658.  
  2659.             a = *lp++;
  2660.             b = *pp++;
  2661.             c = *cp++;
  2662.  
  2663.             p = b - c;
  2664.             pc = a - c;
  2665.  
  2666. #ifdef PNG_USE_ABS
  2667.             pa = abs(p);
  2668.             pb = abs(pc);
  2669.             pc = abs(p + pc);
  2670. #else
  2671.             pa = p < 0 ? -p : p;
  2672.             pb = pc < 0 ? -pc : pc;
  2673.             pc = (p + pc) < 0 ? -(p + pc) : p + pc;
  2674. #endif
  2675.  
  2676.             /*
  2677.                if (pa <= pb && pa <= pc)
  2678.                   p = a;
  2679.                else if (pb <= pc)
  2680.                   p = b;
  2681.                else
  2682.                   p = c;
  2683.              */
  2684.  
  2685.             p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
  2686.  
  2687.             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
  2688.             rp++;
  2689.          }
  2690.          break;
  2691.       }
  2692.       default:
  2693.          png_warning(png_ptr, "Ignoring bad adaptive filter type");
  2694.          *row=0;
  2695.          break;
  2696.    }
  2697. }
  2698.  
  2699. void /* PRIVATE */
  2700. png_read_finish_row(png_structp png_ptr)
  2701. {
  2702. #ifdef PNG_USE_LOCAL_ARRAYS
  2703.    /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  2704.  
  2705.    /* start of interlace block */
  2706.    const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  2707.  
  2708.    /* offset to next interlace block */
  2709.    const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  2710.  
  2711.    /* start of interlace block in the y direction */
  2712.    const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  2713.  
  2714.    /* offset to next interlace block in the y direction */
  2715.    const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  2716. #endif
  2717.  
  2718.    png_debug(1, "in png_read_finish_row\n");
  2719.    png_ptr->row_number++;
  2720.    if (png_ptr->row_number < png_ptr->num_rows)
  2721.       return;
  2722.  
  2723.    if (png_ptr->interlaced)
  2724.    {
  2725.       png_ptr->row_number = 0;
  2726.       png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  2727.       do
  2728.       {
  2729.          png_ptr->pass++;
  2730.          if (png_ptr->pass >= 7)
  2731.             break;
  2732.          png_ptr->iwidth = (png_ptr->width +
  2733.             png_pass_inc[png_ptr->pass] - 1 -
  2734.             png_pass_start[png_ptr->pass]) /
  2735.             png_pass_inc[png_ptr->pass];
  2736.             png_ptr->irowbytes = ((png_ptr->iwidth *
  2737.                (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
  2738.  
  2739.          if (!(png_ptr->transformations & PNG_INTERLACE))
  2740.          {
  2741.             png_ptr->num_rows = (png_ptr->height +
  2742.                png_pass_yinc[png_ptr->pass] - 1 -
  2743.                png_pass_ystart[png_ptr->pass]) /
  2744.                png_pass_yinc[png_ptr->pass];
  2745.             if (!(png_ptr->num_rows))
  2746.                continue;
  2747.          }
  2748.          else  /* if (png_ptr->transformations & PNG_INTERLACE) */
  2749.             break;
  2750.       } while (png_ptr->iwidth == 0);
  2751.  
  2752.       if (png_ptr->pass < 7)
  2753.          return;
  2754.    }
  2755.  
  2756.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  2757.    {
  2758. #ifdef PNG_USE_LOCAL_ARRAYS
  2759.       PNG_IDAT;
  2760. #endif
  2761.       char extra;
  2762.       int ret;
  2763.  
  2764.       png_ptr->zstream.next_out = (Byte *)&extra;
  2765.       png_ptr->zstream.avail_out = (uInt)1;
  2766.       for(;;)
  2767.       {
  2768.          if (!(png_ptr->zstream.avail_in))
  2769.          {
  2770.             while (!png_ptr->idat_size)
  2771.             {
  2772.                png_byte chunk_length[4];
  2773.  
  2774.                png_crc_finish(png_ptr, 0);
  2775.  
  2776.                png_read_data(png_ptr, chunk_length, 4);
  2777.                png_ptr->idat_size = png_get_uint_32(chunk_length);
  2778.  
  2779.                png_reset_crc(png_ptr);
  2780.                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  2781.                if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
  2782.                   png_error(png_ptr, "Not enough image data");
  2783.  
  2784.             }
  2785.             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
  2786.             png_ptr->zstream.next_in = png_ptr->zbuf;
  2787.             if (png_ptr->zbuf_size > png_ptr->idat_size)
  2788.                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
  2789.             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
  2790.             png_ptr->idat_size -= png_ptr->zstream.avail_in;
  2791.          }
  2792.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  2793.          if (ret == Z_STREAM_END)
  2794.          {
  2795.             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
  2796.                png_ptr->idat_size)
  2797.                png_error(png_ptr, "Extra compressed data");
  2798.             png_ptr->mode |= PNG_AFTER_IDAT;
  2799.             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  2800.             break;
  2801.          }
  2802.          if (ret != Z_OK)
  2803.             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
  2804.                       "Decompression Error");
  2805.  
  2806.          if (!(png_ptr->zstream.avail_out))
  2807.             png_error(png_ptr, "Extra compressed data");
  2808.  
  2809.       }
  2810.       png_ptr->zstream.avail_out = 0;
  2811.    }
  2812.  
  2813.    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
  2814.       png_error(png_ptr, "Extra compression data");
  2815.  
  2816.    inflateReset(&png_ptr->zstream);
  2817.  
  2818.    png_ptr->mode |= PNG_AFTER_IDAT;
  2819. }
  2820.  
  2821. void /* PRIVATE */
  2822. png_read_start_row(png_structp png_ptr)
  2823. {
  2824. #ifdef PNG_USE_LOCAL_ARRAYS
  2825.    /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  2826.  
  2827.    /* start of interlace block */
  2828.    const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  2829.  
  2830.    /* offset to next interlace block */
  2831.    const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  2832.  
  2833.    /* start of interlace block in the y direction */
  2834.    const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  2835.  
  2836.    /* offset to next interlace block in the y direction */
  2837.    const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  2838. #endif
  2839.  
  2840.    int max_pixel_depth;
  2841.    png_uint_32 row_bytes;
  2842.  
  2843.    png_debug(1, "in png_read_start_row\n");
  2844.    png_ptr->zstream.avail_in = 0;
  2845.    png_init_read_transformations(png_ptr);
  2846.    if (png_ptr->interlaced)
  2847.    {
  2848.       if (!(png_ptr->transformations & PNG_INTERLACE))
  2849.          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  2850.             png_pass_ystart[0]) / png_pass_yinc[0];
  2851.       else
  2852.          png_ptr->num_rows = png_ptr->height;
  2853.  
  2854.       png_ptr->iwidth = (png_ptr->width +
  2855.          png_pass_inc[png_ptr->pass] - 1 -
  2856.          png_pass_start[png_ptr->pass]) /
  2857.          png_pass_inc[png_ptr->pass];
  2858.  
  2859.          row_bytes = ((png_ptr->iwidth *
  2860.             (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
  2861.          png_ptr->irowbytes = (png_size_t)row_bytes;
  2862.          if((png_uint_32)png_ptr->irowbytes != row_bytes)
  2863.             png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
  2864.    }
  2865.    else
  2866.    {
  2867.       png_ptr->num_rows = png_ptr->height;
  2868.       png_ptr->iwidth = png_ptr->width;
  2869.       png_ptr->irowbytes = png_ptr->rowbytes + 1;
  2870.    }
  2871.    max_pixel_depth = png_ptr->pixel_depth;
  2872.  
  2873. #if defined(PNG_READ_PACK_SUPPORTED)
  2874.    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
  2875.       max_pixel_depth = 8;
  2876. #endif
  2877.  
  2878. #if defined(PNG_READ_EXPAND_SUPPORTED)
  2879.    if (png_ptr->transformations & PNG_EXPAND)
  2880.    {
  2881.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  2882.       {
  2883.          if (png_ptr->num_trans)
  2884.             max_pixel_depth = 32;
  2885.          else
  2886.             max_pixel_depth = 24;
  2887.       }
  2888.       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  2889.       {
  2890.          if (max_pixel_depth < 8)
  2891.             max_pixel_depth = 8;
  2892.          if (png_ptr->num_trans)
  2893.             max_pixel_depth *= 2;
  2894.       }
  2895.       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  2896.       {
  2897.          if (png_ptr->num_trans)
  2898.          {
  2899.             max_pixel_depth *= 4;
  2900.             max_pixel_depth /= 3;
  2901.          }
  2902.       }
  2903.    }
  2904. #endif
  2905.  
  2906. #if defined(PNG_READ_FILLER_SUPPORTED)
  2907.    if (png_ptr->transformations & (PNG_FILLER))
  2908.    {
  2909.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  2910.          max_pixel_depth = 32;
  2911.       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  2912.       {
  2913.          if (max_pixel_depth <= 8)
  2914.             max_pixel_depth = 16;
  2915.          else
  2916.             max_pixel_depth = 32;
  2917.       }
  2918.       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  2919.       {
  2920.          if (max_pixel_depth <= 32)
  2921.             max_pixel_depth = 32;
  2922.          else
  2923.             max_pixel_depth = 64;
  2924.       }
  2925.    }
  2926. #endif
  2927.  
  2928. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  2929.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  2930.    {
  2931.       if (
  2932. #if defined(PNG_READ_EXPAND_SUPPORTED)
  2933.         (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
  2934. #endif
  2935. #if defined(PNG_READ_FILLER_SUPPORTED)
  2936.         (png_ptr->transformations & (PNG_FILLER)) ||
  2937. #endif
  2938.         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  2939.       {
  2940.          if (max_pixel_depth <= 16)
  2941.             max_pixel_depth = 32;
  2942.          else
  2943.             max_pixel_depth = 64;
  2944.       }
  2945.       else
  2946.       {
  2947.          if (max_pixel_depth <= 8)
  2948.            {
  2949.              if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  2950.                max_pixel_depth = 32;
  2951.              else
  2952.                max_pixel_depth = 24;
  2953.            }
  2954.          else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  2955.             max_pixel_depth = 64;
  2956.          else
  2957.             max_pixel_depth = 48;
  2958.       }
  2959.    }
  2960. #endif
  2961.  
  2962. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
  2963. defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
  2964.    if(png_ptr->transformations & PNG_USER_TRANSFORM)
  2965.      {
  2966.        int user_pixel_depth=png_ptr->user_transform_depth*
  2967.          png_ptr->user_transform_channels;
  2968.        if(user_pixel_depth > max_pixel_depth)
  2969.          max_pixel_depth=user_pixel_depth;
  2970.      }
  2971. #endif
  2972.  
  2973.    /* align the width on the next larger 8 pixels.  Mainly used
  2974.       for interlacing */
  2975.    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
  2976.    /* calculate the maximum bytes needed, adding a byte and a pixel
  2977.       for safety's sake */
  2978.    row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
  2979.       1 + ((max_pixel_depth + 7) >> 3);
  2980. #ifdef PNG_MAX_MALLOC_64K
  2981.    if (row_bytes > (png_uint_32)65536L)
  2982.       png_error(png_ptr, "This image requires a row greater than 64KB");
  2983. #endif
  2984.    png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, row_bytes);
  2985.  
  2986. #ifdef PNG_MAX_MALLOC_64K
  2987.    if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
  2988.       png_error(png_ptr, "This image requires a row greater than 64KB");
  2989. #endif
  2990.    png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
  2991.       png_ptr->rowbytes + 1));
  2992.  
  2993.    png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  2994.  
  2995.    png_debug1(3, "width = %lu,\n", png_ptr->width);
  2996.    png_debug1(3, "height = %lu,\n", png_ptr->height);
  2997.    png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
  2998.    png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
  2999.    png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
  3000.    png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
  3001.  
  3002.    png_ptr->flags |= PNG_FLAG_ROW_INIT;
  3003. }
  3004.