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