media/libpng/pngpread.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libpng/pngpread.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1494 @@
     1.4 +
     1.5 +/* pngpread.c - read a png file in push mode
     1.6 + *
     1.7 + * Last changed in libpng 1.6.10 [March 6, 2014]
     1.8 + * Copyright (c) 1998-2014 Glenn Randers-Pehrson
     1.9 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
    1.10 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
    1.11 + *
    1.12 + * This code is released under the libpng license.
    1.13 + * For conditions of distribution and use, see the disclaimer
    1.14 + * and license in png.h
    1.15 + */
    1.16 +
    1.17 +#include "pngpriv.h"
    1.18 +
    1.19 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    1.20 +
    1.21 +/* Push model modes */
    1.22 +#define PNG_READ_SIG_MODE   0
    1.23 +#define PNG_READ_CHUNK_MODE 1
    1.24 +#define PNG_READ_IDAT_MODE  2
    1.25 +#define PNG_SKIP_MODE       3
    1.26 +#define PNG_READ_tEXt_MODE  4
    1.27 +#define PNG_READ_zTXt_MODE  5
    1.28 +#define PNG_READ_DONE_MODE  6
    1.29 +#define PNG_READ_iTXt_MODE  7
    1.30 +#define PNG_ERROR_MODE      8
    1.31 +
    1.32 +void PNGAPI
    1.33 +png_process_data(png_structrp png_ptr, png_inforp info_ptr,
    1.34 +    png_bytep buffer, png_size_t buffer_size)
    1.35 +{
    1.36 +   if (png_ptr == NULL || info_ptr == NULL)
    1.37 +      return;
    1.38 +
    1.39 +   png_push_restore_buffer(png_ptr, buffer, buffer_size);
    1.40 +
    1.41 +   while (png_ptr->buffer_size)
    1.42 +   {
    1.43 +      png_process_some_data(png_ptr, info_ptr);
    1.44 +   }
    1.45 +}
    1.46 +
    1.47 +png_size_t PNGAPI
    1.48 +png_process_data_pause(png_structrp png_ptr, int save)
    1.49 +{
    1.50 +   if (png_ptr != NULL)
    1.51 +   {
    1.52 +      /* It's easiest for the caller if we do the save, then the caller doesn't
    1.53 +       * have to supply the same data again:
    1.54 +       */
    1.55 +      if (save)
    1.56 +         png_push_save_buffer(png_ptr);
    1.57 +      else
    1.58 +      {
    1.59 +         /* This includes any pending saved bytes: */
    1.60 +         png_size_t remaining = png_ptr->buffer_size;
    1.61 +         png_ptr->buffer_size = 0;
    1.62 +
    1.63 +         /* So subtract the saved buffer size, unless all the data
    1.64 +          * is actually 'saved', in which case we just return 0
    1.65 +          */
    1.66 +         if (png_ptr->save_buffer_size < remaining)
    1.67 +            return remaining - png_ptr->save_buffer_size;
    1.68 +      }
    1.69 +   }
    1.70 +
    1.71 +   return 0;
    1.72 +}
    1.73 +
    1.74 +png_uint_32 PNGAPI
    1.75 +png_process_data_skip(png_structrp png_ptr)
    1.76 +{
    1.77 +   png_uint_32 remaining = 0;
    1.78 +
    1.79 +   if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
    1.80 +      png_ptr->skip_length > 0)
    1.81 +   {
    1.82 +      /* At the end of png_process_data the buffer size must be 0 (see the loop
    1.83 +       * above) so we can detect a broken call here:
    1.84 +       */
    1.85 +      if (png_ptr->buffer_size != 0)
    1.86 +         png_error(png_ptr,
    1.87 +            "png_process_data_skip called inside png_process_data");
    1.88 +
    1.89 +      /* If is impossible for there to be a saved buffer at this point -
    1.90 +       * otherwise we could not be in SKIP mode.  This will also happen if
    1.91 +       * png_process_skip is called inside png_process_data (but only very
    1.92 +       * rarely.)
    1.93 +       */
    1.94 +      if (png_ptr->save_buffer_size != 0)
    1.95 +         png_error(png_ptr, "png_process_data_skip called with saved data");
    1.96 +
    1.97 +      remaining = png_ptr->skip_length;
    1.98 +      png_ptr->skip_length = 0;
    1.99 +      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.100 +   }
   1.101 +
   1.102 +   return remaining;
   1.103 +}
   1.104 +
   1.105 +/* What we do with the incoming data depends on what we were previously
   1.106 + * doing before we ran out of data...
   1.107 + */
   1.108 +void /* PRIVATE */
   1.109 +png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
   1.110 +{
   1.111 +   if (png_ptr == NULL)
   1.112 +      return;
   1.113 +
   1.114 +   switch (png_ptr->process_mode)
   1.115 +   {
   1.116 +      case PNG_READ_SIG_MODE:
   1.117 +      {
   1.118 +         png_push_read_sig(png_ptr, info_ptr);
   1.119 +         break;
   1.120 +      }
   1.121 +
   1.122 +      case PNG_READ_CHUNK_MODE:
   1.123 +      {
   1.124 +         png_push_read_chunk(png_ptr, info_ptr);
   1.125 +         break;
   1.126 +      }
   1.127 +
   1.128 +      case PNG_READ_IDAT_MODE:
   1.129 +      {
   1.130 +         png_push_read_IDAT(png_ptr);
   1.131 +         break;
   1.132 +      }
   1.133 +
   1.134 +      case PNG_SKIP_MODE:
   1.135 +      {
   1.136 +         png_push_crc_finish(png_ptr);
   1.137 +         break;
   1.138 +      }
   1.139 +
   1.140 +      default:
   1.141 +      {
   1.142 +         png_ptr->buffer_size = 0;
   1.143 +         break;
   1.144 +      }
   1.145 +   }
   1.146 +}
   1.147 +
   1.148 +/* Read any remaining signature bytes from the stream and compare them with
   1.149 + * the correct PNG signature.  It is possible that this routine is called
   1.150 + * with bytes already read from the signature, either because they have been
   1.151 + * checked by the calling application, or because of multiple calls to this
   1.152 + * routine.
   1.153 + */
   1.154 +void /* PRIVATE */
   1.155 +png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
   1.156 +{
   1.157 +   png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ 
   1.158 +             num_to_check = 8 - num_checked;
   1.159 +
   1.160 +   if (png_ptr->buffer_size < num_to_check)
   1.161 +   {
   1.162 +      num_to_check = png_ptr->buffer_size;
   1.163 +   }
   1.164 +
   1.165 +   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
   1.166 +       num_to_check);
   1.167 +   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
   1.168 +
   1.169 +   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
   1.170 +   {
   1.171 +      if (num_checked < 4 &&
   1.172 +          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
   1.173 +         png_error(png_ptr, "Not a PNG file");
   1.174 +
   1.175 +      else
   1.176 +         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
   1.177 +   }
   1.178 +   else
   1.179 +   {
   1.180 +      if (png_ptr->sig_bytes >= 8)
   1.181 +      {
   1.182 +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.183 +      }
   1.184 +   }
   1.185 +}
   1.186 +
   1.187 +void /* PRIVATE */
   1.188 +png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
   1.189 +{
   1.190 +   png_uint_32 chunk_name;
   1.191 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   1.192 +   int keep; /* unknown handling method */
   1.193 +#endif
   1.194 +
   1.195 +   /* First we make sure we have enough data for the 4 byte chunk name
   1.196 +    * and the 4 byte chunk length before proceeding with decoding the
   1.197 +    * chunk data.  To fully decode each of these chunks, we also make
   1.198 +    * sure we have enough data in the buffer for the 4 byte CRC at the
   1.199 +    * end of every chunk (except IDAT, which is handled separately).
   1.200 +    */
   1.201 +   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
   1.202 +   {
   1.203 +      png_byte chunk_length[4];
   1.204 +      png_byte chunk_tag[4];
   1.205 +
   1.206 +      if (png_ptr->buffer_size < 8)
   1.207 +      {
   1.208 +         png_push_save_buffer(png_ptr);
   1.209 +         return;
   1.210 +      }
   1.211 +
   1.212 +      png_push_fill_buffer(png_ptr, chunk_length, 4);
   1.213 +      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
   1.214 +      png_reset_crc(png_ptr);
   1.215 +      png_crc_read(png_ptr, chunk_tag, 4);
   1.216 +      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
   1.217 +      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
   1.218 +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
   1.219 +   }
   1.220 +
   1.221 +   chunk_name = png_ptr->chunk_name;
   1.222 +
   1.223 +#ifdef PNG_READ_APNG_SUPPORTED
   1.224 +   if (png_ptr->num_frames_read > 0 &&
   1.225 +       png_ptr->num_frames_read < info_ptr->num_frames)
   1.226 +   {
   1.227 +      if (chunk_name == png_IDAT)
   1.228 +      {
   1.229 +         /* Discard trailing IDATs for the first frame */
   1.230 +         if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
   1.231 +            png_error(png_ptr, "out of place IDAT");
   1.232 +
   1.233 +         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.234 +         {
   1.235 +            png_push_save_buffer(png_ptr);
   1.236 +            return;
   1.237 +         }
   1.238 +
   1.239 +         png_push_crc_skip(png_ptr, png_ptr->push_length);
   1.240 +         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.241 +         return;
   1.242 +      }
   1.243 +      else if (chunk_name == png_fdAT)
   1.244 +      {
   1.245 +         if (png_ptr->buffer_size < 4)
   1.246 +         {
   1.247 +            png_push_save_buffer(png_ptr);
   1.248 +            return;
   1.249 +         }
   1.250 +
   1.251 +         png_ensure_sequence_number(png_ptr, 4);
   1.252 +
   1.253 +         if (!(png_ptr->mode & PNG_HAVE_fcTL))
   1.254 +         {
   1.255 +            /* Discard trailing fdATs for frames other than the first */
   1.256 +            if (png_ptr->num_frames_read < 2)
   1.257 +               png_error(png_ptr, "out of place fdAT");
   1.258 +
   1.259 +            if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.260 +            {
   1.261 +               png_push_save_buffer(png_ptr);
   1.262 +               return;
   1.263 +            }
   1.264 +
   1.265 +            png_push_crc_skip(png_ptr, png_ptr->push_length);
   1.266 +            png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.267 +            return;
   1.268 +         }
   1.269 +
   1.270 +         else
   1.271 +         {
   1.272 +            /* frame data follows */
   1.273 +            png_ptr->idat_size = png_ptr->push_length - 4;
   1.274 +            png_ptr->mode |= PNG_HAVE_IDAT;
   1.275 +            png_ptr->process_mode = PNG_READ_IDAT_MODE;
   1.276 +
   1.277 +            return;
   1.278 +         }
   1.279 +      }
   1.280 +
   1.281 +      else if (chunk_name == png_fcTL)
   1.282 +      {
   1.283 +         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.284 +         {
   1.285 +            png_push_save_buffer(png_ptr);
   1.286 +            return;
   1.287 +         }
   1.288 +
   1.289 +         png_read_reset(png_ptr);
   1.290 +         png_ptr->mode &= ~PNG_HAVE_fcTL;
   1.291 +
   1.292 +         png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
   1.293 +
   1.294 +         if (!(png_ptr->mode & PNG_HAVE_fcTL))
   1.295 +            png_error(png_ptr, "missing required fcTL chunk");
   1.296 +
   1.297 +         png_read_reinit(png_ptr, info_ptr);
   1.298 +         png_progressive_read_reset(png_ptr);
   1.299 +
   1.300 +         if (png_ptr->frame_info_fn != NULL)
   1.301 +            (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
   1.302 +
   1.303 +         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.304 +
   1.305 +         return;
   1.306 +      }
   1.307 +
   1.308 +      else
   1.309 +      {
   1.310 +         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.311 +         {
   1.312 +            png_push_save_buffer(png_ptr);
   1.313 +            return;
   1.314 +         }
   1.315 +         png_warning(png_ptr, "Skipped (ignored) a chunk "
   1.316 +                              "between APNG chunks");
   1.317 +         png_push_crc_skip(png_ptr, png_ptr->push_length);
   1.318 +         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.319 +         return;
   1.320 +      }
   1.321 +
   1.322 +      return;
   1.323 +   }
   1.324 +#endif /* PNG_READ_APNG_SUPPORTED */
   1.325 +
   1.326 +   if (chunk_name == png_IDAT)
   1.327 +   {
   1.328 +      if (png_ptr->mode & PNG_AFTER_IDAT)
   1.329 +         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
   1.330 +
   1.331 +      /* If we reach an IDAT chunk, this means we have read all of the
   1.332 +       * header chunks, and we can start reading the image (or if this
   1.333 +       * is called after the image has been read - we have an error).
   1.334 +       */
   1.335 +      if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1.336 +         png_error(png_ptr, "Missing IHDR before IDAT");
   1.337 +
   1.338 +      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
   1.339 +          !(png_ptr->mode & PNG_HAVE_PLTE))
   1.340 +         png_error(png_ptr, "Missing PLTE before IDAT");
   1.341 +
   1.342 +      png_ptr->mode |= PNG_HAVE_IDAT;
   1.343 +      png_ptr->process_mode = PNG_READ_IDAT_MODE;
   1.344 +
   1.345 +      if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
   1.346 +         if (png_ptr->push_length == 0)
   1.347 +            return;
   1.348 +
   1.349 +      if (png_ptr->mode & PNG_AFTER_IDAT)
   1.350 +         png_benign_error(png_ptr, "Too many IDATs found");
   1.351 +   }
   1.352 +
   1.353 +   if (chunk_name == png_IHDR)
   1.354 +   {
   1.355 +      if (png_ptr->push_length != 13)
   1.356 +         png_error(png_ptr, "Invalid IHDR length");
   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 +
   1.364 +      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
   1.365 +   }
   1.366 +
   1.367 +   else if (chunk_name == png_IEND)
   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 +
   1.375 +      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
   1.376 +
   1.377 +      png_ptr->process_mode = PNG_READ_DONE_MODE;
   1.378 +      png_push_have_end(png_ptr, info_ptr);
   1.379 +   }
   1.380 +
   1.381 +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   1.382 +   else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
   1.383 +   {
   1.384 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.385 +      {
   1.386 +         png_push_save_buffer(png_ptr);
   1.387 +         return;
   1.388 +      }
   1.389 +
   1.390 +      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
   1.391 +
   1.392 +      if (chunk_name == png_PLTE)
   1.393 +         png_ptr->mode |= PNG_HAVE_PLTE;
   1.394 +   }
   1.395 +#endif
   1.396 +
   1.397 +   else if (chunk_name == png_PLTE)
   1.398 +   {
   1.399 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.400 +      {
   1.401 +         png_push_save_buffer(png_ptr);
   1.402 +         return;
   1.403 +      }
   1.404 +      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
   1.405 +   }
   1.406 +
   1.407 +   else if (chunk_name == png_IDAT)
   1.408 +   {
   1.409 +#ifdef PNG_READ_APNG_SUPPORTED
   1.410 +      png_have_info(png_ptr, info_ptr);
   1.411 +#endif
   1.412 +      png_ptr->idat_size = png_ptr->push_length;
   1.413 +      png_ptr->process_mode = PNG_READ_IDAT_MODE;
   1.414 +      png_push_have_info(png_ptr, info_ptr);
   1.415 +      png_ptr->zstream.avail_out =
   1.416 +          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
   1.417 +          png_ptr->iwidth) + 1;
   1.418 +      png_ptr->zstream.next_out = png_ptr->row_buf;
   1.419 +      return;
   1.420 +   }
   1.421 +
   1.422 +#ifdef PNG_READ_gAMA_SUPPORTED
   1.423 +   else if (png_ptr->chunk_name == png_gAMA)
   1.424 +   {
   1.425 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.426 +      {
   1.427 +         png_push_save_buffer(png_ptr);
   1.428 +         return;
   1.429 +      }
   1.430 +
   1.431 +      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
   1.432 +   }
   1.433 +
   1.434 +#endif
   1.435 +#ifdef PNG_READ_sBIT_SUPPORTED
   1.436 +   else if (png_ptr->chunk_name == png_sBIT)
   1.437 +   {
   1.438 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.439 +      {
   1.440 +         png_push_save_buffer(png_ptr);
   1.441 +         return;
   1.442 +      }
   1.443 +
   1.444 +      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
   1.445 +   }
   1.446 +
   1.447 +#endif
   1.448 +#ifdef PNG_READ_cHRM_SUPPORTED
   1.449 +   else if (png_ptr->chunk_name == png_cHRM)
   1.450 +   {
   1.451 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.452 +      {
   1.453 +         png_push_save_buffer(png_ptr);
   1.454 +         return;
   1.455 +      }
   1.456 +
   1.457 +      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
   1.458 +   }
   1.459 +
   1.460 +#endif
   1.461 +#ifdef PNG_READ_sRGB_SUPPORTED
   1.462 +   else if (chunk_name == png_sRGB)
   1.463 +   {
   1.464 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.465 +      {
   1.466 +         png_push_save_buffer(png_ptr);
   1.467 +         return;
   1.468 +      }
   1.469 +
   1.470 +      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
   1.471 +   }
   1.472 +
   1.473 +#endif
   1.474 +#ifdef PNG_READ_iCCP_SUPPORTED
   1.475 +   else if (png_ptr->chunk_name == png_iCCP)
   1.476 +   {
   1.477 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.478 +      {
   1.479 +         png_push_save_buffer(png_ptr);
   1.480 +         return;
   1.481 +      }
   1.482 +
   1.483 +      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
   1.484 +   }
   1.485 +
   1.486 +#endif
   1.487 +#ifdef PNG_READ_sPLT_SUPPORTED
   1.488 +   else if (chunk_name == png_sPLT)
   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 +
   1.496 +      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
   1.497 +   }
   1.498 +
   1.499 +#endif
   1.500 +#ifdef PNG_READ_tRNS_SUPPORTED
   1.501 +   else if (chunk_name == png_tRNS)
   1.502 +   {
   1.503 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.504 +      {
   1.505 +         png_push_save_buffer(png_ptr);
   1.506 +         return;
   1.507 +      }
   1.508 +
   1.509 +      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
   1.510 +   }
   1.511 +
   1.512 +#endif
   1.513 +#ifdef PNG_READ_bKGD_SUPPORTED
   1.514 +   else if (chunk_name == png_bKGD)
   1.515 +   {
   1.516 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.517 +      {
   1.518 +         png_push_save_buffer(png_ptr);
   1.519 +         return;
   1.520 +      }
   1.521 +
   1.522 +      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
   1.523 +   }
   1.524 +
   1.525 +#endif
   1.526 +#ifdef PNG_READ_hIST_SUPPORTED
   1.527 +   else if (chunk_name == png_hIST)
   1.528 +   {
   1.529 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.530 +      {
   1.531 +         png_push_save_buffer(png_ptr);
   1.532 +         return;
   1.533 +      }
   1.534 +
   1.535 +      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
   1.536 +   }
   1.537 +
   1.538 +#endif
   1.539 +#ifdef PNG_READ_pHYs_SUPPORTED
   1.540 +   else if (chunk_name == png_pHYs)
   1.541 +   {
   1.542 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.543 +      {
   1.544 +         png_push_save_buffer(png_ptr);
   1.545 +         return;
   1.546 +      }
   1.547 +
   1.548 +      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
   1.549 +   }
   1.550 +
   1.551 +#endif
   1.552 +#ifdef PNG_READ_oFFs_SUPPORTED
   1.553 +   else if (chunk_name == png_oFFs)
   1.554 +   {
   1.555 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.556 +      {
   1.557 +         png_push_save_buffer(png_ptr);
   1.558 +         return;
   1.559 +      }
   1.560 +
   1.561 +      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
   1.562 +   }
   1.563 +#endif
   1.564 +
   1.565 +#ifdef PNG_READ_pCAL_SUPPORTED
   1.566 +   else if (chunk_name == png_pCAL)
   1.567 +   {
   1.568 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.569 +      {
   1.570 +         png_push_save_buffer(png_ptr);
   1.571 +         return;
   1.572 +      }
   1.573 +
   1.574 +      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
   1.575 +   }
   1.576 +
   1.577 +#endif
   1.578 +#ifdef PNG_READ_sCAL_SUPPORTED
   1.579 +   else if (chunk_name == png_sCAL)
   1.580 +   {
   1.581 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.582 +      {
   1.583 +         png_push_save_buffer(png_ptr);
   1.584 +         return;
   1.585 +      }
   1.586 +
   1.587 +      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
   1.588 +   }
   1.589 +
   1.590 +#endif
   1.591 +#ifdef PNG_READ_tIME_SUPPORTED
   1.592 +   else if (chunk_name == png_tIME)
   1.593 +   {
   1.594 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.595 +      {
   1.596 +         png_push_save_buffer(png_ptr);
   1.597 +         return;
   1.598 +      }
   1.599 +
   1.600 +      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
   1.601 +   }
   1.602 +
   1.603 +#endif
   1.604 +#ifdef PNG_READ_tEXt_SUPPORTED
   1.605 +   else if (chunk_name == png_tEXt)
   1.606 +   {
   1.607 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.608 +      {
   1.609 +         png_push_save_buffer(png_ptr);
   1.610 +         return;
   1.611 +      }
   1.612 +
   1.613 +      png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
   1.614 +   }
   1.615 +
   1.616 +#endif
   1.617 +#ifdef PNG_READ_zTXt_SUPPORTED
   1.618 +   else if (chunk_name == png_zTXt)
   1.619 +   {
   1.620 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.621 +      {
   1.622 +         png_push_save_buffer(png_ptr);
   1.623 +         return;
   1.624 +      }
   1.625 +
   1.626 +      png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
   1.627 +   }
   1.628 +
   1.629 +#endif
   1.630 +#ifdef PNG_READ_iTXt_SUPPORTED
   1.631 +   else if (chunk_name == png_iTXt)
   1.632 +   {
   1.633 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.634 +      {
   1.635 +         png_push_save_buffer(png_ptr);
   1.636 +         return;
   1.637 +      }
   1.638 +
   1.639 +      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
   1.640 +   }
   1.641 +#endif
   1.642 +
   1.643 +#ifdef PNG_READ_APNG_SUPPORTED
   1.644 +   else if (chunk_name == png_acTL)
   1.645 +   {
   1.646 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.647 +      {
   1.648 +         png_push_save_buffer(png_ptr);
   1.649 +         return;
   1.650 +      }
   1.651 +
   1.652 +      png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
   1.653 +   }
   1.654 +
   1.655 +   else if (chunk_name == png_fcTL)
   1.656 +   {
   1.657 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.658 +      {
   1.659 +         png_push_save_buffer(png_ptr);
   1.660 +         return;
   1.661 +      }
   1.662 +
   1.663 +      png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
   1.664 +   }
   1.665 +
   1.666 +#endif /* PNG_READ_APNG_SUPPORTED */
   1.667 +   else
   1.668 +   {
   1.669 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.670 +      {
   1.671 +         png_push_save_buffer(png_ptr);
   1.672 +         return;
   1.673 +      }
   1.674 +      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
   1.675 +         PNG_HANDLE_CHUNK_AS_DEFAULT);
   1.676 +   }
   1.677 +
   1.678 +   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.679 +}
   1.680 +
   1.681 +void /* PRIVATE */
   1.682 +png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip)
   1.683 +{
   1.684 +   png_ptr->process_mode = PNG_SKIP_MODE;
   1.685 +   png_ptr->skip_length = skip;
   1.686 +}
   1.687 +
   1.688 +void /* PRIVATE */
   1.689 +png_push_crc_finish(png_structrp png_ptr)
   1.690 +{
   1.691 +   if (png_ptr->skip_length && png_ptr->save_buffer_size)
   1.692 +   {
   1.693 +      png_size_t save_size = png_ptr->save_buffer_size;
   1.694 +      png_uint_32 skip_length = png_ptr->skip_length;
   1.695 +
   1.696 +      /* We want the smaller of 'skip_length' and 'save_buffer_size', but
   1.697 +       * they are of different types and we don't know which variable has the
   1.698 +       * fewest bits.  Carefully select the smaller and cast it to the type of
   1.699 +       * the larger - this cannot overflow.  Do not cast in the following test
   1.700 +       * - it will break on either 16 or 64 bit platforms.
   1.701 +       */
   1.702 +      if (skip_length < save_size)
   1.703 +         save_size = (png_size_t)skip_length;
   1.704 +
   1.705 +      else
   1.706 +         skip_length = (png_uint_32)save_size;
   1.707 +
   1.708 +      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
   1.709 +
   1.710 +      png_ptr->skip_length -= skip_length;
   1.711 +      png_ptr->buffer_size -= save_size;
   1.712 +      png_ptr->save_buffer_size -= save_size;
   1.713 +      png_ptr->save_buffer_ptr += save_size;
   1.714 +   }
   1.715 +   if (png_ptr->skip_length && png_ptr->current_buffer_size)
   1.716 +   {
   1.717 +      png_size_t save_size = png_ptr->current_buffer_size;
   1.718 +      png_uint_32 skip_length = png_ptr->skip_length;
   1.719 +
   1.720 +      /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
   1.721 +       * the same problem exists as above and the same solution.
   1.722 +       */
   1.723 +      if (skip_length < save_size)
   1.724 +         save_size = (png_size_t)skip_length;
   1.725 +
   1.726 +      else
   1.727 +         skip_length = (png_uint_32)save_size;
   1.728 +
   1.729 +      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
   1.730 +
   1.731 +      png_ptr->skip_length -= skip_length;
   1.732 +      png_ptr->buffer_size -= save_size;
   1.733 +      png_ptr->current_buffer_size -= save_size;
   1.734 +      png_ptr->current_buffer_ptr += save_size;
   1.735 +   }
   1.736 +   if (!png_ptr->skip_length)
   1.737 +   {
   1.738 +      if (png_ptr->buffer_size < 4)
   1.739 +      {
   1.740 +         png_push_save_buffer(png_ptr);
   1.741 +         return;
   1.742 +      }
   1.743 +
   1.744 +      png_crc_finish(png_ptr, 0);
   1.745 +      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.746 +   }
   1.747 +}
   1.748 +
   1.749 +void PNGCBAPI
   1.750 +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
   1.751 +{
   1.752 +   png_bytep ptr;
   1.753 +
   1.754 +   if (png_ptr == NULL)
   1.755 +      return;
   1.756 +
   1.757 +   ptr = buffer;
   1.758 +   if (png_ptr->save_buffer_size)
   1.759 +   {
   1.760 +      png_size_t save_size;
   1.761 +
   1.762 +      if (length < png_ptr->save_buffer_size)
   1.763 +         save_size = length;
   1.764 +
   1.765 +      else
   1.766 +         save_size = png_ptr->save_buffer_size;
   1.767 +
   1.768 +      memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
   1.769 +      length -= save_size;
   1.770 +      ptr += save_size;
   1.771 +      png_ptr->buffer_size -= save_size;
   1.772 +      png_ptr->save_buffer_size -= save_size;
   1.773 +      png_ptr->save_buffer_ptr += save_size;
   1.774 +   }
   1.775 +   if (length && png_ptr->current_buffer_size)
   1.776 +   {
   1.777 +      png_size_t save_size;
   1.778 +
   1.779 +      if (length < png_ptr->current_buffer_size)
   1.780 +         save_size = length;
   1.781 +
   1.782 +      else
   1.783 +         save_size = png_ptr->current_buffer_size;
   1.784 +
   1.785 +      memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
   1.786 +      png_ptr->buffer_size -= save_size;
   1.787 +      png_ptr->current_buffer_size -= save_size;
   1.788 +      png_ptr->current_buffer_ptr += save_size;
   1.789 +   }
   1.790 +}
   1.791 +
   1.792 +void /* PRIVATE */
   1.793 +png_push_save_buffer(png_structrp png_ptr)
   1.794 +{
   1.795 +   if (png_ptr->save_buffer_size)
   1.796 +   {
   1.797 +      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
   1.798 +      {
   1.799 +         png_size_t i, istop;
   1.800 +         png_bytep sp;
   1.801 +         png_bytep dp;
   1.802 +
   1.803 +         istop = png_ptr->save_buffer_size;
   1.804 +         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
   1.805 +             i < istop; i++, sp++, dp++)
   1.806 +         {
   1.807 +            *dp = *sp;
   1.808 +         }
   1.809 +      }
   1.810 +   }
   1.811 +   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
   1.812 +       png_ptr->save_buffer_max)
   1.813 +   {
   1.814 +      png_size_t new_max;
   1.815 +      png_bytep old_buffer;
   1.816 +
   1.817 +      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
   1.818 +          (png_ptr->current_buffer_size + 256))
   1.819 +      {
   1.820 +         png_error(png_ptr, "Potential overflow of save_buffer");
   1.821 +      }
   1.822 +
   1.823 +      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
   1.824 +      old_buffer = png_ptr->save_buffer;
   1.825 +      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
   1.826 +          (png_size_t)new_max);
   1.827 +
   1.828 +      if (png_ptr->save_buffer == NULL)
   1.829 +      {
   1.830 +         png_free(png_ptr, old_buffer);
   1.831 +         png_error(png_ptr, "Insufficient memory for save_buffer");
   1.832 +      }
   1.833 +
   1.834 +      memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
   1.835 +      png_free(png_ptr, old_buffer);
   1.836 +      png_ptr->save_buffer_max = new_max;
   1.837 +   }
   1.838 +   if (png_ptr->current_buffer_size)
   1.839 +   {
   1.840 +      memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
   1.841 +         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
   1.842 +      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
   1.843 +      png_ptr->current_buffer_size = 0;
   1.844 +   }
   1.845 +   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
   1.846 +   png_ptr->buffer_size = 0;
   1.847 +}
   1.848 +
   1.849 +void /* PRIVATE */
   1.850 +png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
   1.851 +   png_size_t buffer_length)
   1.852 +{
   1.853 +   png_ptr->current_buffer = buffer;
   1.854 +   png_ptr->current_buffer_size = buffer_length;
   1.855 +   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
   1.856 +   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
   1.857 +}
   1.858 +
   1.859 +void /* PRIVATE */
   1.860 +png_push_read_IDAT(png_structrp png_ptr)
   1.861 +{
   1.862 +   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
   1.863 +   {
   1.864 +      png_byte chunk_length[4];
   1.865 +      png_byte chunk_tag[4];
   1.866 +
   1.867 +      /* TODO: this code can be commoned up with the same code in push_read */
   1.868 +#ifdef PNG_READ_APNG_SUPPORTED
   1.869 +      if (png_ptr->buffer_size < 12)
   1.870 +#else
   1.871 +      if (png_ptr->buffer_size < 8)
   1.872 +#endif
   1.873 +      {
   1.874 +         png_push_save_buffer(png_ptr);
   1.875 +         return;
   1.876 +      }
   1.877 +
   1.878 +      png_push_fill_buffer(png_ptr, chunk_length, 4);
   1.879 +      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
   1.880 +      png_reset_crc(png_ptr);
   1.881 +      png_crc_read(png_ptr, chunk_tag, 4);
   1.882 +      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
   1.883 +      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
   1.884 +
   1.885 +#ifdef PNG_READ_APNG_SUPPORTED
   1.886 +      if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
   1.887 +      {
   1.888 +          if (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)
   1.889 +          {
   1.890 +              png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.891 +              if (png_ptr->frame_end_fn != NULL)
   1.892 +                 (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
   1.893 +              png_ptr->num_frames_read++;
   1.894 +              return;
   1.895 +          }
   1.896 +          else
   1.897 +          {
   1.898 +              if (png_ptr->chunk_name == png_IEND)
   1.899 +                  png_error(png_ptr, "Not enough image data");
   1.900 +              if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.901 +              {
   1.902 +                 png_push_save_buffer(png_ptr);
   1.903 +                 return;
   1.904 +              }
   1.905 +              png_warning(png_ptr, "Skipping (ignoring) a chunk between "
   1.906 +                                   "APNG chunks");
   1.907 +              png_crc_finish(png_ptr, png_ptr->push_length);
   1.908 +              png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.909 +              return;
   1.910 +          }
   1.911 +      }
   1.912 +      else
   1.913 +#endif
   1.914 +#ifdef PNG_READ_APNG_SUPPORTED
   1.915 +      if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0)
   1.916 +#else
   1.917 +      if (png_ptr->chunk_name != png_IDAT)
   1.918 +#endif
   1.919 +      {
   1.920 +         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.921 +
   1.922 +         if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
   1.923 +            png_error(png_ptr, "Not enough compressed data");
   1.924 +
   1.925 +#ifdef PNG_READ_APNG_SUPPORTED
   1.926 +         if (png_ptr->frame_end_fn != NULL)
   1.927 +            (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
   1.928 +         png_ptr->num_frames_read++;
   1.929 +#endif
   1.930 +
   1.931 +         return;
   1.932 +      }
   1.933 +
   1.934 +      png_ptr->idat_size = png_ptr->push_length;
   1.935 +
   1.936 +#ifdef PNG_READ_APNG_SUPPORTED
   1.937 +      if (png_ptr->num_frames_read > 0)
   1.938 +      {
   1.939 +         png_ensure_sequence_number(png_ptr, 4);
   1.940 +         png_ptr->idat_size -= 4;
   1.941 +      }
   1.942 +#endif
   1.943 +   }
   1.944 +
   1.945 +   if (png_ptr->idat_size && png_ptr->save_buffer_size)
   1.946 +   {
   1.947 +      png_size_t save_size = png_ptr->save_buffer_size;
   1.948 +      png_uint_32 idat_size = png_ptr->idat_size;
   1.949 +
   1.950 +      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
   1.951 +       * are of different types and we don't know which variable has the fewest
   1.952 +       * bits.  Carefully select the smaller and cast it to the type of the
   1.953 +       * larger - this cannot overflow.  Do not cast in the following test - it
   1.954 +       * will break on either 16 or 64 bit platforms.
   1.955 +       */
   1.956 +      if (idat_size < save_size)
   1.957 +         save_size = (png_size_t)idat_size;
   1.958 +
   1.959 +      else
   1.960 +         idat_size = (png_uint_32)save_size;
   1.961 +
   1.962 +      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
   1.963 +
   1.964 +      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
   1.965 +
   1.966 +      png_ptr->idat_size -= idat_size;
   1.967 +      png_ptr->buffer_size -= save_size;
   1.968 +      png_ptr->save_buffer_size -= save_size;
   1.969 +      png_ptr->save_buffer_ptr += save_size;
   1.970 +   }
   1.971 +
   1.972 +   if (png_ptr->idat_size && png_ptr->current_buffer_size)
   1.973 +   {
   1.974 +      png_size_t save_size = png_ptr->current_buffer_size;
   1.975 +      png_uint_32 idat_size = png_ptr->idat_size;
   1.976 +
   1.977 +      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
   1.978 +       * are of different types and we don't know which variable has the fewest
   1.979 +       * bits.  Carefully select the smaller and cast it to the type of the
   1.980 +       * larger - this cannot overflow.
   1.981 +       */
   1.982 +      if (idat_size < save_size)
   1.983 +         save_size = (png_size_t)idat_size;
   1.984 +
   1.985 +      else
   1.986 +         idat_size = (png_uint_32)save_size;
   1.987 +
   1.988 +      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
   1.989 +
   1.990 +      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
   1.991 +
   1.992 +      png_ptr->idat_size -= idat_size;
   1.993 +      png_ptr->buffer_size -= save_size;
   1.994 +      png_ptr->current_buffer_size -= save_size;
   1.995 +      png_ptr->current_buffer_ptr += save_size;
   1.996 +   }
   1.997 +   if (!png_ptr->idat_size)
   1.998 +   {
   1.999 +      if (png_ptr->buffer_size < 4)
  1.1000 +      {
  1.1001 +         png_push_save_buffer(png_ptr);
  1.1002 +         return;
  1.1003 +      }
  1.1004 +
  1.1005 +      png_crc_finish(png_ptr, 0);
  1.1006 +      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
  1.1007 +      png_ptr->mode |= PNG_AFTER_IDAT;
  1.1008 +      png_ptr->zowner = 0;
  1.1009 +   }
  1.1010 +}
  1.1011 +
  1.1012 +void /* PRIVATE */
  1.1013 +png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
  1.1014 +   png_size_t buffer_length)
  1.1015 +{
  1.1016 +   /* The caller checks for a non-zero buffer length. */
  1.1017 +   if (!(buffer_length > 0) || buffer == NULL)
  1.1018 +      png_error(png_ptr, "No IDAT data (internal error)");
  1.1019 +
  1.1020 +#ifdef PNG_READ_APNG_SUPPORTED
  1.1021 +   /* If the app is not APNG-aware, decode only the first frame */
  1.1022 +   if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
  1.1023 +   {
  1.1024 +     png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
  1.1025 +     return;
  1.1026 +   }
  1.1027 +#endif
  1.1028 +
  1.1029 +   /* This routine must process all the data it has been given
  1.1030 +    * before returning, calling the row callback as required to
  1.1031 +    * handle the uncompressed results.
  1.1032 +    */
  1.1033 +   png_ptr->zstream.next_in = buffer;
  1.1034 +   /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
  1.1035 +   png_ptr->zstream.avail_in = (uInt)buffer_length;
  1.1036 +
  1.1037 +   /* Keep going until the decompressed data is all processed
  1.1038 +    * or the stream marked as finished.
  1.1039 +    */
  1.1040 +   while (png_ptr->zstream.avail_in > 0 &&
  1.1041 +      !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
  1.1042 +   {
  1.1043 +      int ret;
  1.1044 +
  1.1045 +      /* We have data for zlib, but we must check that zlib
  1.1046 +       * has someplace to put the results.  It doesn't matter
  1.1047 +       * if we don't expect any results -- it may be the input
  1.1048 +       * data is just the LZ end code.
  1.1049 +       */
  1.1050 +      if (!(png_ptr->zstream.avail_out > 0))
  1.1051 +      {
  1.1052 +         /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
  1.1053 +         png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
  1.1054 +             png_ptr->iwidth) + 1);
  1.1055 +
  1.1056 +         png_ptr->zstream.next_out = png_ptr->row_buf;
  1.1057 +      }
  1.1058 +
  1.1059 +      /* Using Z_SYNC_FLUSH here means that an unterminated
  1.1060 +       * LZ stream (a stream with a missing end code) can still
  1.1061 +       * be handled, otherwise (Z_NO_FLUSH) a future zlib
  1.1062 +       * implementation might defer output and therefore
  1.1063 +       * change the current behavior (see comments in inflate.c
  1.1064 +       * for why this doesn't happen at present with zlib 1.2.5).
  1.1065 +       */
  1.1066 +      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
  1.1067 +
  1.1068 +      /* Check for any failure before proceeding. */
  1.1069 +      if (ret != Z_OK && ret != Z_STREAM_END)
  1.1070 +      {
  1.1071 +         /* Terminate the decompression. */
  1.1072 +         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
  1.1073 +         png_ptr->zowner = 0;
  1.1074 +
  1.1075 +         /* This may be a truncated stream (missing or
  1.1076 +          * damaged end code).  Treat that as a warning.
  1.1077 +          */
  1.1078 +         if (png_ptr->row_number >= png_ptr->num_rows ||
  1.1079 +             png_ptr->pass > 6)
  1.1080 +            png_warning(png_ptr, "Truncated compressed data in IDAT");
  1.1081 +
  1.1082 +         else
  1.1083 +            png_error(png_ptr, "Decompression error in IDAT");
  1.1084 +
  1.1085 +         /* Skip the check on unprocessed input */
  1.1086 +         return;
  1.1087 +      }
  1.1088 +
  1.1089 +      /* Did inflate output any data? */
  1.1090 +      if (png_ptr->zstream.next_out != png_ptr->row_buf)
  1.1091 +      {
  1.1092 +         /* Is this unexpected data after the last row?
  1.1093 +          * If it is, artificially terminate the LZ output
  1.1094 +          * here.
  1.1095 +          */
  1.1096 +         if (png_ptr->row_number >= png_ptr->num_rows ||
  1.1097 +             png_ptr->pass > 6)
  1.1098 +         {
  1.1099 +            /* Extra data. */
  1.1100 +            png_warning(png_ptr, "Extra compressed data in IDAT");
  1.1101 +            png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
  1.1102 +            png_ptr->zowner = 0;
  1.1103 +
  1.1104 +            /* Do no more processing; skip the unprocessed
  1.1105 +             * input check below.
  1.1106 +             */
  1.1107 +            return;
  1.1108 +         }
  1.1109 +
  1.1110 +         /* Do we have a complete row? */
  1.1111 +         if (png_ptr->zstream.avail_out == 0)
  1.1112 +            png_push_process_row(png_ptr);
  1.1113 +      }
  1.1114 +
  1.1115 +      /* And check for the end of the stream. */
  1.1116 +      if (ret == Z_STREAM_END)
  1.1117 +         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
  1.1118 +   }
  1.1119 +
  1.1120 +   /* All the data should have been processed, if anything
  1.1121 +    * is left at this point we have bytes of IDAT data
  1.1122 +    * after the zlib end code.
  1.1123 +    */
  1.1124 +   if (png_ptr->zstream.avail_in > 0)
  1.1125 +      png_warning(png_ptr, "Extra compression data in IDAT");
  1.1126 +}
  1.1127 +
  1.1128 +void /* PRIVATE */
  1.1129 +png_push_process_row(png_structrp png_ptr)
  1.1130 +{
  1.1131 +   /* 1.5.6: row_info moved out of png_struct to a local here. */
  1.1132 +   png_row_info row_info;
  1.1133 +
  1.1134 +   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
  1.1135 +   row_info.color_type = png_ptr->color_type;
  1.1136 +   row_info.bit_depth = png_ptr->bit_depth;
  1.1137 +   row_info.channels = png_ptr->channels;
  1.1138 +   row_info.pixel_depth = png_ptr->pixel_depth;
  1.1139 +   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
  1.1140 +
  1.1141 +   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
  1.1142 +   {
  1.1143 +      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
  1.1144 +         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
  1.1145 +            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
  1.1146 +      else
  1.1147 +         png_error(png_ptr, "bad adaptive filter value");
  1.1148 +   }
  1.1149 +
  1.1150 +   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
  1.1151 +    * 1.5.6, while the buffer really is this big in current versions of libpng
  1.1152 +    * it may not be in the future, so this was changed just to copy the
  1.1153 +    * interlaced row count:
  1.1154 +    */
  1.1155 +   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
  1.1156 +
  1.1157 +#ifdef PNG_READ_TRANSFORMS_SUPPORTED
  1.1158 +   if (png_ptr->transformations)
  1.1159 +      png_do_read_transformations(png_ptr, &row_info);
  1.1160 +#endif
  1.1161 +
  1.1162 +   /* The transformed pixel depth should match the depth now in row_info. */
  1.1163 +   if (png_ptr->transformed_pixel_depth == 0)
  1.1164 +   {
  1.1165 +      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
  1.1166 +      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
  1.1167 +         png_error(png_ptr, "progressive row overflow");
  1.1168 +   }
  1.1169 +
  1.1170 +   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
  1.1171 +      png_error(png_ptr, "internal progressive row size calculation error");
  1.1172 +
  1.1173 +
  1.1174 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.1175 +   /* Blow up interlaced rows to full size */
  1.1176 +   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
  1.1177 +   {
  1.1178 +      if (png_ptr->pass < 6)
  1.1179 +         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
  1.1180 +            png_ptr->transformations);
  1.1181 +
  1.1182 +    switch (png_ptr->pass)
  1.1183 +    {
  1.1184 +         case 0:
  1.1185 +         {
  1.1186 +            int i;
  1.1187 +            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  1.1188 +            {
  1.1189 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1190 +               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
  1.1191 +            }
  1.1192 +
  1.1193 +            if (png_ptr->pass == 2) /* Pass 1 might be empty */
  1.1194 +            {
  1.1195 +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1.1196 +               {
  1.1197 +                  png_push_have_row(png_ptr, NULL);
  1.1198 +                  png_read_push_finish_row(png_ptr);
  1.1199 +               }
  1.1200 +            }
  1.1201 +
  1.1202 +            if (png_ptr->pass == 4 && png_ptr->height <= 4)
  1.1203 +            {
  1.1204 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1.1205 +               {
  1.1206 +                  png_push_have_row(png_ptr, NULL);
  1.1207 +                  png_read_push_finish_row(png_ptr);
  1.1208 +               }
  1.1209 +            }
  1.1210 +
  1.1211 +            if (png_ptr->pass == 6 && png_ptr->height <= 4)
  1.1212 +            {
  1.1213 +                png_push_have_row(png_ptr, NULL);
  1.1214 +                png_read_push_finish_row(png_ptr);
  1.1215 +            }
  1.1216 +
  1.1217 +            break;
  1.1218 +         }
  1.1219 +
  1.1220 +         case 1:
  1.1221 +         {
  1.1222 +            int i;
  1.1223 +            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  1.1224 +            {
  1.1225 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1226 +               png_read_push_finish_row(png_ptr);
  1.1227 +            }
  1.1228 +
  1.1229 +            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
  1.1230 +            {
  1.1231 +               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1.1232 +               {
  1.1233 +                  png_push_have_row(png_ptr, NULL);
  1.1234 +                  png_read_push_finish_row(png_ptr);
  1.1235 +               }
  1.1236 +            }
  1.1237 +
  1.1238 +            break;
  1.1239 +         }
  1.1240 +
  1.1241 +         case 2:
  1.1242 +         {
  1.1243 +            int i;
  1.1244 +
  1.1245 +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1.1246 +            {
  1.1247 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1248 +               png_read_push_finish_row(png_ptr);
  1.1249 +            }
  1.1250 +
  1.1251 +            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  1.1252 +            {
  1.1253 +               png_push_have_row(png_ptr, NULL);
  1.1254 +               png_read_push_finish_row(png_ptr);
  1.1255 +            }
  1.1256 +
  1.1257 +            if (png_ptr->pass == 4) /* Pass 3 might be empty */
  1.1258 +            {
  1.1259 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1.1260 +               {
  1.1261 +                  png_push_have_row(png_ptr, NULL);
  1.1262 +                  png_read_push_finish_row(png_ptr);
  1.1263 +               }
  1.1264 +            }
  1.1265 +
  1.1266 +            break;
  1.1267 +         }
  1.1268 +
  1.1269 +         case 3:
  1.1270 +         {
  1.1271 +            int i;
  1.1272 +
  1.1273 +            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  1.1274 +            {
  1.1275 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1276 +               png_read_push_finish_row(png_ptr);
  1.1277 +            }
  1.1278 +
  1.1279 +            if (png_ptr->pass == 4) /* Skip top two generated rows */
  1.1280 +            {
  1.1281 +               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1.1282 +               {
  1.1283 +                  png_push_have_row(png_ptr, NULL);
  1.1284 +                  png_read_push_finish_row(png_ptr);
  1.1285 +               }
  1.1286 +            }
  1.1287 +
  1.1288 +            break;
  1.1289 +         }
  1.1290 +
  1.1291 +         case 4:
  1.1292 +         {
  1.1293 +            int i;
  1.1294 +
  1.1295 +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1.1296 +            {
  1.1297 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1298 +               png_read_push_finish_row(png_ptr);
  1.1299 +            }
  1.1300 +
  1.1301 +            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  1.1302 +            {
  1.1303 +               png_push_have_row(png_ptr, NULL);
  1.1304 +               png_read_push_finish_row(png_ptr);
  1.1305 +            }
  1.1306 +
  1.1307 +            if (png_ptr->pass == 6) /* Pass 5 might be empty */
  1.1308 +            {
  1.1309 +               png_push_have_row(png_ptr, NULL);
  1.1310 +               png_read_push_finish_row(png_ptr);
  1.1311 +            }
  1.1312 +
  1.1313 +            break;
  1.1314 +         }
  1.1315 +
  1.1316 +         case 5:
  1.1317 +         {
  1.1318 +            int i;
  1.1319 +
  1.1320 +            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  1.1321 +            {
  1.1322 +               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1323 +               png_read_push_finish_row(png_ptr);
  1.1324 +            }
  1.1325 +
  1.1326 +            if (png_ptr->pass == 6) /* Skip top generated row */
  1.1327 +            {
  1.1328 +               png_push_have_row(png_ptr, NULL);
  1.1329 +               png_read_push_finish_row(png_ptr);
  1.1330 +            }
  1.1331 +
  1.1332 +            break;
  1.1333 +         }
  1.1334 +
  1.1335 +         default:
  1.1336 +         case 6:
  1.1337 +         {
  1.1338 +            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1339 +            png_read_push_finish_row(png_ptr);
  1.1340 +
  1.1341 +            if (png_ptr->pass != 6)
  1.1342 +               break;
  1.1343 +
  1.1344 +            png_push_have_row(png_ptr, NULL);
  1.1345 +            png_read_push_finish_row(png_ptr);
  1.1346 +         }
  1.1347 +      }
  1.1348 +   }
  1.1349 +   else
  1.1350 +#endif
  1.1351 +   {
  1.1352 +      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  1.1353 +      png_read_push_finish_row(png_ptr);
  1.1354 +   }
  1.1355 +}
  1.1356 +
  1.1357 +void /* PRIVATE */
  1.1358 +png_read_push_finish_row(png_structrp png_ptr)
  1.1359 +{
  1.1360 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.1361 +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1.1362 +
  1.1363 +   /* Start of interlace block */
  1.1364 +   static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
  1.1365 +
  1.1366 +   /* Offset to next interlace block */
  1.1367 +   static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  1.1368 +
  1.1369 +   /* Start of interlace block in the y direction */
  1.1370 +   static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  1.1371 +
  1.1372 +   /* Offset to next interlace block in the y direction */
  1.1373 +   static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  1.1374 +
  1.1375 +   /* Height of interlace block.  This is not currently used - if you need
  1.1376 +    * it, uncomment it here and in png.h
  1.1377 +   static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
  1.1378 +   */
  1.1379 +#endif
  1.1380 +
  1.1381 +   png_ptr->row_number++;
  1.1382 +   if (png_ptr->row_number < png_ptr->num_rows)
  1.1383 +      return;
  1.1384 +
  1.1385 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.1386 +   if (png_ptr->interlaced)
  1.1387 +   {
  1.1388 +      png_ptr->row_number = 0;
  1.1389 +      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  1.1390 +
  1.1391 +      do
  1.1392 +      {
  1.1393 +         png_ptr->pass++;
  1.1394 +         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
  1.1395 +             (png_ptr->pass == 3 && png_ptr->width < 3) ||
  1.1396 +             (png_ptr->pass == 5 && png_ptr->width < 2))
  1.1397 +            png_ptr->pass++;
  1.1398 +
  1.1399 +         if (png_ptr->pass > 7)
  1.1400 +            png_ptr->pass--;
  1.1401 +
  1.1402 +         if (png_ptr->pass >= 7)
  1.1403 +            break;
  1.1404 +
  1.1405 +         png_ptr->iwidth = (png_ptr->width +
  1.1406 +             png_pass_inc[png_ptr->pass] - 1 -
  1.1407 +             png_pass_start[png_ptr->pass]) /
  1.1408 +             png_pass_inc[png_ptr->pass];
  1.1409 +
  1.1410 +         if (png_ptr->transformations & PNG_INTERLACE)
  1.1411 +            break;
  1.1412 +
  1.1413 +         png_ptr->num_rows = (png_ptr->height +
  1.1414 +             png_pass_yinc[png_ptr->pass] - 1 -
  1.1415 +             png_pass_ystart[png_ptr->pass]) /
  1.1416 +             png_pass_yinc[png_ptr->pass];
  1.1417 +
  1.1418 +      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
  1.1419 +   }
  1.1420 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.1421 +}
  1.1422 +
  1.1423 +void /* PRIVATE */
  1.1424 +png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
  1.1425 +{
  1.1426 +   if (png_ptr->info_fn != NULL)
  1.1427 +      (*(png_ptr->info_fn))(png_ptr, info_ptr);
  1.1428 +}
  1.1429 +
  1.1430 +void /* PRIVATE */
  1.1431 +png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
  1.1432 +{
  1.1433 +   if (png_ptr->end_fn != NULL)
  1.1434 +      (*(png_ptr->end_fn))(png_ptr, info_ptr);
  1.1435 +}
  1.1436 +
  1.1437 +void /* PRIVATE */
  1.1438 +png_push_have_row(png_structrp png_ptr, png_bytep row)
  1.1439 +{
  1.1440 +   if (png_ptr->row_fn != NULL)
  1.1441 +      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  1.1442 +         (int)png_ptr->pass);
  1.1443 +}
  1.1444 +
  1.1445 +#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.1446 +void PNGAPI
  1.1447 +png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
  1.1448 +    png_const_bytep new_row)
  1.1449 +{
  1.1450 +   if (png_ptr == NULL)
  1.1451 +      return;
  1.1452 +
  1.1453 +   /* new_row is a flag here - if it is NULL then the app callback was called
  1.1454 +    * from an empty row (see the calls to png_struct::row_fn below), otherwise
  1.1455 +    * it must be png_ptr->row_buf+1
  1.1456 +    */
  1.1457 +   if (new_row != NULL)
  1.1458 +      png_combine_row(png_ptr, old_row, 1/*display*/);
  1.1459 +}
  1.1460 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.1461 +
  1.1462 +void PNGAPI
  1.1463 +png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
  1.1464 +    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1.1465 +    png_progressive_end_ptr end_fn)
  1.1466 +{
  1.1467 +   if (png_ptr == NULL)
  1.1468 +      return;
  1.1469 +
  1.1470 +   png_ptr->info_fn = info_fn;
  1.1471 +   png_ptr->row_fn = row_fn;
  1.1472 +   png_ptr->end_fn = end_fn;
  1.1473 +
  1.1474 +   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
  1.1475 +}
  1.1476 +
  1.1477 +#ifdef PNG_READ_APNG_SUPPORTED
  1.1478 +void PNGAPI
  1.1479 +png_set_progressive_frame_fn(png_structp png_ptr,
  1.1480 +   png_progressive_frame_ptr frame_info_fn,
  1.1481 +   png_progressive_frame_ptr frame_end_fn)
  1.1482 +{
  1.1483 +   png_ptr->frame_info_fn = frame_info_fn;
  1.1484 +   png_ptr->frame_end_fn = frame_end_fn;
  1.1485 +   png_ptr->apng_flags |= PNG_APNG_APP;
  1.1486 +}
  1.1487 +#endif
  1.1488 +
  1.1489 +png_voidp PNGAPI
  1.1490 +png_get_progressive_ptr(png_const_structrp png_ptr)
  1.1491 +{
  1.1492 +   if (png_ptr == NULL)
  1.1493 +      return (NULL);
  1.1494 +
  1.1495 +   return png_ptr->io_ptr;
  1.1496 +}
  1.1497 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

mercurial