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