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 */