istereo

diff libs/libpng/pngpread.c @ 26:862a3329a8f0

wohooo, added a shitload of code from zlib/libpng/libjpeg. When the good lord was raining shared libraries the iphone held a fucking umbrella...
author John Tsiombikas <nuclear@mutantstargoat.com>
date Thu, 08 Sep 2011 06:28:38 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/libpng/pngpread.c	Thu Sep 08 06:28:38 2011 +0300
     1.3 @@ -0,0 +1,1594 @@
     1.4 +
     1.5 +/* pngpread.c - read a png file in push mode
     1.6 + *
     1.7 + * Last changed in libpng 1.2.32 [September 18, 2008]
     1.8 + * For conditions of distribution and use, see copyright notice in png.h
     1.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson
    1.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
    1.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
    1.12 + */
    1.13 +
    1.14 +#define PNG_INTERNAL
    1.15 +#include "png.h"
    1.16 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    1.17 +
    1.18 +/* push model modes */
    1.19 +#define PNG_READ_SIG_MODE   0
    1.20 +#define PNG_READ_CHUNK_MODE 1
    1.21 +#define PNG_READ_IDAT_MODE  2
    1.22 +#define PNG_SKIP_MODE       3
    1.23 +#define PNG_READ_tEXt_MODE  4
    1.24 +#define PNG_READ_zTXt_MODE  5
    1.25 +#define PNG_READ_DONE_MODE  6
    1.26 +#define PNG_READ_iTXt_MODE  7
    1.27 +#define PNG_ERROR_MODE      8
    1.28 +
    1.29 +void PNGAPI
    1.30 +png_process_data(png_structp png_ptr, png_infop info_ptr,
    1.31 +   png_bytep buffer, png_size_t buffer_size)
    1.32 +{
    1.33 +   if (png_ptr == NULL || info_ptr == NULL) return;
    1.34 +   png_push_restore_buffer(png_ptr, buffer, buffer_size);
    1.35 +
    1.36 +   while (png_ptr->buffer_size)
    1.37 +   {
    1.38 +      png_process_some_data(png_ptr, info_ptr);
    1.39 +   }
    1.40 +}
    1.41 +
    1.42 +/* What we do with the incoming data depends on what we were previously
    1.43 + * doing before we ran out of data...
    1.44 + */
    1.45 +void /* PRIVATE */
    1.46 +png_process_some_data(png_structp png_ptr, png_infop info_ptr)
    1.47 +{
    1.48 +   if (png_ptr == NULL) return;
    1.49 +   switch (png_ptr->process_mode)
    1.50 +   {
    1.51 +      case PNG_READ_SIG_MODE:
    1.52 +      {
    1.53 +         png_push_read_sig(png_ptr, info_ptr);
    1.54 +         break;
    1.55 +      }
    1.56 +      case PNG_READ_CHUNK_MODE:
    1.57 +      {
    1.58 +         png_push_read_chunk(png_ptr, info_ptr);
    1.59 +         break;
    1.60 +      }
    1.61 +      case PNG_READ_IDAT_MODE:
    1.62 +      {
    1.63 +         png_push_read_IDAT(png_ptr);
    1.64 +         break;
    1.65 +      }
    1.66 +#if defined(PNG_READ_tEXt_SUPPORTED)
    1.67 +      case PNG_READ_tEXt_MODE:
    1.68 +      {
    1.69 +         png_push_read_tEXt(png_ptr, info_ptr);
    1.70 +         break;
    1.71 +      }
    1.72 +#endif
    1.73 +#if defined(PNG_READ_zTXt_SUPPORTED)
    1.74 +      case PNG_READ_zTXt_MODE:
    1.75 +      {
    1.76 +         png_push_read_zTXt(png_ptr, info_ptr);
    1.77 +         break;
    1.78 +      }
    1.79 +#endif
    1.80 +#if defined(PNG_READ_iTXt_SUPPORTED)
    1.81 +      case PNG_READ_iTXt_MODE:
    1.82 +      {
    1.83 +         png_push_read_iTXt(png_ptr, info_ptr);
    1.84 +         break;
    1.85 +      }
    1.86 +#endif
    1.87 +      case PNG_SKIP_MODE:
    1.88 +      {
    1.89 +         png_push_crc_finish(png_ptr);
    1.90 +         break;
    1.91 +      }
    1.92 +      default:
    1.93 +      {
    1.94 +         png_ptr->buffer_size = 0;
    1.95 +         break;
    1.96 +      }
    1.97 +   }
    1.98 +}
    1.99 +
   1.100 +/* Read any remaining signature bytes from the stream and compare them with
   1.101 + * the correct PNG signature.  It is possible that this routine is called
   1.102 + * with bytes already read from the signature, either because they have been
   1.103 + * checked by the calling application, or because of multiple calls to this
   1.104 + * routine.
   1.105 + */
   1.106 +void /* PRIVATE */
   1.107 +png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
   1.108 +{
   1.109 +   png_size_t num_checked = png_ptr->sig_bytes,
   1.110 +             num_to_check = 8 - num_checked;
   1.111 +
   1.112 +   if (png_ptr->buffer_size < num_to_check)
   1.113 +   {
   1.114 +      num_to_check = png_ptr->buffer_size;
   1.115 +   }
   1.116 +
   1.117 +   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
   1.118 +      num_to_check);
   1.119 +   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
   1.120 +
   1.121 +   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
   1.122 +   {
   1.123 +      if (num_checked < 4 &&
   1.124 +          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
   1.125 +         png_error(png_ptr, "Not a PNG file");
   1.126 +      else
   1.127 +         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
   1.128 +   }
   1.129 +   else
   1.130 +   {
   1.131 +      if (png_ptr->sig_bytes >= 8)
   1.132 +      {
   1.133 +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.134 +      }
   1.135 +   }
   1.136 +}
   1.137 +
   1.138 +void /* PRIVATE */
   1.139 +png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
   1.140 +{
   1.141 +#ifdef PNG_USE_LOCAL_ARRAYS
   1.142 +      PNG_CONST PNG_IHDR;
   1.143 +      PNG_CONST PNG_IDAT;
   1.144 +      PNG_CONST PNG_IEND;
   1.145 +      PNG_CONST PNG_PLTE;
   1.146 +#if defined(PNG_READ_bKGD_SUPPORTED)
   1.147 +      PNG_CONST PNG_bKGD;
   1.148 +#endif
   1.149 +#if defined(PNG_READ_cHRM_SUPPORTED)
   1.150 +      PNG_CONST PNG_cHRM;
   1.151 +#endif
   1.152 +#if defined(PNG_READ_gAMA_SUPPORTED)
   1.153 +      PNG_CONST PNG_gAMA;
   1.154 +#endif
   1.155 +#if defined(PNG_READ_hIST_SUPPORTED)
   1.156 +      PNG_CONST PNG_hIST;
   1.157 +#endif
   1.158 +#if defined(PNG_READ_iCCP_SUPPORTED)
   1.159 +      PNG_CONST PNG_iCCP;
   1.160 +#endif
   1.161 +#if defined(PNG_READ_iTXt_SUPPORTED)
   1.162 +      PNG_CONST PNG_iTXt;
   1.163 +#endif
   1.164 +#if defined(PNG_READ_oFFs_SUPPORTED)
   1.165 +      PNG_CONST PNG_oFFs;
   1.166 +#endif
   1.167 +#if defined(PNG_READ_pCAL_SUPPORTED)
   1.168 +      PNG_CONST PNG_pCAL;
   1.169 +#endif
   1.170 +#if defined(PNG_READ_pHYs_SUPPORTED)
   1.171 +      PNG_CONST PNG_pHYs;
   1.172 +#endif
   1.173 +#if defined(PNG_READ_sBIT_SUPPORTED)
   1.174 +      PNG_CONST PNG_sBIT;
   1.175 +#endif
   1.176 +#if defined(PNG_READ_sCAL_SUPPORTED)
   1.177 +      PNG_CONST PNG_sCAL;
   1.178 +#endif
   1.179 +#if defined(PNG_READ_sRGB_SUPPORTED)
   1.180 +      PNG_CONST PNG_sRGB;
   1.181 +#endif
   1.182 +#if defined(PNG_READ_sPLT_SUPPORTED)
   1.183 +      PNG_CONST PNG_sPLT;
   1.184 +#endif
   1.185 +#if defined(PNG_READ_tEXt_SUPPORTED)
   1.186 +      PNG_CONST PNG_tEXt;
   1.187 +#endif
   1.188 +#if defined(PNG_READ_tIME_SUPPORTED)
   1.189 +      PNG_CONST PNG_tIME;
   1.190 +#endif
   1.191 +#if defined(PNG_READ_tRNS_SUPPORTED)
   1.192 +      PNG_CONST PNG_tRNS;
   1.193 +#endif
   1.194 +#if defined(PNG_READ_zTXt_SUPPORTED)
   1.195 +      PNG_CONST PNG_zTXt;
   1.196 +#endif
   1.197 +#endif /* PNG_USE_LOCAL_ARRAYS */
   1.198 +   /* First we make sure we have enough data for the 4 byte chunk name
   1.199 +    * and the 4 byte chunk length before proceeding with decoding the
   1.200 +    * chunk data.  To fully decode each of these chunks, we also make
   1.201 +    * sure we have enough data in the buffer for the 4 byte CRC at the
   1.202 +    * end of every chunk (except IDAT, which is handled separately).
   1.203 +    */
   1.204 +   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
   1.205 +   {
   1.206 +      png_byte chunk_length[4];
   1.207 +
   1.208 +      if (png_ptr->buffer_size < 8)
   1.209 +      {
   1.210 +         png_push_save_buffer(png_ptr);
   1.211 +         return;
   1.212 +      }
   1.213 +
   1.214 +      png_push_fill_buffer(png_ptr, chunk_length, 4);
   1.215 +      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
   1.216 +      png_reset_crc(png_ptr);
   1.217 +      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
   1.218 +      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
   1.219 +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
   1.220 +   }
   1.221 +
   1.222 +   if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
   1.223 +     if (png_ptr->mode & PNG_AFTER_IDAT)
   1.224 +        png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
   1.225 +
   1.226 +   if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
   1.227 +   {
   1.228 +      if (png_ptr->push_length != 13)
   1.229 +         png_error(png_ptr, "Invalid IHDR length");
   1.230 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.231 +      {
   1.232 +         png_push_save_buffer(png_ptr);
   1.233 +         return;
   1.234 +      }
   1.235 +      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
   1.236 +   }
   1.237 +   else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
   1.238 +   {
   1.239 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.240 +      {
   1.241 +         png_push_save_buffer(png_ptr);
   1.242 +         return;
   1.243 +      }
   1.244 +      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
   1.245 +
   1.246 +      png_ptr->process_mode = PNG_READ_DONE_MODE;
   1.247 +      png_push_have_end(png_ptr, info_ptr);
   1.248 +   }
   1.249 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   1.250 +   else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
   1.251 +   {
   1.252 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.253 +      {
   1.254 +         png_push_save_buffer(png_ptr);
   1.255 +         return;
   1.256 +      }
   1.257 +      if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
   1.258 +         png_ptr->mode |= PNG_HAVE_IDAT;
   1.259 +      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
   1.260 +      if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
   1.261 +         png_ptr->mode |= PNG_HAVE_PLTE;
   1.262 +      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
   1.263 +      {
   1.264 +         if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1.265 +            png_error(png_ptr, "Missing IHDR before IDAT");
   1.266 +         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
   1.267 +                  !(png_ptr->mode & PNG_HAVE_PLTE))
   1.268 +            png_error(png_ptr, "Missing PLTE before IDAT");
   1.269 +      }
   1.270 +   }
   1.271 +#endif
   1.272 +   else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
   1.273 +   {
   1.274 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.275 +      {
   1.276 +         png_push_save_buffer(png_ptr);
   1.277 +         return;
   1.278 +      }
   1.279 +      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
   1.280 +   }
   1.281 +   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
   1.282 +   {
   1.283 +      /* If we reach an IDAT chunk, this means we have read all of the
   1.284 +       * header chunks, and we can start reading the image (or if this
   1.285 +       * is called after the image has been read - we have an error).
   1.286 +       */
   1.287 +     if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1.288 +       png_error(png_ptr, "Missing IHDR before IDAT");
   1.289 +     else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
   1.290 +         !(png_ptr->mode & PNG_HAVE_PLTE))
   1.291 +       png_error(png_ptr, "Missing PLTE before IDAT");
   1.292 +
   1.293 +      if (png_ptr->mode & PNG_HAVE_IDAT)
   1.294 +      {
   1.295 +         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
   1.296 +           if (png_ptr->push_length == 0)
   1.297 +              return;
   1.298 +
   1.299 +         if (png_ptr->mode & PNG_AFTER_IDAT)
   1.300 +            png_error(png_ptr, "Too many IDAT's found");
   1.301 +      }
   1.302 +
   1.303 +      png_ptr->idat_size = png_ptr->push_length;
   1.304 +      png_ptr->mode |= PNG_HAVE_IDAT;
   1.305 +      png_ptr->process_mode = PNG_READ_IDAT_MODE;
   1.306 +      png_push_have_info(png_ptr, info_ptr);
   1.307 +      png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
   1.308 +      png_ptr->zstream.next_out = png_ptr->row_buf;
   1.309 +      return;
   1.310 +   }
   1.311 +#if defined(PNG_READ_gAMA_SUPPORTED)
   1.312 +   else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
   1.313 +   {
   1.314 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.315 +      {
   1.316 +         png_push_save_buffer(png_ptr);
   1.317 +         return;
   1.318 +      }
   1.319 +      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
   1.320 +   }
   1.321 +#endif
   1.322 +#if defined(PNG_READ_sBIT_SUPPORTED)
   1.323 +   else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
   1.324 +   {
   1.325 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.326 +      {
   1.327 +         png_push_save_buffer(png_ptr);
   1.328 +         return;
   1.329 +      }
   1.330 +      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
   1.331 +   }
   1.332 +#endif
   1.333 +#if defined(PNG_READ_cHRM_SUPPORTED)
   1.334 +   else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
   1.335 +   {
   1.336 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.337 +      {
   1.338 +         png_push_save_buffer(png_ptr);
   1.339 +         return;
   1.340 +      }
   1.341 +      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
   1.342 +   }
   1.343 +#endif
   1.344 +#if defined(PNG_READ_sRGB_SUPPORTED)
   1.345 +   else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
   1.346 +   {
   1.347 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.348 +      {
   1.349 +         png_push_save_buffer(png_ptr);
   1.350 +         return;
   1.351 +      }
   1.352 +      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
   1.353 +   }
   1.354 +#endif
   1.355 +#if defined(PNG_READ_iCCP_SUPPORTED)
   1.356 +   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
   1.357 +   {
   1.358 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.359 +      {
   1.360 +         png_push_save_buffer(png_ptr);
   1.361 +         return;
   1.362 +      }
   1.363 +      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
   1.364 +   }
   1.365 +#endif
   1.366 +#if defined(PNG_READ_sPLT_SUPPORTED)
   1.367 +   else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
   1.368 +   {
   1.369 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.370 +      {
   1.371 +         png_push_save_buffer(png_ptr);
   1.372 +         return;
   1.373 +      }
   1.374 +      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
   1.375 +   }
   1.376 +#endif
   1.377 +#if defined(PNG_READ_tRNS_SUPPORTED)
   1.378 +   else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
   1.379 +   {
   1.380 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.381 +      {
   1.382 +         png_push_save_buffer(png_ptr);
   1.383 +         return;
   1.384 +      }
   1.385 +      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
   1.386 +   }
   1.387 +#endif
   1.388 +#if defined(PNG_READ_bKGD_SUPPORTED)
   1.389 +   else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
   1.390 +   {
   1.391 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.392 +      {
   1.393 +         png_push_save_buffer(png_ptr);
   1.394 +         return;
   1.395 +      }
   1.396 +      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
   1.397 +   }
   1.398 +#endif
   1.399 +#if defined(PNG_READ_hIST_SUPPORTED)
   1.400 +   else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
   1.401 +   {
   1.402 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.403 +      {
   1.404 +         png_push_save_buffer(png_ptr);
   1.405 +         return;
   1.406 +      }
   1.407 +      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
   1.408 +   }
   1.409 +#endif
   1.410 +#if defined(PNG_READ_pHYs_SUPPORTED)
   1.411 +   else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
   1.412 +   {
   1.413 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.414 +      {
   1.415 +         png_push_save_buffer(png_ptr);
   1.416 +         return;
   1.417 +      }
   1.418 +      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
   1.419 +   }
   1.420 +#endif
   1.421 +#if defined(PNG_READ_oFFs_SUPPORTED)
   1.422 +   else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
   1.423 +   {
   1.424 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.425 +      {
   1.426 +         png_push_save_buffer(png_ptr);
   1.427 +         return;
   1.428 +      }
   1.429 +      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
   1.430 +   }
   1.431 +#endif
   1.432 +#if defined(PNG_READ_pCAL_SUPPORTED)
   1.433 +   else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
   1.434 +   {
   1.435 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.436 +      {
   1.437 +         png_push_save_buffer(png_ptr);
   1.438 +         return;
   1.439 +      }
   1.440 +      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
   1.441 +   }
   1.442 +#endif
   1.443 +#if defined(PNG_READ_sCAL_SUPPORTED)
   1.444 +   else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
   1.445 +   {
   1.446 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.447 +      {
   1.448 +         png_push_save_buffer(png_ptr);
   1.449 +         return;
   1.450 +      }
   1.451 +      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
   1.452 +   }
   1.453 +#endif
   1.454 +#if defined(PNG_READ_tIME_SUPPORTED)
   1.455 +   else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
   1.456 +   {
   1.457 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.458 +      {
   1.459 +         png_push_save_buffer(png_ptr);
   1.460 +         return;
   1.461 +      }
   1.462 +      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
   1.463 +   }
   1.464 +#endif
   1.465 +#if defined(PNG_READ_tEXt_SUPPORTED)
   1.466 +   else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
   1.467 +   {
   1.468 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.469 +      {
   1.470 +         png_push_save_buffer(png_ptr);
   1.471 +         return;
   1.472 +      }
   1.473 +      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
   1.474 +   }
   1.475 +#endif
   1.476 +#if defined(PNG_READ_zTXt_SUPPORTED)
   1.477 +   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
   1.478 +   {
   1.479 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.480 +      {
   1.481 +         png_push_save_buffer(png_ptr);
   1.482 +         return;
   1.483 +      }
   1.484 +      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
   1.485 +   }
   1.486 +#endif
   1.487 +#if defined(PNG_READ_iTXt_SUPPORTED)
   1.488 +   else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
   1.489 +   {
   1.490 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.491 +      {
   1.492 +         png_push_save_buffer(png_ptr);
   1.493 +         return;
   1.494 +      }
   1.495 +      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
   1.496 +   }
   1.497 +#endif
   1.498 +   else
   1.499 +   {
   1.500 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.501 +      {
   1.502 +         png_push_save_buffer(png_ptr);
   1.503 +         return;
   1.504 +      }
   1.505 +      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
   1.506 +   }
   1.507 +
   1.508 +   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.509 +}
   1.510 +
   1.511 +void /* PRIVATE */
   1.512 +png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
   1.513 +{
   1.514 +   png_ptr->process_mode = PNG_SKIP_MODE;
   1.515 +   png_ptr->skip_length = skip;
   1.516 +}
   1.517 +
   1.518 +void /* PRIVATE */
   1.519 +png_push_crc_finish(png_structp png_ptr)
   1.520 +{
   1.521 +   if (png_ptr->skip_length && png_ptr->save_buffer_size)
   1.522 +   {
   1.523 +      png_size_t save_size;
   1.524 +
   1.525 +      if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
   1.526 +         save_size = (png_size_t)png_ptr->skip_length;
   1.527 +      else
   1.528 +         save_size = png_ptr->save_buffer_size;
   1.529 +
   1.530 +      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
   1.531 +
   1.532 +      png_ptr->skip_length -= save_size;
   1.533 +      png_ptr->buffer_size -= save_size;
   1.534 +      png_ptr->save_buffer_size -= save_size;
   1.535 +      png_ptr->save_buffer_ptr += save_size;
   1.536 +   }
   1.537 +   if (png_ptr->skip_length && png_ptr->current_buffer_size)
   1.538 +   {
   1.539 +      png_size_t save_size;
   1.540 +
   1.541 +      if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
   1.542 +         save_size = (png_size_t)png_ptr->skip_length;
   1.543 +      else
   1.544 +         save_size = png_ptr->current_buffer_size;
   1.545 +
   1.546 +      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
   1.547 +
   1.548 +      png_ptr->skip_length -= save_size;
   1.549 +      png_ptr->buffer_size -= save_size;
   1.550 +      png_ptr->current_buffer_size -= save_size;
   1.551 +      png_ptr->current_buffer_ptr += save_size;
   1.552 +   }
   1.553 +   if (!png_ptr->skip_length)
   1.554 +   {
   1.555 +      if (png_ptr->buffer_size < 4)
   1.556 +      {
   1.557 +         png_push_save_buffer(png_ptr);
   1.558 +         return;
   1.559 +      }
   1.560 +
   1.561 +      png_crc_finish(png_ptr, 0);
   1.562 +      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.563 +   }
   1.564 +}
   1.565 +
   1.566 +void PNGAPI
   1.567 +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
   1.568 +{
   1.569 +   png_bytep ptr;
   1.570 +
   1.571 +   if (png_ptr == NULL) return;
   1.572 +   ptr = buffer;
   1.573 +   if (png_ptr->save_buffer_size)
   1.574 +   {
   1.575 +      png_size_t save_size;
   1.576 +
   1.577 +      if (length < png_ptr->save_buffer_size)
   1.578 +         save_size = length;
   1.579 +      else
   1.580 +         save_size = png_ptr->save_buffer_size;
   1.581 +
   1.582 +      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
   1.583 +      length -= save_size;
   1.584 +      ptr += save_size;
   1.585 +      png_ptr->buffer_size -= save_size;
   1.586 +      png_ptr->save_buffer_size -= save_size;
   1.587 +      png_ptr->save_buffer_ptr += save_size;
   1.588 +   }
   1.589 +   if (length && png_ptr->current_buffer_size)
   1.590 +   {
   1.591 +      png_size_t save_size;
   1.592 +
   1.593 +      if (length < png_ptr->current_buffer_size)
   1.594 +         save_size = length;
   1.595 +      else
   1.596 +         save_size = png_ptr->current_buffer_size;
   1.597 +
   1.598 +      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
   1.599 +      png_ptr->buffer_size -= save_size;
   1.600 +      png_ptr->current_buffer_size -= save_size;
   1.601 +      png_ptr->current_buffer_ptr += save_size;
   1.602 +   }
   1.603 +}
   1.604 +
   1.605 +void /* PRIVATE */
   1.606 +png_push_save_buffer(png_structp png_ptr)
   1.607 +{
   1.608 +   if (png_ptr->save_buffer_size)
   1.609 +   {
   1.610 +      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
   1.611 +      {
   1.612 +         png_size_t i, istop;
   1.613 +         png_bytep sp;
   1.614 +         png_bytep dp;
   1.615 +
   1.616 +         istop = png_ptr->save_buffer_size;
   1.617 +         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
   1.618 +            i < istop; i++, sp++, dp++)
   1.619 +         {
   1.620 +            *dp = *sp;
   1.621 +         }
   1.622 +      }
   1.623 +   }
   1.624 +   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
   1.625 +      png_ptr->save_buffer_max)
   1.626 +   {
   1.627 +      png_size_t new_max;
   1.628 +      png_bytep old_buffer;
   1.629 +
   1.630 +      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
   1.631 +         (png_ptr->current_buffer_size + 256))
   1.632 +      {
   1.633 +        png_error(png_ptr, "Potential overflow of save_buffer");
   1.634 +      }
   1.635 +      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
   1.636 +      old_buffer = png_ptr->save_buffer;
   1.637 +      png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
   1.638 +         (png_uint_32)new_max);
   1.639 +      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
   1.640 +      png_free(png_ptr, old_buffer);
   1.641 +      png_ptr->save_buffer_max = new_max;
   1.642 +   }
   1.643 +   if (png_ptr->current_buffer_size)
   1.644 +   {
   1.645 +      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
   1.646 +         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
   1.647 +      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
   1.648 +      png_ptr->current_buffer_size = 0;
   1.649 +   }
   1.650 +   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
   1.651 +   png_ptr->buffer_size = 0;
   1.652 +}
   1.653 +
   1.654 +void /* PRIVATE */
   1.655 +png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
   1.656 +   png_size_t buffer_length)
   1.657 +{
   1.658 +   png_ptr->current_buffer = buffer;
   1.659 +   png_ptr->current_buffer_size = buffer_length;
   1.660 +   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
   1.661 +   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
   1.662 +}
   1.663 +
   1.664 +void /* PRIVATE */
   1.665 +png_push_read_IDAT(png_structp png_ptr)
   1.666 +{
   1.667 +#ifdef PNG_USE_LOCAL_ARRAYS
   1.668 +   PNG_CONST PNG_IDAT;
   1.669 +#endif
   1.670 +   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
   1.671 +   {
   1.672 +      png_byte chunk_length[4];
   1.673 +
   1.674 +      if (png_ptr->buffer_size < 8)
   1.675 +      {
   1.676 +         png_push_save_buffer(png_ptr);
   1.677 +         return;
   1.678 +      }
   1.679 +
   1.680 +      png_push_fill_buffer(png_ptr, chunk_length, 4);
   1.681 +      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
   1.682 +      png_reset_crc(png_ptr);
   1.683 +      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
   1.684 +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
   1.685 +
   1.686 +      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
   1.687 +      {
   1.688 +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.689 +         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
   1.690 +            png_error(png_ptr, "Not enough compressed data");
   1.691 +         return;
   1.692 +      }
   1.693 +
   1.694 +      png_ptr->idat_size = png_ptr->push_length;
   1.695 +   }
   1.696 +   if (png_ptr->idat_size && png_ptr->save_buffer_size)
   1.697 +   {
   1.698 +      png_size_t save_size;
   1.699 +
   1.700 +      if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
   1.701 +      {
   1.702 +         save_size = (png_size_t)png_ptr->idat_size;
   1.703 +         /* check for overflow */
   1.704 +         if ((png_uint_32)save_size != png_ptr->idat_size)
   1.705 +            png_error(png_ptr, "save_size overflowed in pngpread");
   1.706 +      }
   1.707 +      else
   1.708 +         save_size = png_ptr->save_buffer_size;
   1.709 +
   1.710 +      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
   1.711 +      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
   1.712 +         png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
   1.713 +      png_ptr->idat_size -= save_size;
   1.714 +      png_ptr->buffer_size -= save_size;
   1.715 +      png_ptr->save_buffer_size -= save_size;
   1.716 +      png_ptr->save_buffer_ptr += save_size;
   1.717 +   }
   1.718 +   if (png_ptr->idat_size && png_ptr->current_buffer_size)
   1.719 +   {
   1.720 +      png_size_t save_size;
   1.721 +
   1.722 +      if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
   1.723 +      {
   1.724 +         save_size = (png_size_t)png_ptr->idat_size;
   1.725 +         /* check for overflow */
   1.726 +         if ((png_uint_32)save_size != png_ptr->idat_size)
   1.727 +            png_error(png_ptr, "save_size overflowed in pngpread");
   1.728 +      }
   1.729 +      else
   1.730 +         save_size = png_ptr->current_buffer_size;
   1.731 +
   1.732 +      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
   1.733 +      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
   1.734 +        png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
   1.735 +
   1.736 +      png_ptr->idat_size -= save_size;
   1.737 +      png_ptr->buffer_size -= save_size;
   1.738 +      png_ptr->current_buffer_size -= save_size;
   1.739 +      png_ptr->current_buffer_ptr += save_size;
   1.740 +   }
   1.741 +   if (!png_ptr->idat_size)
   1.742 +   {
   1.743 +      if (png_ptr->buffer_size < 4)
   1.744 +      {
   1.745 +         png_push_save_buffer(png_ptr);
   1.746 +         return;
   1.747 +      }
   1.748 +
   1.749 +      png_crc_finish(png_ptr, 0);
   1.750 +      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.751 +      png_ptr->mode |= PNG_AFTER_IDAT;
   1.752 +   }
   1.753 +}
   1.754 +
   1.755 +void /* PRIVATE */
   1.756 +png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
   1.757 +   png_size_t buffer_length)
   1.758 +{
   1.759 +   int ret;
   1.760 +
   1.761 +   if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
   1.762 +      png_error(png_ptr, "Extra compression data");
   1.763 +
   1.764 +   png_ptr->zstream.next_in = buffer;
   1.765 +   png_ptr->zstream.avail_in = (uInt)buffer_length;
   1.766 +   for (;;)
   1.767 +   {
   1.768 +      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
   1.769 +      if (ret != Z_OK)
   1.770 +      {
   1.771 +         if (ret == Z_STREAM_END)
   1.772 +         {
   1.773 +            if (png_ptr->zstream.avail_in)
   1.774 +               png_error(png_ptr, "Extra compressed data");
   1.775 +            if (!(png_ptr->zstream.avail_out))
   1.776 +            {
   1.777 +               png_push_process_row(png_ptr);
   1.778 +            }
   1.779 +
   1.780 +            png_ptr->mode |= PNG_AFTER_IDAT;
   1.781 +            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
   1.782 +            break;
   1.783 +         }
   1.784 +         else if (ret == Z_BUF_ERROR)
   1.785 +            break;
   1.786 +         else
   1.787 +            png_error(png_ptr, "Decompression Error");
   1.788 +      }
   1.789 +      if (!(png_ptr->zstream.avail_out))
   1.790 +      {
   1.791 +         if ((
   1.792 +#if defined(PNG_READ_INTERLACING_SUPPORTED)
   1.793 +             png_ptr->interlaced && png_ptr->pass > 6) ||
   1.794 +             (!png_ptr->interlaced &&
   1.795 +#endif
   1.796 +             png_ptr->row_number == png_ptr->num_rows))
   1.797 +         {
   1.798 +           if (png_ptr->zstream.avail_in)
   1.799 +             png_warning(png_ptr, "Too much data in IDAT chunks");
   1.800 +           png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
   1.801 +           break;
   1.802 +         }
   1.803 +         png_push_process_row(png_ptr);
   1.804 +         png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
   1.805 +         png_ptr->zstream.next_out = png_ptr->row_buf;
   1.806 +      }
   1.807 +      else
   1.808 +         break;
   1.809 +   }
   1.810 +}
   1.811 +
   1.812 +void /* PRIVATE */
   1.813 +png_push_process_row(png_structp png_ptr)
   1.814 +{
   1.815 +   png_ptr->row_info.color_type = png_ptr->color_type;
   1.816 +   png_ptr->row_info.width = png_ptr->iwidth;
   1.817 +   png_ptr->row_info.channels = png_ptr->channels;
   1.818 +   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
   1.819 +   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
   1.820 +
   1.821 +   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
   1.822 +       png_ptr->row_info.width);
   1.823 +
   1.824 +   png_read_filter_row(png_ptr, &(png_ptr->row_info),
   1.825 +      png_ptr->row_buf + 1, png_ptr->prev_row + 1,
   1.826 +      (int)(png_ptr->row_buf[0]));
   1.827 +
   1.828 +   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
   1.829 +      png_ptr->rowbytes + 1);
   1.830 +
   1.831 +   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
   1.832 +      png_do_read_transformations(png_ptr);
   1.833 +
   1.834 +#if defined(PNG_READ_INTERLACING_SUPPORTED)
   1.835 +   /* blow up interlaced rows to full size */
   1.836 +   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
   1.837 +   {
   1.838 +      if (png_ptr->pass < 6)
   1.839 +/*       old interface (pre-1.0.9):
   1.840 +         png_do_read_interlace(&(png_ptr->row_info),
   1.841 +            png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
   1.842 + */
   1.843 +         png_do_read_interlace(png_ptr);
   1.844 +
   1.845 +    switch (png_ptr->pass)
   1.846 +    {
   1.847 +         case 0:
   1.848 +         {
   1.849 +            int i;
   1.850 +            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
   1.851 +            {
   1.852 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.853 +               png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
   1.854 +            }
   1.855 +            if (png_ptr->pass == 2) /* pass 1 might be empty */
   1.856 +            {
   1.857 +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1.858 +               {
   1.859 +                  png_push_have_row(png_ptr, png_bytep_NULL);
   1.860 +                  png_read_push_finish_row(png_ptr);
   1.861 +               }
   1.862 +            }
   1.863 +            if (png_ptr->pass == 4 && png_ptr->height <= 4)
   1.864 +            {
   1.865 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1.866 +               {
   1.867 +                  png_push_have_row(png_ptr, png_bytep_NULL);
   1.868 +                  png_read_push_finish_row(png_ptr);
   1.869 +               }
   1.870 +            }
   1.871 +            if (png_ptr->pass == 6 && png_ptr->height <= 4)
   1.872 +            {
   1.873 +                png_push_have_row(png_ptr, png_bytep_NULL);
   1.874 +                png_read_push_finish_row(png_ptr);
   1.875 +            }
   1.876 +            break;
   1.877 +         }
   1.878 +         case 1:
   1.879 +         {
   1.880 +            int i;
   1.881 +            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
   1.882 +            {
   1.883 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.884 +               png_read_push_finish_row(png_ptr);
   1.885 +            }
   1.886 +            if (png_ptr->pass == 2) /* skip top 4 generated rows */
   1.887 +            {
   1.888 +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1.889 +               {
   1.890 +                  png_push_have_row(png_ptr, png_bytep_NULL);
   1.891 +                  png_read_push_finish_row(png_ptr);
   1.892 +               }
   1.893 +            }
   1.894 +            break;
   1.895 +         }
   1.896 +         case 2:
   1.897 +         {
   1.898 +            int i;
   1.899 +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1.900 +            {
   1.901 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.902 +               png_read_push_finish_row(png_ptr);
   1.903 +            }
   1.904 +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1.905 +            {
   1.906 +               png_push_have_row(png_ptr, png_bytep_NULL);
   1.907 +               png_read_push_finish_row(png_ptr);
   1.908 +            }
   1.909 +            if (png_ptr->pass == 4) /* pass 3 might be empty */
   1.910 +            {
   1.911 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1.912 +               {
   1.913 +                  png_push_have_row(png_ptr, png_bytep_NULL);
   1.914 +                  png_read_push_finish_row(png_ptr);
   1.915 +               }
   1.916 +            }
   1.917 +            break;
   1.918 +         }
   1.919 +         case 3:
   1.920 +         {
   1.921 +            int i;
   1.922 +            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
   1.923 +            {
   1.924 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.925 +               png_read_push_finish_row(png_ptr);
   1.926 +            }
   1.927 +            if (png_ptr->pass == 4) /* skip top two generated rows */
   1.928 +            {
   1.929 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1.930 +               {
   1.931 +                  png_push_have_row(png_ptr, png_bytep_NULL);
   1.932 +                  png_read_push_finish_row(png_ptr);
   1.933 +               }
   1.934 +            }
   1.935 +            break;
   1.936 +         }
   1.937 +         case 4:
   1.938 +         {
   1.939 +            int i;
   1.940 +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1.941 +            {
   1.942 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.943 +               png_read_push_finish_row(png_ptr);
   1.944 +            }
   1.945 +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1.946 +            {
   1.947 +               png_push_have_row(png_ptr, png_bytep_NULL);
   1.948 +               png_read_push_finish_row(png_ptr);
   1.949 +            }
   1.950 +            if (png_ptr->pass == 6) /* pass 5 might be empty */
   1.951 +            {
   1.952 +               png_push_have_row(png_ptr, png_bytep_NULL);
   1.953 +               png_read_push_finish_row(png_ptr);
   1.954 +            }
   1.955 +            break;
   1.956 +         }
   1.957 +         case 5:
   1.958 +         {
   1.959 +            int i;
   1.960 +            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
   1.961 +            {
   1.962 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.963 +               png_read_push_finish_row(png_ptr);
   1.964 +            }
   1.965 +            if (png_ptr->pass == 6) /* skip top generated row */
   1.966 +            {
   1.967 +               png_push_have_row(png_ptr, png_bytep_NULL);
   1.968 +               png_read_push_finish_row(png_ptr);
   1.969 +            }
   1.970 +            break;
   1.971 +         }
   1.972 +         case 6:
   1.973 +         {
   1.974 +            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.975 +            png_read_push_finish_row(png_ptr);
   1.976 +            if (png_ptr->pass != 6)
   1.977 +               break;
   1.978 +            png_push_have_row(png_ptr, png_bytep_NULL);
   1.979 +            png_read_push_finish_row(png_ptr);
   1.980 +         }
   1.981 +      }
   1.982 +   }
   1.983 +   else
   1.984 +#endif
   1.985 +   {
   1.986 +      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1.987 +      png_read_push_finish_row(png_ptr);
   1.988 +   }
   1.989 +}
   1.990 +
   1.991 +void /* PRIVATE */
   1.992 +png_read_push_finish_row(png_structp png_ptr)
   1.993 +{
   1.994 +#ifdef PNG_USE_LOCAL_ARRAYS
   1.995 +   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   1.996 +
   1.997 +   /* start of interlace block */
   1.998 +   PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
   1.999 +
  1.1000 +   /* offset to next interlace block */
  1.1001 +   PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  1.1002 +
  1.1003 +   /* start of interlace block in the y direction */
  1.1004 +   PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  1.1005 +
  1.1006 +   /* offset to next interlace block in the y direction */
  1.1007 +   PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  1.1008 +
  1.1009 +   /* Height of interlace block.  This is not currently used - if you need
  1.1010 +    * it, uncomment it here and in png.h
  1.1011 +   PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
  1.1012 +   */
  1.1013 +#endif
  1.1014 +
  1.1015 +   png_ptr->row_number++;
  1.1016 +   if (png_ptr->row_number < png_ptr->num_rows)
  1.1017 +      return;
  1.1018 +
  1.1019 +   if (png_ptr->interlaced)
  1.1020 +   {
  1.1021 +      png_ptr->row_number = 0;
  1.1022 +      png_memset_check(png_ptr, png_ptr->prev_row, 0,
  1.1023 +         png_ptr->rowbytes + 1);
  1.1024 +      do
  1.1025 +      {
  1.1026 +         png_ptr->pass++;
  1.1027 +         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
  1.1028 +             (png_ptr->pass == 3 && png_ptr->width < 3) ||
  1.1029 +             (png_ptr->pass == 5 && png_ptr->width < 2))
  1.1030 +           png_ptr->pass++;
  1.1031 +
  1.1032 +         if (png_ptr->pass > 7)
  1.1033 +            png_ptr->pass--;
  1.1034 +         if (png_ptr->pass >= 7)
  1.1035 +            break;
  1.1036 +
  1.1037 +         png_ptr->iwidth = (png_ptr->width +
  1.1038 +            png_pass_inc[png_ptr->pass] - 1 -
  1.1039 +            png_pass_start[png_ptr->pass]) /
  1.1040 +            png_pass_inc[png_ptr->pass];
  1.1041 +
  1.1042 +         png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
  1.1043 +            png_ptr->iwidth) + 1;
  1.1044 +
  1.1045 +         if (png_ptr->transformations & PNG_INTERLACE)
  1.1046 +            break;
  1.1047 +
  1.1048 +         png_ptr->num_rows = (png_ptr->height +
  1.1049 +            png_pass_yinc[png_ptr->pass] - 1 -
  1.1050 +            png_pass_ystart[png_ptr->pass]) /
  1.1051 +            png_pass_yinc[png_ptr->pass];
  1.1052 +
  1.1053 +      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
  1.1054 +   }
  1.1055 +}
  1.1056 +
  1.1057 +#if defined(PNG_READ_tEXt_SUPPORTED)
  1.1058 +void /* PRIVATE */
  1.1059 +png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1.1060 +   length)
  1.1061 +{
  1.1062 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1.1063 +      {
  1.1064 +         png_error(png_ptr, "Out of place tEXt");
  1.1065 +         info_ptr = info_ptr; /* to quiet some compiler warnings */
  1.1066 +      }
  1.1067 +
  1.1068 +#ifdef PNG_MAX_MALLOC_64K
  1.1069 +   png_ptr->skip_length = 0;  /* This may not be necessary */
  1.1070 +
  1.1071 +   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  1.1072 +   {
  1.1073 +      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  1.1074 +      png_ptr->skip_length = length - (png_uint_32)65535L;
  1.1075 +      length = (png_uint_32)65535L;
  1.1076 +   }
  1.1077 +#endif
  1.1078 +
  1.1079 +   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1.1080 +      (png_uint_32)(length + 1));
  1.1081 +   png_ptr->current_text[length] = '\0';
  1.1082 +   png_ptr->current_text_ptr = png_ptr->current_text;
  1.1083 +   png_ptr->current_text_size = (png_size_t)length;
  1.1084 +   png_ptr->current_text_left = (png_size_t)length;
  1.1085 +   png_ptr->process_mode = PNG_READ_tEXt_MODE;
  1.1086 +}
  1.1087 +
  1.1088 +void /* PRIVATE */
  1.1089 +png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
  1.1090 +{
  1.1091 +   if (png_ptr->buffer_size && png_ptr->current_text_left)
  1.1092 +   {
  1.1093 +      png_size_t text_size;
  1.1094 +
  1.1095 +      if (png_ptr->buffer_size < png_ptr->current_text_left)
  1.1096 +         text_size = png_ptr->buffer_size;
  1.1097 +      else
  1.1098 +         text_size = png_ptr->current_text_left;
  1.1099 +      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1.1100 +      png_ptr->current_text_left -= text_size;
  1.1101 +      png_ptr->current_text_ptr += text_size;
  1.1102 +   }
  1.1103 +   if (!(png_ptr->current_text_left))
  1.1104 +   {
  1.1105 +      png_textp text_ptr;
  1.1106 +      png_charp text;
  1.1107 +      png_charp key;
  1.1108 +      int ret;
  1.1109 +
  1.1110 +      if (png_ptr->buffer_size < 4)
  1.1111 +      {
  1.1112 +         png_push_save_buffer(png_ptr);
  1.1113 +         return;
  1.1114 +      }
  1.1115 +
  1.1116 +      png_push_crc_finish(png_ptr);
  1.1117 +
  1.1118 +#if defined(PNG_MAX_MALLOC_64K)
  1.1119 +      if (png_ptr->skip_length)
  1.1120 +         return;
  1.1121 +#endif
  1.1122 +
  1.1123 +      key = png_ptr->current_text;
  1.1124 +
  1.1125 +      for (text = key; *text; text++)
  1.1126 +         /* empty loop */ ;
  1.1127 +
  1.1128 +      if (text < key + png_ptr->current_text_size)
  1.1129 +         text++;
  1.1130 +
  1.1131 +      text_ptr = (png_textp)png_malloc(png_ptr,
  1.1132 +         (png_uint_32)png_sizeof(png_text));
  1.1133 +      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  1.1134 +      text_ptr->key = key;
  1.1135 +#ifdef PNG_iTXt_SUPPORTED
  1.1136 +      text_ptr->lang = NULL;
  1.1137 +      text_ptr->lang_key = NULL;
  1.1138 +#endif
  1.1139 +      text_ptr->text = text;
  1.1140 +
  1.1141 +      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1.1142 +
  1.1143 +      png_free(png_ptr, key);
  1.1144 +      png_free(png_ptr, text_ptr);
  1.1145 +      png_ptr->current_text = NULL;
  1.1146 +
  1.1147 +      if (ret)
  1.1148 +        png_warning(png_ptr, "Insufficient memory to store text chunk.");
  1.1149 +   }
  1.1150 +}
  1.1151 +#endif
  1.1152 +
  1.1153 +#if defined(PNG_READ_zTXt_SUPPORTED)
  1.1154 +void /* PRIVATE */
  1.1155 +png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1.1156 +   length)
  1.1157 +{
  1.1158 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1.1159 +      {
  1.1160 +         png_error(png_ptr, "Out of place zTXt");
  1.1161 +         info_ptr = info_ptr; /* to quiet some compiler warnings */
  1.1162 +      }
  1.1163 +
  1.1164 +#ifdef PNG_MAX_MALLOC_64K
  1.1165 +   /* We can't handle zTXt chunks > 64K, since we don't have enough space
  1.1166 +    * to be able to store the uncompressed data.  Actually, the threshold
  1.1167 +    * is probably around 32K, but it isn't as definite as 64K is.
  1.1168 +    */
  1.1169 +   if (length > (png_uint_32)65535L)
  1.1170 +   {
  1.1171 +      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
  1.1172 +      png_push_crc_skip(png_ptr, length);
  1.1173 +      return;
  1.1174 +   }
  1.1175 +#endif
  1.1176 +
  1.1177 +   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1.1178 +      (png_uint_32)(length + 1));
  1.1179 +   png_ptr->current_text[length] = '\0';
  1.1180 +   png_ptr->current_text_ptr = png_ptr->current_text;
  1.1181 +   png_ptr->current_text_size = (png_size_t)length;
  1.1182 +   png_ptr->current_text_left = (png_size_t)length;
  1.1183 +   png_ptr->process_mode = PNG_READ_zTXt_MODE;
  1.1184 +}
  1.1185 +
  1.1186 +void /* PRIVATE */
  1.1187 +png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
  1.1188 +{
  1.1189 +   if (png_ptr->buffer_size && png_ptr->current_text_left)
  1.1190 +   {
  1.1191 +      png_size_t text_size;
  1.1192 +
  1.1193 +      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
  1.1194 +         text_size = png_ptr->buffer_size;
  1.1195 +      else
  1.1196 +         text_size = png_ptr->current_text_left;
  1.1197 +      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1.1198 +      png_ptr->current_text_left -= text_size;
  1.1199 +      png_ptr->current_text_ptr += text_size;
  1.1200 +   }
  1.1201 +   if (!(png_ptr->current_text_left))
  1.1202 +   {
  1.1203 +      png_textp text_ptr;
  1.1204 +      png_charp text;
  1.1205 +      png_charp key;
  1.1206 +      int ret;
  1.1207 +      png_size_t text_size, key_size;
  1.1208 +
  1.1209 +      if (png_ptr->buffer_size < 4)
  1.1210 +      {
  1.1211 +         png_push_save_buffer(png_ptr);
  1.1212 +         return;
  1.1213 +      }
  1.1214 +
  1.1215 +      png_push_crc_finish(png_ptr);
  1.1216 +
  1.1217 +      key = png_ptr->current_text;
  1.1218 +
  1.1219 +      for (text = key; *text; text++)
  1.1220 +         /* empty loop */ ;
  1.1221 +
  1.1222 +      /* zTXt can't have zero text */
  1.1223 +      if (text >= key + png_ptr->current_text_size)
  1.1224 +      {
  1.1225 +         png_ptr->current_text = NULL;
  1.1226 +         png_free(png_ptr, key);
  1.1227 +         return;
  1.1228 +      }
  1.1229 +
  1.1230 +      text++;
  1.1231 +
  1.1232 +      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
  1.1233 +      {
  1.1234 +         png_ptr->current_text = NULL;
  1.1235 +         png_free(png_ptr, key);
  1.1236 +         return;
  1.1237 +      }
  1.1238 +
  1.1239 +      text++;
  1.1240 +
  1.1241 +      png_ptr->zstream.next_in = (png_bytep )text;
  1.1242 +      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
  1.1243 +         (text - key));
  1.1244 +      png_ptr->zstream.next_out = png_ptr->zbuf;
  1.1245 +      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1.1246 +
  1.1247 +      key_size = text - key;
  1.1248 +      text_size = 0;
  1.1249 +      text = NULL;
  1.1250 +      ret = Z_STREAM_END;
  1.1251 +
  1.1252 +      while (png_ptr->zstream.avail_in)
  1.1253 +      {
  1.1254 +         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  1.1255 +         if (ret != Z_OK && ret != Z_STREAM_END)
  1.1256 +         {
  1.1257 +            inflateReset(&png_ptr->zstream);
  1.1258 +            png_ptr->zstream.avail_in = 0;
  1.1259 +            png_ptr->current_text = NULL;
  1.1260 +            png_free(png_ptr, key);
  1.1261 +            png_free(png_ptr, text);
  1.1262 +            return;
  1.1263 +         }
  1.1264 +         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
  1.1265 +         {
  1.1266 +            if (text == NULL)
  1.1267 +            {
  1.1268 +               text = (png_charp)png_malloc(png_ptr,
  1.1269 +                     (png_uint_32)(png_ptr->zbuf_size
  1.1270 +                     - png_ptr->zstream.avail_out + key_size + 1));
  1.1271 +               png_memcpy(text + key_size, png_ptr->zbuf,
  1.1272 +                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1.1273 +               png_memcpy(text, key, key_size);
  1.1274 +               text_size = key_size + png_ptr->zbuf_size -
  1.1275 +                  png_ptr->zstream.avail_out;
  1.1276 +               *(text + text_size) = '\0';
  1.1277 +            }
  1.1278 +            else
  1.1279 +            {
  1.1280 +               png_charp tmp;
  1.1281 +
  1.1282 +               tmp = text;
  1.1283 +               text = (png_charp)png_malloc(png_ptr, text_size +
  1.1284 +                  (png_uint_32)(png_ptr->zbuf_size 
  1.1285 +                  - png_ptr->zstream.avail_out + 1));
  1.1286 +               png_memcpy(text, tmp, text_size);
  1.1287 +               png_free(png_ptr, tmp);
  1.1288 +               png_memcpy(text + text_size, png_ptr->zbuf,
  1.1289 +                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1.1290 +               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  1.1291 +               *(text + text_size) = '\0';
  1.1292 +            }
  1.1293 +            if (ret != Z_STREAM_END)
  1.1294 +            {
  1.1295 +               png_ptr->zstream.next_out = png_ptr->zbuf;
  1.1296 +               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1.1297 +            }
  1.1298 +         }
  1.1299 +         else
  1.1300 +         {
  1.1301 +            break;
  1.1302 +         }
  1.1303 +
  1.1304 +         if (ret == Z_STREAM_END)
  1.1305 +            break;
  1.1306 +      }
  1.1307 +
  1.1308 +      inflateReset(&png_ptr->zstream);
  1.1309 +      png_ptr->zstream.avail_in = 0;
  1.1310 +
  1.1311 +      if (ret != Z_STREAM_END)
  1.1312 +      {
  1.1313 +         png_ptr->current_text = NULL;
  1.1314 +         png_free(png_ptr, key);
  1.1315 +         png_free(png_ptr, text);
  1.1316 +         return;
  1.1317 +      }
  1.1318 +
  1.1319 +      png_ptr->current_text = NULL;
  1.1320 +      png_free(png_ptr, key);
  1.1321 +      key = text;
  1.1322 +      text += key_size;
  1.1323 +
  1.1324 +      text_ptr = (png_textp)png_malloc(png_ptr,
  1.1325 +          (png_uint_32)png_sizeof(png_text));
  1.1326 +      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
  1.1327 +      text_ptr->key = key;
  1.1328 +#ifdef PNG_iTXt_SUPPORTED
  1.1329 +      text_ptr->lang = NULL;
  1.1330 +      text_ptr->lang_key = NULL;
  1.1331 +#endif
  1.1332 +      text_ptr->text = text;
  1.1333 +
  1.1334 +      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1.1335 +
  1.1336 +      png_free(png_ptr, key);
  1.1337 +      png_free(png_ptr, text_ptr);
  1.1338 +
  1.1339 +      if (ret)
  1.1340 +        png_warning(png_ptr, "Insufficient memory to store text chunk.");
  1.1341 +   }
  1.1342 +}
  1.1343 +#endif
  1.1344 +
  1.1345 +#if defined(PNG_READ_iTXt_SUPPORTED)
  1.1346 +void /* PRIVATE */
  1.1347 +png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1.1348 +   length)
  1.1349 +{
  1.1350 +   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
  1.1351 +      {
  1.1352 +         png_error(png_ptr, "Out of place iTXt");
  1.1353 +         info_ptr = info_ptr; /* to quiet some compiler warnings */
  1.1354 +      }
  1.1355 +
  1.1356 +#ifdef PNG_MAX_MALLOC_64K
  1.1357 +   png_ptr->skip_length = 0;  /* This may not be necessary */
  1.1358 +
  1.1359 +   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
  1.1360 +   {
  1.1361 +      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
  1.1362 +      png_ptr->skip_length = length - (png_uint_32)65535L;
  1.1363 +      length = (png_uint_32)65535L;
  1.1364 +   }
  1.1365 +#endif
  1.1366 +
  1.1367 +   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
  1.1368 +      (png_uint_32)(length + 1));
  1.1369 +   png_ptr->current_text[length] = '\0';
  1.1370 +   png_ptr->current_text_ptr = png_ptr->current_text;
  1.1371 +   png_ptr->current_text_size = (png_size_t)length;
  1.1372 +   png_ptr->current_text_left = (png_size_t)length;
  1.1373 +   png_ptr->process_mode = PNG_READ_iTXt_MODE;
  1.1374 +}
  1.1375 +
  1.1376 +void /* PRIVATE */
  1.1377 +png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
  1.1378 +{
  1.1379 +
  1.1380 +   if (png_ptr->buffer_size && png_ptr->current_text_left)
  1.1381 +   {
  1.1382 +      png_size_t text_size;
  1.1383 +
  1.1384 +      if (png_ptr->buffer_size < png_ptr->current_text_left)
  1.1385 +         text_size = png_ptr->buffer_size;
  1.1386 +      else
  1.1387 +         text_size = png_ptr->current_text_left;
  1.1388 +      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
  1.1389 +      png_ptr->current_text_left -= text_size;
  1.1390 +      png_ptr->current_text_ptr += text_size;
  1.1391 +   }
  1.1392 +   if (!(png_ptr->current_text_left))
  1.1393 +   {
  1.1394 +      png_textp text_ptr;
  1.1395 +      png_charp key;
  1.1396 +      int comp_flag;
  1.1397 +      png_charp lang;
  1.1398 +      png_charp lang_key;
  1.1399 +      png_charp text;
  1.1400 +      int ret;
  1.1401 +
  1.1402 +      if (png_ptr->buffer_size < 4)
  1.1403 +      {
  1.1404 +         png_push_save_buffer(png_ptr);
  1.1405 +         return;
  1.1406 +      }
  1.1407 +
  1.1408 +      png_push_crc_finish(png_ptr);
  1.1409 +
  1.1410 +#if defined(PNG_MAX_MALLOC_64K)
  1.1411 +      if (png_ptr->skip_length)
  1.1412 +         return;
  1.1413 +#endif
  1.1414 +
  1.1415 +      key = png_ptr->current_text;
  1.1416 +
  1.1417 +      for (lang = key; *lang; lang++)
  1.1418 +         /* empty loop */ ;
  1.1419 +
  1.1420 +      if (lang < key + png_ptr->current_text_size - 3)
  1.1421 +         lang++;
  1.1422 +
  1.1423 +      comp_flag = *lang++;
  1.1424 +      lang++;     /* skip comp_type, always zero */
  1.1425 +
  1.1426 +      for (lang_key = lang; *lang_key; lang_key++)
  1.1427 +         /* empty loop */ ;
  1.1428 +      lang_key++;        /* skip NUL separator */
  1.1429 +
  1.1430 +      text=lang_key;
  1.1431 +      if (lang_key < key + png_ptr->current_text_size - 1)
  1.1432 +      {
  1.1433 +        for (; *text; text++)
  1.1434 +           /* empty loop */ ;
  1.1435 +      }
  1.1436 +
  1.1437 +      if (text < key + png_ptr->current_text_size)
  1.1438 +         text++;
  1.1439 +
  1.1440 +      text_ptr = (png_textp)png_malloc(png_ptr,
  1.1441 +         (png_uint_32)png_sizeof(png_text));
  1.1442 +      text_ptr->compression = comp_flag + 2;
  1.1443 +      text_ptr->key = key;
  1.1444 +      text_ptr->lang = lang;
  1.1445 +      text_ptr->lang_key = lang_key;
  1.1446 +      text_ptr->text = text;
  1.1447 +      text_ptr->text_length = 0;
  1.1448 +      text_ptr->itxt_length = png_strlen(text);
  1.1449 +
  1.1450 +      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1.1451 +
  1.1452 +      png_ptr->current_text = NULL;
  1.1453 +
  1.1454 +      png_free(png_ptr, text_ptr);
  1.1455 +      if (ret)
  1.1456 +        png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
  1.1457 +   }
  1.1458 +}
  1.1459 +#endif
  1.1460 +
  1.1461 +/* This function is called when we haven't found a handler for this
  1.1462 + * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
  1.1463 + * name or a critical chunk), the chunk is (currently) silently ignored.
  1.1464 + */
  1.1465 +void /* PRIVATE */
  1.1466 +png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
  1.1467 +   length)
  1.1468 +{
  1.1469 +   png_uint_32 skip = 0;
  1.1470 +
  1.1471 +   if (!(png_ptr->chunk_name[0] & 0x20))
  1.1472 +   {
  1.1473 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  1.1474 +      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1.1475 +         PNG_HANDLE_CHUNK_ALWAYS
  1.1476 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  1.1477 +         && png_ptr->read_user_chunk_fn == NULL
  1.1478 +#endif
  1.1479 +         )
  1.1480 +#endif
  1.1481 +         png_chunk_error(png_ptr, "unknown critical chunk");
  1.1482 +
  1.1483 +      info_ptr = info_ptr; /* to quiet some compiler warnings */
  1.1484 +   }
  1.1485 +
  1.1486 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
  1.1487 +   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
  1.1488 +   {
  1.1489 +#ifdef PNG_MAX_MALLOC_64K
  1.1490 +      if (length > (png_uint_32)65535L)
  1.1491 +      {
  1.1492 +          png_warning(png_ptr, "unknown chunk too large to fit in memory");
  1.1493 +          skip = length - (png_uint_32)65535L;
  1.1494 +          length = (png_uint_32)65535L;
  1.1495 +      }
  1.1496 +#endif
  1.1497 +      png_memcpy((png_charp)png_ptr->unknown_chunk.name,
  1.1498 +                 (png_charp)png_ptr->chunk_name, 
  1.1499 +                 png_sizeof(png_ptr->unknown_chunk.name));
  1.1500 +      png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
  1.1501 +        = '\0';
  1.1502 +
  1.1503 +      png_ptr->unknown_chunk.size = (png_size_t)length;
  1.1504 +      if (length == 0)
  1.1505 +         png_ptr->unknown_chunk.data = NULL;
  1.1506 +      else
  1.1507 +      {
  1.1508 +         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
  1.1509 +       (png_uint_32)length);
  1.1510 +         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
  1.1511 +      }
  1.1512 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
  1.1513 +      if (png_ptr->read_user_chunk_fn != NULL)
  1.1514 +      {
  1.1515 +         /* callback to user unknown chunk handler */
  1.1516 +         int ret;
  1.1517 +         ret = (*(png_ptr->read_user_chunk_fn))
  1.1518 +           (png_ptr, &png_ptr->unknown_chunk);
  1.1519 +         if (ret < 0)
  1.1520 +            png_chunk_error(png_ptr, "error in user chunk");
  1.1521 +         if (ret == 0)
  1.1522 +         {
  1.1523 +            if (!(png_ptr->chunk_name[0] & 0x20))
  1.1524 +               if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
  1.1525 +                    PNG_HANDLE_CHUNK_ALWAYS)
  1.1526 +                  png_chunk_error(png_ptr, "unknown critical chunk");
  1.1527 +            png_set_unknown_chunks(png_ptr, info_ptr,
  1.1528 +               &png_ptr->unknown_chunk, 1);
  1.1529 +         }
  1.1530 +      }
  1.1531 +      else
  1.1532 +#endif
  1.1533 +        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
  1.1534 +      png_free(png_ptr, png_ptr->unknown_chunk.data);
  1.1535 +      png_ptr->unknown_chunk.data = NULL;
  1.1536 +   }
  1.1537 +   else
  1.1538 +#endif
  1.1539 +      skip=length;
  1.1540 +   png_push_crc_skip(png_ptr, skip);
  1.1541 +}
  1.1542 +
  1.1543 +void /* PRIVATE */
  1.1544 +png_push_have_info(png_structp png_ptr, png_infop info_ptr)
  1.1545 +{
  1.1546 +   if (png_ptr->info_fn != NULL)
  1.1547 +      (*(png_ptr->info_fn))(png_ptr, info_ptr);
  1.1548 +}
  1.1549 +
  1.1550 +void /* PRIVATE */
  1.1551 +png_push_have_end(png_structp png_ptr, png_infop info_ptr)
  1.1552 +{
  1.1553 +   if (png_ptr->end_fn != NULL)
  1.1554 +      (*(png_ptr->end_fn))(png_ptr, info_ptr);
  1.1555 +}
  1.1556 +
  1.1557 +void /* PRIVATE */
  1.1558 +png_push_have_row(png_structp png_ptr, png_bytep row)
  1.1559 +{
  1.1560 +   if (png_ptr->row_fn != NULL)
  1.1561 +      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1.1562 +         (int)png_ptr->pass);
  1.1563 +}
  1.1564 +
  1.1565 +void PNGAPI
  1.1566 +png_progressive_combine_row (png_structp png_ptr,
  1.1567 +   png_bytep old_row, png_bytep new_row)
  1.1568 +{
  1.1569 +#ifdef PNG_USE_LOCAL_ARRAYS
  1.1570 +   PNG_CONST int FARDATA png_pass_dsp_mask[7] =
  1.1571 +      {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
  1.1572 +#endif
  1.1573 +   if (png_ptr == NULL) return;
  1.1574 +   if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
  1.1575 +      png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1.1576 +}
  1.1577 +
  1.1578 +void PNGAPI
  1.1579 +png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1.1580 +   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1.1581 +   png_progressive_end_ptr end_fn)
  1.1582 +{
  1.1583 +   if (png_ptr == NULL) return;
  1.1584 +   png_ptr->info_fn = info_fn;
  1.1585 +   png_ptr->row_fn = row_fn;
  1.1586 +   png_ptr->end_fn = end_fn;
  1.1587 +
  1.1588 +   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1.1589 +}
  1.1590 +
  1.1591 +png_voidp PNGAPI
  1.1592 +png_get_progressive_ptr(png_structp png_ptr)
  1.1593 +{
  1.1594 +   if (png_ptr == NULL) return (NULL);
  1.1595 +   return png_ptr->io_ptr;
  1.1596 +}
  1.1597 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */