1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libpng/pngrutil.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,4767 @@ 1.4 + 1.5 +/* pngrutil.c - utilities to read a PNG file 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 + * This file contains routines that are only called from within 1.17 + * libpng itself during the course of reading an image. 1.18 + */ 1.19 + 1.20 +#include "pngpriv.h" 1.21 + 1.22 +#ifdef PNG_READ_SUPPORTED 1.23 + 1.24 +png_uint_32 PNGAPI 1.25 +png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) 1.26 +{ 1.27 + png_uint_32 uval = png_get_uint_32(buf); 1.28 + 1.29 + if (uval > PNG_UINT_31_MAX) 1.30 + png_error(png_ptr, "PNG unsigned integer out of range"); 1.31 + 1.32 + return (uval); 1.33 +} 1.34 + 1.35 +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) 1.36 +/* The following is a variation on the above for use with the fixed 1.37 + * point values used for gAMA and cHRM. Instead of png_error it 1.38 + * issues a warning and returns (-1) - an invalid value because both 1.39 + * gAMA and cHRM use *unsigned* integers for fixed point values. 1.40 + */ 1.41 +#define PNG_FIXED_ERROR (-1) 1.42 + 1.43 +static png_fixed_point /* PRIVATE */ 1.44 +png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) 1.45 +{ 1.46 + png_uint_32 uval = png_get_uint_32(buf); 1.47 + 1.48 + if (uval <= PNG_UINT_31_MAX) 1.49 + return (png_fixed_point)uval; /* known to be in range */ 1.50 + 1.51 + /* The caller can turn off the warning by passing NULL. */ 1.52 + if (png_ptr != NULL) 1.53 + png_warning(png_ptr, "PNG fixed point integer out of range"); 1.54 + 1.55 + return PNG_FIXED_ERROR; 1.56 +} 1.57 +#endif 1.58 + 1.59 +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED 1.60 +/* NOTE: the read macros will obscure these definitions, so that if 1.61 + * PNG_USE_READ_MACROS is set the library will not use them internally, 1.62 + * but the APIs will still be available externally. 1.63 + * 1.64 + * The parentheses around "PNGAPI function_name" in the following three 1.65 + * functions are necessary because they allow the macros to co-exist with 1.66 + * these (unused but exported) functions. 1.67 + */ 1.68 + 1.69 +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ 1.70 +png_uint_32 (PNGAPI 1.71 +png_get_uint_32)(png_const_bytep buf) 1.72 +{ 1.73 + png_uint_32 uval = 1.74 + ((png_uint_32)(*(buf )) << 24) + 1.75 + ((png_uint_32)(*(buf + 1)) << 16) + 1.76 + ((png_uint_32)(*(buf + 2)) << 8) + 1.77 + ((png_uint_32)(*(buf + 3)) ) ; 1.78 + 1.79 + return uval; 1.80 +} 1.81 + 1.82 +/* Grab a signed 32-bit integer from a buffer in big-endian format. The 1.83 + * data is stored in the PNG file in two's complement format and there 1.84 + * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore 1.85 + * the following code does a two's complement to native conversion. 1.86 + */ 1.87 +png_int_32 (PNGAPI 1.88 +png_get_int_32)(png_const_bytep buf) 1.89 +{ 1.90 + png_uint_32 uval = png_get_uint_32(buf); 1.91 + if ((uval & 0x80000000) == 0) /* non-negative */ 1.92 + return uval; 1.93 + 1.94 + uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ 1.95 + return -(png_int_32)uval; 1.96 +} 1.97 + 1.98 +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ 1.99 +png_uint_16 (PNGAPI 1.100 +png_get_uint_16)(png_const_bytep buf) 1.101 +{ 1.102 + /* ANSI-C requires an int value to accomodate at least 16 bits so this 1.103 + * works and allows the compiler not to worry about possible narrowing 1.104 + * on 32 bit systems. (Pre-ANSI systems did not make integers smaller 1.105 + * than 16 bits either.) 1.106 + */ 1.107 + unsigned int val = 1.108 + ((unsigned int)(*buf) << 8) + 1.109 + ((unsigned int)(*(buf + 1))); 1.110 + 1.111 + return (png_uint_16)val; 1.112 +} 1.113 + 1.114 +#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ 1.115 + 1.116 +/* Read and check the PNG file signature */ 1.117 +void /* PRIVATE */ 1.118 +png_read_sig(png_structrp png_ptr, png_inforp info_ptr) 1.119 +{ 1.120 + png_size_t num_checked, num_to_check; 1.121 + 1.122 + /* Exit if the user application does not expect a signature. */ 1.123 + if (png_ptr->sig_bytes >= 8) 1.124 + return; 1.125 + 1.126 + num_checked = png_ptr->sig_bytes; 1.127 + num_to_check = 8 - num_checked; 1.128 + 1.129 +#ifdef PNG_IO_STATE_SUPPORTED 1.130 + png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; 1.131 +#endif 1.132 + 1.133 + /* The signature must be serialized in a single I/O call. */ 1.134 + png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); 1.135 + png_ptr->sig_bytes = 8; 1.136 + 1.137 + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) 1.138 + { 1.139 + if (num_checked < 4 && 1.140 + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) 1.141 + png_error(png_ptr, "Not a PNG file"); 1.142 + else 1.143 + png_error(png_ptr, "PNG file corrupted by ASCII conversion"); 1.144 + } 1.145 + if (num_checked < 3) 1.146 + png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; 1.147 +} 1.148 + 1.149 +/* Read the chunk header (length + type name). 1.150 + * Put the type name into png_ptr->chunk_name, and return the length. 1.151 + */ 1.152 +png_uint_32 /* PRIVATE */ 1.153 +png_read_chunk_header(png_structrp png_ptr) 1.154 +{ 1.155 + png_byte buf[8]; 1.156 + png_uint_32 length; 1.157 + 1.158 +#ifdef PNG_IO_STATE_SUPPORTED 1.159 + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; 1.160 +#endif 1.161 + 1.162 + /* Read the length and the chunk name. 1.163 + * This must be performed in a single I/O call. 1.164 + */ 1.165 + png_read_data(png_ptr, buf, 8); 1.166 + length = png_get_uint_31(png_ptr, buf); 1.167 + 1.168 + /* Put the chunk name into png_ptr->chunk_name. */ 1.169 + png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); 1.170 + 1.171 + png_debug2(0, "Reading %lx chunk, length = %lu", 1.172 + (unsigned long)png_ptr->chunk_name, (unsigned long)length); 1.173 + 1.174 + /* Reset the crc and run it over the chunk name. */ 1.175 + png_reset_crc(png_ptr); 1.176 + png_calculate_crc(png_ptr, buf + 4, 4); 1.177 + 1.178 + /* Check to see if chunk name is valid. */ 1.179 + png_check_chunk_name(png_ptr, png_ptr->chunk_name); 1.180 + 1.181 +#ifdef PNG_IO_STATE_SUPPORTED 1.182 + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; 1.183 +#endif 1.184 + 1.185 + return length; 1.186 +} 1.187 + 1.188 +/* Read data, and (optionally) run it through the CRC. */ 1.189 +void /* PRIVATE */ 1.190 +png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) 1.191 +{ 1.192 + if (png_ptr == NULL) 1.193 + return; 1.194 + 1.195 + png_read_data(png_ptr, buf, length); 1.196 + png_calculate_crc(png_ptr, buf, length); 1.197 +} 1.198 + 1.199 +/* Optionally skip data and then check the CRC. Depending on whether we 1.200 + * are reading an ancillary or critical chunk, and how the program has set 1.201 + * things up, we may calculate the CRC on the data and print a message. 1.202 + * Returns '1' if there was a CRC error, '0' otherwise. 1.203 + */ 1.204 +int /* PRIVATE */ 1.205 +png_crc_finish(png_structrp png_ptr, png_uint_32 skip) 1.206 +{ 1.207 + /* The size of the local buffer for inflate is a good guess as to a 1.208 + * reasonable size to use for buffering reads from the application. 1.209 + */ 1.210 + while (skip > 0) 1.211 + { 1.212 + png_uint_32 len; 1.213 + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; 1.214 + 1.215 + len = (sizeof tmpbuf); 1.216 + if (len > skip) 1.217 + len = skip; 1.218 + skip -= len; 1.219 + 1.220 + png_crc_read(png_ptr, tmpbuf, len); 1.221 + } 1.222 + 1.223 + if (png_crc_error(png_ptr)) 1.224 + { 1.225 + if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) ? 1.226 + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) : 1.227 + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)) 1.228 + { 1.229 + png_chunk_warning(png_ptr, "CRC error"); 1.230 + } 1.231 + 1.232 + else 1.233 + png_chunk_error(png_ptr, "CRC error"); 1.234 + 1.235 + return (1); 1.236 + } 1.237 + 1.238 + return (0); 1.239 +} 1.240 + 1.241 +/* Compare the CRC stored in the PNG file with that calculated by libpng from 1.242 + * the data it has read thus far. 1.243 + */ 1.244 +int /* PRIVATE */ 1.245 +png_crc_error(png_structrp png_ptr) 1.246 +{ 1.247 + png_byte crc_bytes[4]; 1.248 + png_uint_32 crc; 1.249 + int need_crc = 1; 1.250 + 1.251 + if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)) 1.252 + { 1.253 + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 1.254 + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 1.255 + need_crc = 0; 1.256 + } 1.257 + 1.258 + else /* critical */ 1.259 + { 1.260 + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 1.261 + need_crc = 0; 1.262 + } 1.263 + 1.264 +#ifdef PNG_IO_STATE_SUPPORTED 1.265 + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; 1.266 +#endif 1.267 + 1.268 + /* The chunk CRC must be serialized in a single I/O call. */ 1.269 + png_read_data(png_ptr, crc_bytes, 4); 1.270 + 1.271 + if (need_crc) 1.272 + { 1.273 + crc = png_get_uint_32(crc_bytes); 1.274 + return ((int)(crc != png_ptr->crc)); 1.275 + } 1.276 + 1.277 + else 1.278 + return (0); 1.279 +} 1.280 + 1.281 +#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ 1.282 + defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ 1.283 + defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ 1.284 + defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) 1.285 +/* Manage the read buffer; this simply reallocates the buffer if it is not small 1.286 + * enough (or if it is not allocated). The routine returns a pointer to the 1.287 + * buffer; if an error occurs and 'warn' is set the routine returns NULL, else 1.288 + * it will call png_error (via png_malloc) on failure. (warn == 2 means 1.289 + * 'silent'). 1.290 + */ 1.291 +static png_bytep 1.292 +png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) 1.293 +{ 1.294 + png_bytep buffer = png_ptr->read_buffer; 1.295 + 1.296 + if (buffer != NULL && new_size > png_ptr->read_buffer_size) 1.297 + { 1.298 + png_ptr->read_buffer = NULL; 1.299 + png_ptr->read_buffer = NULL; 1.300 + png_ptr->read_buffer_size = 0; 1.301 + png_free(png_ptr, buffer); 1.302 + buffer = NULL; 1.303 + } 1.304 + 1.305 + if (buffer == NULL) 1.306 + { 1.307 + buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); 1.308 + 1.309 + if (buffer != NULL) 1.310 + { 1.311 + png_ptr->read_buffer = buffer; 1.312 + png_ptr->read_buffer_size = new_size; 1.313 + } 1.314 + 1.315 + else if (warn < 2) /* else silent */ 1.316 + { 1.317 + if (warn) 1.318 + png_chunk_warning(png_ptr, "insufficient memory to read chunk"); 1.319 + 1.320 + else 1.321 + png_chunk_error(png_ptr, "insufficient memory to read chunk"); 1.322 + } 1.323 + } 1.324 + 1.325 + return buffer; 1.326 +} 1.327 +#endif /* PNG_READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ 1.328 + 1.329 +/* png_inflate_claim: claim the zstream for some nefarious purpose that involves 1.330 + * decompression. Returns Z_OK on success, else a zlib error code. It checks 1.331 + * the owner but, in final release builds, just issues a warning if some other 1.332 + * chunk apparently owns the stream. Prior to release it does a png_error. 1.333 + */ 1.334 +static int 1.335 +png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) 1.336 +{ 1.337 + if (png_ptr->zowner != 0) 1.338 + { 1.339 + char msg[64]; 1.340 + 1.341 + PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); 1.342 + /* So the message that results is "<chunk> using zstream"; this is an 1.343 + * internal error, but is very useful for debugging. i18n requirements 1.344 + * are minimal. 1.345 + */ 1.346 + (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); 1.347 +# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC 1.348 + png_chunk_warning(png_ptr, msg); 1.349 + png_ptr->zowner = 0; 1.350 +# else 1.351 + png_chunk_error(png_ptr, msg); 1.352 +# endif 1.353 + } 1.354 + 1.355 + /* Implementation note: unlike 'png_deflate_claim' this internal function 1.356 + * does not take the size of the data as an argument. Some efficiency could 1.357 + * be gained by using this when it is known *if* the zlib stream itself does 1.358 + * not record the number; however, this is an illusion: the original writer 1.359 + * of the PNG may have selected a lower window size, and we really must 1.360 + * follow that because, for systems with with limited capabilities, we 1.361 + * would otherwise reject the application's attempts to use a smaller window 1.362 + * size (zlib doesn't have an interface to say "this or lower"!). 1.363 + * 1.364 + * inflateReset2 was added to zlib 1.2.4; before this the window could not be 1.365 + * reset, therefore it is necessary to always allocate the maximum window 1.366 + * size with earlier zlibs just in case later compressed chunks need it. 1.367 + */ 1.368 + { 1.369 + int ret; /* zlib return code */ 1.370 +# if PNG_ZLIB_VERNUM >= 0x1240 1.371 + 1.372 +# if defined(PNG_SET_OPTION_SUPPORTED) && \ 1.373 + defined(PNG_MAXIMUM_INFLATE_WINDOW) 1.374 + int window_bits; 1.375 + 1.376 + if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == 1.377 + PNG_OPTION_ON) 1.378 + window_bits = 15; 1.379 + 1.380 + else 1.381 + window_bits = 0; 1.382 +# else 1.383 +# define window_bits 0 1.384 +# endif 1.385 +# endif 1.386 + 1.387 + /* Set this for safety, just in case the previous owner left pointers to 1.388 + * memory allocations. 1.389 + */ 1.390 + png_ptr->zstream.next_in = NULL; 1.391 + png_ptr->zstream.avail_in = 0; 1.392 + png_ptr->zstream.next_out = NULL; 1.393 + png_ptr->zstream.avail_out = 0; 1.394 + 1.395 + if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) 1.396 + { 1.397 +# if PNG_ZLIB_VERNUM < 0x1240 1.398 + ret = inflateReset(&png_ptr->zstream); 1.399 +# else 1.400 + ret = inflateReset2(&png_ptr->zstream, window_bits); 1.401 +# endif 1.402 + } 1.403 + 1.404 + else 1.405 + { 1.406 +# if PNG_ZLIB_VERNUM < 0x1240 1.407 + ret = inflateInit(&png_ptr->zstream); 1.408 +# else 1.409 + ret = inflateInit2(&png_ptr->zstream, window_bits); 1.410 +# endif 1.411 + 1.412 + if (ret == Z_OK) 1.413 + png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; 1.414 + } 1.415 + 1.416 + if (ret == Z_OK) 1.417 + png_ptr->zowner = owner; 1.418 + 1.419 + else 1.420 + png_zstream_error(png_ptr, ret); 1.421 + 1.422 + return ret; 1.423 + } 1.424 + 1.425 +# ifdef window_bits 1.426 +# undef window_bits 1.427 +# endif 1.428 +} 1.429 + 1.430 +#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED 1.431 +/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to 1.432 + * allow the caller to do multiple calls if required. If the 'finish' flag is 1.433 + * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must 1.434 + * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and 1.435 + * Z_OK or Z_STREAM_END will be returned on success. 1.436 + * 1.437 + * The input and output sizes are updated to the actual amounts of data consumed 1.438 + * or written, not the amount available (as in a z_stream). The data pointers 1.439 + * are not changed, so the next input is (data+input_size) and the next 1.440 + * available output is (output+output_size). 1.441 + */ 1.442 +static int 1.443 +png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, 1.444 + /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, 1.445 + /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) 1.446 +{ 1.447 + if (png_ptr->zowner == owner) /* Else not claimed */ 1.448 + { 1.449 + int ret; 1.450 + png_alloc_size_t avail_out = *output_size_ptr; 1.451 + png_uint_32 avail_in = *input_size_ptr; 1.452 + 1.453 + /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it 1.454 + * can't even necessarily handle 65536 bytes) because the type uInt is 1.455 + * "16 bits or more". Consequently it is necessary to chunk the input to 1.456 + * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the 1.457 + * maximum value that can be stored in a uInt.) It is possible to set 1.458 + * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have 1.459 + * a performance advantage, because it reduces the amount of data accessed 1.460 + * at each step and that may give the OS more time to page it in. 1.461 + */ 1.462 + png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); 1.463 + /* avail_in and avail_out are set below from 'size' */ 1.464 + png_ptr->zstream.avail_in = 0; 1.465 + png_ptr->zstream.avail_out = 0; 1.466 + 1.467 + /* Read directly into the output if it is available (this is set to 1.468 + * a local buffer below if output is NULL). 1.469 + */ 1.470 + if (output != NULL) 1.471 + png_ptr->zstream.next_out = output; 1.472 + 1.473 + do 1.474 + { 1.475 + uInt avail; 1.476 + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; 1.477 + 1.478 + /* zlib INPUT BUFFER */ 1.479 + /* The setting of 'avail_in' used to be outside the loop; by setting it 1.480 + * inside it is possible to chunk the input to zlib and simply rely on 1.481 + * zlib to advance the 'next_in' pointer. This allows arbitrary 1.482 + * amounts of data to be passed through zlib at the unavoidable cost of 1.483 + * requiring a window save (memcpy of up to 32768 output bytes) 1.484 + * every ZLIB_IO_MAX input bytes. 1.485 + */ 1.486 + avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ 1.487 + 1.488 + avail = ZLIB_IO_MAX; 1.489 + 1.490 + if (avail_in < avail) 1.491 + avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ 1.492 + 1.493 + avail_in -= avail; 1.494 + png_ptr->zstream.avail_in = avail; 1.495 + 1.496 + /* zlib OUTPUT BUFFER */ 1.497 + avail_out += png_ptr->zstream.avail_out; /* not written last time */ 1.498 + 1.499 + avail = ZLIB_IO_MAX; /* maximum zlib can process */ 1.500 + 1.501 + if (output == NULL) 1.502 + { 1.503 + /* Reset the output buffer each time round if output is NULL and 1.504 + * make available the full buffer, up to 'remaining_space' 1.505 + */ 1.506 + png_ptr->zstream.next_out = local_buffer; 1.507 + if ((sizeof local_buffer) < avail) 1.508 + avail = (sizeof local_buffer); 1.509 + } 1.510 + 1.511 + if (avail_out < avail) 1.512 + avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ 1.513 + 1.514 + png_ptr->zstream.avail_out = avail; 1.515 + avail_out -= avail; 1.516 + 1.517 + /* zlib inflate call */ 1.518 + /* In fact 'avail_out' may be 0 at this point, that happens at the end 1.519 + * of the read when the final LZ end code was not passed at the end of 1.520 + * the previous chunk of input data. Tell zlib if we have reached the 1.521 + * end of the output buffer. 1.522 + */ 1.523 + ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : 1.524 + (finish ? Z_FINISH : Z_SYNC_FLUSH)); 1.525 + } while (ret == Z_OK); 1.526 + 1.527 + /* For safety kill the local buffer pointer now */ 1.528 + if (output == NULL) 1.529 + png_ptr->zstream.next_out = NULL; 1.530 + 1.531 + /* Claw back the 'size' and 'remaining_space' byte counts. */ 1.532 + avail_in += png_ptr->zstream.avail_in; 1.533 + avail_out += png_ptr->zstream.avail_out; 1.534 + 1.535 + /* Update the input and output sizes; the updated values are the amount 1.536 + * consumed or written, effectively the inverse of what zlib uses. 1.537 + */ 1.538 + if (avail_out > 0) 1.539 + *output_size_ptr -= avail_out; 1.540 + 1.541 + if (avail_in > 0) 1.542 + *input_size_ptr -= avail_in; 1.543 + 1.544 + /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ 1.545 + png_zstream_error(png_ptr, ret); 1.546 + return ret; 1.547 + } 1.548 + 1.549 + else 1.550 + { 1.551 + /* This is a bad internal error. The recovery assigns to the zstream msg 1.552 + * pointer, which is not owned by the caller, but this is safe; it's only 1.553 + * used on errors! 1.554 + */ 1.555 + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); 1.556 + return Z_STREAM_ERROR; 1.557 + } 1.558 +} 1.559 + 1.560 +/* 1.561 + * Decompress trailing data in a chunk. The assumption is that read_buffer 1.562 + * points at an allocated area holding the contents of a chunk with a 1.563 + * trailing compressed part. What we get back is an allocated area 1.564 + * holding the original prefix part and an uncompressed version of the 1.565 + * trailing part (the malloc area passed in is freed). 1.566 + */ 1.567 +static int 1.568 +png_decompress_chunk(png_structrp png_ptr, 1.569 + png_uint_32 chunklength, png_uint_32 prefix_size, 1.570 + png_alloc_size_t *newlength /* must be initialized to the maximum! */, 1.571 + int terminate /*add a '\0' to the end of the uncompressed data*/) 1.572 +{ 1.573 + /* TODO: implement different limits for different types of chunk. 1.574 + * 1.575 + * The caller supplies *newlength set to the maximum length of the 1.576 + * uncompressed data, but this routine allocates space for the prefix and 1.577 + * maybe a '\0' terminator too. We have to assume that 'prefix_size' is 1.578 + * limited only by the maximum chunk size. 1.579 + */ 1.580 + png_alloc_size_t limit = PNG_SIZE_MAX; 1.581 + 1.582 +# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED 1.583 + if (png_ptr->user_chunk_malloc_max > 0 && 1.584 + png_ptr->user_chunk_malloc_max < limit) 1.585 + limit = png_ptr->user_chunk_malloc_max; 1.586 +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 1.587 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) 1.588 + limit = PNG_USER_CHUNK_MALLOC_MAX; 1.589 +# endif 1.590 + 1.591 + if (limit >= prefix_size + (terminate != 0)) 1.592 + { 1.593 + int ret; 1.594 + 1.595 + limit -= prefix_size + (terminate != 0); 1.596 + 1.597 + if (limit < *newlength) 1.598 + *newlength = limit; 1.599 + 1.600 + /* Now try to claim the stream. */ 1.601 + ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); 1.602 + 1.603 + if (ret == Z_OK) 1.604 + { 1.605 + png_uint_32 lzsize = chunklength - prefix_size; 1.606 + 1.607 + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, 1.608 + /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, 1.609 + /* output: */ NULL, newlength); 1.610 + 1.611 + if (ret == Z_STREAM_END) 1.612 + { 1.613 + /* Use 'inflateReset' here, not 'inflateReset2' because this 1.614 + * preserves the previously decided window size (otherwise it would 1.615 + * be necessary to store the previous window size.) In practice 1.616 + * this doesn't matter anyway, because png_inflate will call inflate 1.617 + * with Z_FINISH in almost all cases, so the window will not be 1.618 + * maintained. 1.619 + */ 1.620 + if (inflateReset(&png_ptr->zstream) == Z_OK) 1.621 + { 1.622 + /* Because of the limit checks above we know that the new, 1.623 + * expanded, size will fit in a size_t (let alone an 1.624 + * png_alloc_size_t). Use png_malloc_base here to avoid an 1.625 + * extra OOM message. 1.626 + */ 1.627 + png_alloc_size_t new_size = *newlength; 1.628 + png_alloc_size_t buffer_size = prefix_size + new_size + 1.629 + (terminate != 0); 1.630 + png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, 1.631 + buffer_size)); 1.632 + 1.633 + if (text != NULL) 1.634 + { 1.635 + ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, 1.636 + png_ptr->read_buffer + prefix_size, &lzsize, 1.637 + text + prefix_size, newlength); 1.638 + 1.639 + if (ret == Z_STREAM_END) 1.640 + { 1.641 + if (new_size == *newlength) 1.642 + { 1.643 + if (terminate) 1.644 + text[prefix_size + *newlength] = 0; 1.645 + 1.646 + if (prefix_size > 0) 1.647 + memcpy(text, png_ptr->read_buffer, prefix_size); 1.648 + 1.649 + { 1.650 + png_bytep old_ptr = png_ptr->read_buffer; 1.651 + 1.652 + png_ptr->read_buffer = text; 1.653 + png_ptr->read_buffer_size = buffer_size; 1.654 + text = old_ptr; /* freed below */ 1.655 + } 1.656 + } 1.657 + 1.658 + else 1.659 + { 1.660 + /* The size changed on the second read, there can be no 1.661 + * guarantee that anything is correct at this point. 1.662 + * The 'msg' pointer has been set to "unexpected end of 1.663 + * LZ stream", which is fine, but return an error code 1.664 + * that the caller won't accept. 1.665 + */ 1.666 + ret = PNG_UNEXPECTED_ZLIB_RETURN; 1.667 + } 1.668 + } 1.669 + 1.670 + else if (ret == Z_OK) 1.671 + ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ 1.672 + 1.673 + /* Free the text pointer (this is the old read_buffer on 1.674 + * success) 1.675 + */ 1.676 + png_free(png_ptr, text); 1.677 + 1.678 + /* This really is very benign, but it's still an error because 1.679 + * the extra space may otherwise be used as a Trojan Horse. 1.680 + */ 1.681 + if (ret == Z_STREAM_END && 1.682 + chunklength - prefix_size != lzsize) 1.683 + png_chunk_benign_error(png_ptr, "extra compressed data"); 1.684 + } 1.685 + 1.686 + else 1.687 + { 1.688 + /* Out of memory allocating the buffer */ 1.689 + ret = Z_MEM_ERROR; 1.690 + png_zstream_error(png_ptr, Z_MEM_ERROR); 1.691 + } 1.692 + } 1.693 + 1.694 + else 1.695 + { 1.696 + /* inflateReset failed, store the error message */ 1.697 + png_zstream_error(png_ptr, ret); 1.698 + 1.699 + if (ret == Z_STREAM_END) 1.700 + ret = PNG_UNEXPECTED_ZLIB_RETURN; 1.701 + } 1.702 + } 1.703 + 1.704 + else if (ret == Z_OK) 1.705 + ret = PNG_UNEXPECTED_ZLIB_RETURN; 1.706 + 1.707 + /* Release the claimed stream */ 1.708 + png_ptr->zowner = 0; 1.709 + } 1.710 + 1.711 + else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ 1.712 + ret = PNG_UNEXPECTED_ZLIB_RETURN; 1.713 + 1.714 + return ret; 1.715 + } 1.716 + 1.717 + else 1.718 + { 1.719 + /* Application/configuration limits exceeded */ 1.720 + png_zstream_error(png_ptr, Z_MEM_ERROR); 1.721 + return Z_MEM_ERROR; 1.722 + } 1.723 +} 1.724 +#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ 1.725 + 1.726 +#ifdef PNG_READ_iCCP_SUPPORTED 1.727 +/* Perform a partial read and decompress, producing 'avail_out' bytes and 1.728 + * reading from the current chunk as required. 1.729 + */ 1.730 +static int 1.731 +png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, 1.732 + png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, 1.733 + int finish) 1.734 +{ 1.735 + if (png_ptr->zowner == png_ptr->chunk_name) 1.736 + { 1.737 + int ret; 1.738 + 1.739 + /* next_in and avail_in must have been initialized by the caller. */ 1.740 + png_ptr->zstream.next_out = next_out; 1.741 + png_ptr->zstream.avail_out = 0; /* set in the loop */ 1.742 + 1.743 + do 1.744 + { 1.745 + if (png_ptr->zstream.avail_in == 0) 1.746 + { 1.747 + if (read_size > *chunk_bytes) 1.748 + read_size = (uInt)*chunk_bytes; 1.749 + *chunk_bytes -= read_size; 1.750 + 1.751 + if (read_size > 0) 1.752 + png_crc_read(png_ptr, read_buffer, read_size); 1.753 + 1.754 + png_ptr->zstream.next_in = read_buffer; 1.755 + png_ptr->zstream.avail_in = read_size; 1.756 + } 1.757 + 1.758 + if (png_ptr->zstream.avail_out == 0) 1.759 + { 1.760 + uInt avail = ZLIB_IO_MAX; 1.761 + if (avail > *out_size) 1.762 + avail = (uInt)*out_size; 1.763 + *out_size -= avail; 1.764 + 1.765 + png_ptr->zstream.avail_out = avail; 1.766 + } 1.767 + 1.768 + /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all 1.769 + * the available output is produced; this allows reading of truncated 1.770 + * streams. 1.771 + */ 1.772 + ret = inflate(&png_ptr->zstream, 1.773 + *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); 1.774 + } 1.775 + while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); 1.776 + 1.777 + *out_size += png_ptr->zstream.avail_out; 1.778 + png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ 1.779 + 1.780 + /* Ensure the error message pointer is always set: */ 1.781 + png_zstream_error(png_ptr, ret); 1.782 + return ret; 1.783 + } 1.784 + 1.785 + else 1.786 + { 1.787 + png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); 1.788 + return Z_STREAM_ERROR; 1.789 + } 1.790 +} 1.791 +#endif 1.792 + 1.793 +/* Read and check the IDHR chunk */ 1.794 +void /* PRIVATE */ 1.795 +png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.796 +{ 1.797 + png_byte buf[13]; 1.798 + png_uint_32 width, height; 1.799 + int bit_depth, color_type, compression_type, filter_type; 1.800 + int interlace_type; 1.801 + 1.802 + png_debug(1, "in png_handle_IHDR"); 1.803 + 1.804 + if (png_ptr->mode & PNG_HAVE_IHDR) 1.805 + png_chunk_error(png_ptr, "out of place"); 1.806 + 1.807 + /* Check the length */ 1.808 + if (length != 13) 1.809 + png_chunk_error(png_ptr, "invalid"); 1.810 + 1.811 + png_ptr->mode |= PNG_HAVE_IHDR; 1.812 + 1.813 + png_crc_read(png_ptr, buf, 13); 1.814 + png_crc_finish(png_ptr, 0); 1.815 + 1.816 + width = png_get_uint_31(png_ptr, buf); 1.817 + height = png_get_uint_31(png_ptr, buf + 4); 1.818 + bit_depth = buf[8]; 1.819 + color_type = buf[9]; 1.820 + compression_type = buf[10]; 1.821 + filter_type = buf[11]; 1.822 + interlace_type = buf[12]; 1.823 + 1.824 +#ifdef PNG_READ_APNG_SUPPORTED 1.825 + png_ptr->first_frame_width = width; 1.826 + png_ptr->first_frame_height = height; 1.827 +#endif 1.828 + 1.829 + /* Set internal variables */ 1.830 + png_ptr->width = width; 1.831 + png_ptr->height = height; 1.832 + png_ptr->bit_depth = (png_byte)bit_depth; 1.833 + png_ptr->interlaced = (png_byte)interlace_type; 1.834 + png_ptr->color_type = (png_byte)color_type; 1.835 +#ifdef PNG_MNG_FEATURES_SUPPORTED 1.836 + png_ptr->filter_type = (png_byte)filter_type; 1.837 +#endif 1.838 + png_ptr->compression_type = (png_byte)compression_type; 1.839 + 1.840 + /* Find number of channels */ 1.841 + switch (png_ptr->color_type) 1.842 + { 1.843 + default: /* invalid, png_set_IHDR calls png_error */ 1.844 + case PNG_COLOR_TYPE_GRAY: 1.845 + case PNG_COLOR_TYPE_PALETTE: 1.846 + png_ptr->channels = 1; 1.847 + break; 1.848 + 1.849 + case PNG_COLOR_TYPE_RGB: 1.850 + png_ptr->channels = 3; 1.851 + break; 1.852 + 1.853 + case PNG_COLOR_TYPE_GRAY_ALPHA: 1.854 + png_ptr->channels = 2; 1.855 + break; 1.856 + 1.857 + case PNG_COLOR_TYPE_RGB_ALPHA: 1.858 + png_ptr->channels = 4; 1.859 + break; 1.860 + } 1.861 + 1.862 + /* Set up other useful info */ 1.863 + png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 1.864 + png_ptr->channels); 1.865 + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); 1.866 + png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); 1.867 + png_debug1(3, "channels = %d", png_ptr->channels); 1.868 + png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); 1.869 + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 1.870 + color_type, interlace_type, compression_type, filter_type); 1.871 +} 1.872 + 1.873 +/* Read and check the palette */ 1.874 +void /* PRIVATE */ 1.875 +png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.876 +{ 1.877 + png_color palette[PNG_MAX_PALETTE_LENGTH]; 1.878 + int num, i; 1.879 +#ifdef PNG_POINTER_INDEXING_SUPPORTED 1.880 + png_colorp pal_ptr; 1.881 +#endif 1.882 + 1.883 + png_debug(1, "in png_handle_PLTE"); 1.884 + 1.885 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.886 + png_chunk_error(png_ptr, "missing IHDR"); 1.887 + 1.888 + /* Moved to before the 'after IDAT' check below because otherwise duplicate 1.889 + * PLTE chunks are potentially ignored (the spec says there shall not be more 1.890 + * than one PLTE, the error is not treated as benign, so this check trumps 1.891 + * the requirement that PLTE appears before IDAT.) 1.892 + */ 1.893 + else if (png_ptr->mode & PNG_HAVE_PLTE) 1.894 + png_chunk_error(png_ptr, "duplicate"); 1.895 + 1.896 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.897 + { 1.898 + /* This is benign because the non-benign error happened before, when an 1.899 + * IDAT was encountered in a color-mapped image with no PLTE. 1.900 + */ 1.901 + png_crc_finish(png_ptr, length); 1.902 + png_chunk_benign_error(png_ptr, "out of place"); 1.903 + return; 1.904 + } 1.905 + 1.906 + png_ptr->mode |= PNG_HAVE_PLTE; 1.907 + 1.908 + if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) 1.909 + { 1.910 + png_crc_finish(png_ptr, length); 1.911 + png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); 1.912 + return; 1.913 + } 1.914 + 1.915 +#ifndef PNG_READ_OPT_PLTE_SUPPORTED 1.916 + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 1.917 + { 1.918 + png_crc_finish(png_ptr, length); 1.919 + return; 1.920 + } 1.921 +#endif 1.922 + 1.923 + if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) 1.924 + { 1.925 + png_crc_finish(png_ptr, length); 1.926 + 1.927 + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 1.928 + png_chunk_benign_error(png_ptr, "invalid"); 1.929 + 1.930 + else 1.931 + png_chunk_error(png_ptr, "invalid"); 1.932 + 1.933 + return; 1.934 + } 1.935 + 1.936 + /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ 1.937 + num = (int)length / 3; 1.938 + 1.939 +#ifdef PNG_POINTER_INDEXING_SUPPORTED 1.940 + for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) 1.941 + { 1.942 + png_byte buf[3]; 1.943 + 1.944 + png_crc_read(png_ptr, buf, 3); 1.945 + pal_ptr->red = buf[0]; 1.946 + pal_ptr->green = buf[1]; 1.947 + pal_ptr->blue = buf[2]; 1.948 + } 1.949 +#else 1.950 + for (i = 0; i < num; i++) 1.951 + { 1.952 + png_byte buf[3]; 1.953 + 1.954 + png_crc_read(png_ptr, buf, 3); 1.955 + /* Don't depend upon png_color being any order */ 1.956 + palette[i].red = buf[0]; 1.957 + palette[i].green = buf[1]; 1.958 + palette[i].blue = buf[2]; 1.959 + } 1.960 +#endif 1.961 + 1.962 + /* If we actually need the PLTE chunk (ie for a paletted image), we do 1.963 + * whatever the normal CRC configuration tells us. However, if we 1.964 + * have an RGB image, the PLTE can be considered ancillary, so 1.965 + * we will act as though it is. 1.966 + */ 1.967 +#ifndef PNG_READ_OPT_PLTE_SUPPORTED 1.968 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.969 +#endif 1.970 + { 1.971 + png_crc_finish(png_ptr, 0); 1.972 + } 1.973 + 1.974 +#ifndef PNG_READ_OPT_PLTE_SUPPORTED 1.975 + else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ 1.976 + { 1.977 + /* If we don't want to use the data from an ancillary chunk, 1.978 + * we have two options: an error abort, or a warning and we 1.979 + * ignore the data in this chunk (which should be OK, since 1.980 + * it's considered ancillary for a RGB or RGBA image). 1.981 + * 1.982 + * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the 1.983 + * chunk type to determine whether to check the ancillary or the critical 1.984 + * flags. 1.985 + */ 1.986 + if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) 1.987 + { 1.988 + if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) 1.989 + return; 1.990 + 1.991 + else 1.992 + png_chunk_error(png_ptr, "CRC error"); 1.993 + } 1.994 + 1.995 + /* Otherwise, we (optionally) emit a warning and use the chunk. */ 1.996 + else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) 1.997 + png_chunk_warning(png_ptr, "CRC error"); 1.998 + } 1.999 +#endif 1.1000 + 1.1001 + /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its 1.1002 + * own copy of the palette. This has the side effect that when png_start_row 1.1003 + * is called (this happens after any call to png_read_update_info) the 1.1004 + * info_ptr palette gets changed. This is extremely unexpected and 1.1005 + * confusing. 1.1006 + * 1.1007 + * Fix this by not sharing the palette in this way. 1.1008 + */ 1.1009 + png_set_PLTE(png_ptr, info_ptr, palette, num); 1.1010 + 1.1011 + /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before 1.1012 + * IDAT. Prior to 1.6.0 this was not checked; instead the code merely 1.1013 + * checked the apparent validity of a tRNS chunk inserted before PLTE on a 1.1014 + * palette PNG. 1.6.0 attempts to rigorously follow the standard and 1.1015 + * therefore does a benign error if the erroneous condition is detected *and* 1.1016 + * cancels the tRNS if the benign error returns. The alternative is to 1.1017 + * amend the standard since it would be rather hypocritical of the standards 1.1018 + * maintainers to ignore it. 1.1019 + */ 1.1020 +#ifdef PNG_READ_tRNS_SUPPORTED 1.1021 + if (png_ptr->num_trans > 0 || 1.1022 + (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) 1.1023 + { 1.1024 + /* Cancel this because otherwise it would be used if the transforms 1.1025 + * require it. Don't cancel the 'valid' flag because this would prevent 1.1026 + * detection of duplicate chunks. 1.1027 + */ 1.1028 + png_ptr->num_trans = 0; 1.1029 + 1.1030 + if (info_ptr != NULL) 1.1031 + info_ptr->num_trans = 0; 1.1032 + 1.1033 + png_chunk_benign_error(png_ptr, "tRNS must be after"); 1.1034 + } 1.1035 +#endif 1.1036 + 1.1037 +#ifdef PNG_READ_hIST_SUPPORTED 1.1038 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) 1.1039 + png_chunk_benign_error(png_ptr, "hIST must be after"); 1.1040 +#endif 1.1041 + 1.1042 +#ifdef PNG_READ_bKGD_SUPPORTED 1.1043 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) 1.1044 + png_chunk_benign_error(png_ptr, "bKGD must be after"); 1.1045 +#endif 1.1046 +} 1.1047 + 1.1048 +void /* PRIVATE */ 1.1049 +png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1050 +{ 1.1051 + png_debug(1, "in png_handle_IEND"); 1.1052 + 1.1053 + if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) 1.1054 + png_chunk_error(png_ptr, "out of place"); 1.1055 + 1.1056 + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); 1.1057 + 1.1058 + png_crc_finish(png_ptr, length); 1.1059 + 1.1060 + if (length != 0) 1.1061 + png_chunk_benign_error(png_ptr, "invalid"); 1.1062 + 1.1063 + PNG_UNUSED(info_ptr) 1.1064 +} 1.1065 + 1.1066 +#ifdef PNG_READ_gAMA_SUPPORTED 1.1067 +void /* PRIVATE */ 1.1068 +png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1069 +{ 1.1070 + png_fixed_point igamma; 1.1071 + png_byte buf[4]; 1.1072 + 1.1073 + png_debug(1, "in png_handle_gAMA"); 1.1074 + 1.1075 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1076 + png_chunk_error(png_ptr, "missing IHDR"); 1.1077 + 1.1078 + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) 1.1079 + { 1.1080 + png_crc_finish(png_ptr, length); 1.1081 + png_chunk_benign_error(png_ptr, "out of place"); 1.1082 + return; 1.1083 + } 1.1084 + 1.1085 + if (length != 4) 1.1086 + { 1.1087 + png_crc_finish(png_ptr, length); 1.1088 + png_chunk_benign_error(png_ptr, "invalid"); 1.1089 + return; 1.1090 + } 1.1091 + 1.1092 + png_crc_read(png_ptr, buf, 4); 1.1093 + 1.1094 + if (png_crc_finish(png_ptr, 0)) 1.1095 + return; 1.1096 + 1.1097 + igamma = png_get_fixed_point(NULL, buf); 1.1098 + 1.1099 + png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); 1.1100 + png_colorspace_sync(png_ptr, info_ptr); 1.1101 +} 1.1102 +#endif 1.1103 + 1.1104 +#ifdef PNG_READ_sBIT_SUPPORTED 1.1105 +void /* PRIVATE */ 1.1106 +png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1107 +{ 1.1108 + unsigned int truelen, i; 1.1109 + png_byte sample_depth; 1.1110 + png_byte buf[4]; 1.1111 + 1.1112 + png_debug(1, "in png_handle_sBIT"); 1.1113 + 1.1114 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1115 + png_chunk_error(png_ptr, "missing IHDR"); 1.1116 + 1.1117 + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) 1.1118 + { 1.1119 + png_crc_finish(png_ptr, length); 1.1120 + png_chunk_benign_error(png_ptr, "out of place"); 1.1121 + return; 1.1122 + } 1.1123 + 1.1124 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) 1.1125 + { 1.1126 + png_crc_finish(png_ptr, length); 1.1127 + png_chunk_benign_error(png_ptr, "duplicate"); 1.1128 + return; 1.1129 + } 1.1130 + 1.1131 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.1132 + { 1.1133 + truelen = 3; 1.1134 + sample_depth = 8; 1.1135 + } 1.1136 + 1.1137 + else 1.1138 + { 1.1139 + truelen = png_ptr->channels; 1.1140 + sample_depth = png_ptr->bit_depth; 1.1141 + } 1.1142 + 1.1143 + if (length != truelen || length > 4) 1.1144 + { 1.1145 + png_chunk_benign_error(png_ptr, "invalid"); 1.1146 + png_crc_finish(png_ptr, length); 1.1147 + return; 1.1148 + } 1.1149 + 1.1150 + buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; 1.1151 + png_crc_read(png_ptr, buf, truelen); 1.1152 + 1.1153 + if (png_crc_finish(png_ptr, 0)) 1.1154 + return; 1.1155 + 1.1156 + for (i=0; i<truelen; ++i) 1.1157 + if (buf[i] == 0 || buf[i] > sample_depth) 1.1158 + { 1.1159 + png_chunk_benign_error(png_ptr, "invalid"); 1.1160 + return; 1.1161 + } 1.1162 + 1.1163 + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1.1164 + { 1.1165 + png_ptr->sig_bit.red = buf[0]; 1.1166 + png_ptr->sig_bit.green = buf[1]; 1.1167 + png_ptr->sig_bit.blue = buf[2]; 1.1168 + png_ptr->sig_bit.alpha = buf[3]; 1.1169 + } 1.1170 + 1.1171 + else 1.1172 + { 1.1173 + png_ptr->sig_bit.gray = buf[0]; 1.1174 + png_ptr->sig_bit.red = buf[0]; 1.1175 + png_ptr->sig_bit.green = buf[0]; 1.1176 + png_ptr->sig_bit.blue = buf[0]; 1.1177 + png_ptr->sig_bit.alpha = buf[1]; 1.1178 + } 1.1179 + 1.1180 + png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); 1.1181 +} 1.1182 +#endif 1.1183 + 1.1184 +#ifdef PNG_READ_cHRM_SUPPORTED 1.1185 +void /* PRIVATE */ 1.1186 +png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1187 +{ 1.1188 + png_byte buf[32]; 1.1189 + png_xy xy; 1.1190 + 1.1191 + png_debug(1, "in png_handle_cHRM"); 1.1192 + 1.1193 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1194 + png_chunk_error(png_ptr, "missing IHDR"); 1.1195 + 1.1196 + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) 1.1197 + { 1.1198 + png_crc_finish(png_ptr, length); 1.1199 + png_chunk_benign_error(png_ptr, "out of place"); 1.1200 + return; 1.1201 + } 1.1202 + 1.1203 + if (length != 32) 1.1204 + { 1.1205 + png_crc_finish(png_ptr, length); 1.1206 + png_chunk_benign_error(png_ptr, "invalid"); 1.1207 + return; 1.1208 + } 1.1209 + 1.1210 + png_crc_read(png_ptr, buf, 32); 1.1211 + 1.1212 + if (png_crc_finish(png_ptr, 0)) 1.1213 + return; 1.1214 + 1.1215 + xy.whitex = png_get_fixed_point(NULL, buf); 1.1216 + xy.whitey = png_get_fixed_point(NULL, buf + 4); 1.1217 + xy.redx = png_get_fixed_point(NULL, buf + 8); 1.1218 + xy.redy = png_get_fixed_point(NULL, buf + 12); 1.1219 + xy.greenx = png_get_fixed_point(NULL, buf + 16); 1.1220 + xy.greeny = png_get_fixed_point(NULL, buf + 20); 1.1221 + xy.bluex = png_get_fixed_point(NULL, buf + 24); 1.1222 + xy.bluey = png_get_fixed_point(NULL, buf + 28); 1.1223 + 1.1224 + if (xy.whitex == PNG_FIXED_ERROR || 1.1225 + xy.whitey == PNG_FIXED_ERROR || 1.1226 + xy.redx == PNG_FIXED_ERROR || 1.1227 + xy.redy == PNG_FIXED_ERROR || 1.1228 + xy.greenx == PNG_FIXED_ERROR || 1.1229 + xy.greeny == PNG_FIXED_ERROR || 1.1230 + xy.bluex == PNG_FIXED_ERROR || 1.1231 + xy.bluey == PNG_FIXED_ERROR) 1.1232 + { 1.1233 + png_chunk_benign_error(png_ptr, "invalid values"); 1.1234 + return; 1.1235 + } 1.1236 + 1.1237 + /* If a colorspace error has already been output skip this chunk */ 1.1238 + if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) 1.1239 + return; 1.1240 + 1.1241 + if (png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) 1.1242 + { 1.1243 + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; 1.1244 + png_colorspace_sync(png_ptr, info_ptr); 1.1245 + png_chunk_benign_error(png_ptr, "duplicate"); 1.1246 + return; 1.1247 + } 1.1248 + 1.1249 + png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; 1.1250 + (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, 1.1251 + 1/*prefer cHRM values*/); 1.1252 + png_colorspace_sync(png_ptr, info_ptr); 1.1253 +} 1.1254 +#endif 1.1255 + 1.1256 +#ifdef PNG_READ_sRGB_SUPPORTED 1.1257 +void /* PRIVATE */ 1.1258 +png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1259 +{ 1.1260 + png_byte intent; 1.1261 + 1.1262 + png_debug(1, "in png_handle_sRGB"); 1.1263 + 1.1264 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1265 + png_chunk_error(png_ptr, "missing IHDR"); 1.1266 + 1.1267 + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) 1.1268 + { 1.1269 + png_crc_finish(png_ptr, length); 1.1270 + png_chunk_benign_error(png_ptr, "out of place"); 1.1271 + return; 1.1272 + } 1.1273 + 1.1274 + if (length != 1) 1.1275 + { 1.1276 + png_crc_finish(png_ptr, length); 1.1277 + png_chunk_benign_error(png_ptr, "invalid"); 1.1278 + return; 1.1279 + } 1.1280 + 1.1281 + png_crc_read(png_ptr, &intent, 1); 1.1282 + 1.1283 + if (png_crc_finish(png_ptr, 0)) 1.1284 + return; 1.1285 + 1.1286 + /* If a colorspace error has already been output skip this chunk */ 1.1287 + if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) 1.1288 + return; 1.1289 + 1.1290 + /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect 1.1291 + * this. 1.1292 + */ 1.1293 + if (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) 1.1294 + { 1.1295 + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; 1.1296 + png_colorspace_sync(png_ptr, info_ptr); 1.1297 + png_chunk_benign_error(png_ptr, "too many profiles"); 1.1298 + return; 1.1299 + } 1.1300 + 1.1301 + (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); 1.1302 + png_colorspace_sync(png_ptr, info_ptr); 1.1303 +} 1.1304 +#endif /* PNG_READ_sRGB_SUPPORTED */ 1.1305 + 1.1306 +#ifdef PNG_READ_iCCP_SUPPORTED 1.1307 +void /* PRIVATE */ 1.1308 +png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1309 +/* Note: this does not properly handle profiles that are > 64K under DOS */ 1.1310 +{ 1.1311 + png_const_charp errmsg = NULL; /* error message output, or no error */ 1.1312 + int finished = 0; /* crc checked */ 1.1313 + 1.1314 + png_debug(1, "in png_handle_iCCP"); 1.1315 + 1.1316 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1317 + png_chunk_error(png_ptr, "missing IHDR"); 1.1318 + 1.1319 + else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) 1.1320 + { 1.1321 + png_crc_finish(png_ptr, length); 1.1322 + png_chunk_benign_error(png_ptr, "out of place"); 1.1323 + return; 1.1324 + } 1.1325 + 1.1326 + /* Consistent with all the above colorspace handling an obviously *invalid* 1.1327 + * chunk is just ignored, so does not invalidate the color space. An 1.1328 + * alternative is to set the 'invalid' flags at the start of this routine 1.1329 + * and only clear them in they were not set before and all the tests pass. 1.1330 + * The minimum 'deflate' stream is assumed to be just the 2 byte header and 4 1.1331 + * byte checksum. The keyword must be one character and there is a 1.1332 + * terminator (0) byte and the compression method. 1.1333 + */ 1.1334 + if (length < 9) 1.1335 + { 1.1336 + png_crc_finish(png_ptr, length); 1.1337 + png_chunk_benign_error(png_ptr, "too short"); 1.1338 + return; 1.1339 + } 1.1340 + 1.1341 + /* If a colorspace error has already been output skip this chunk */ 1.1342 + if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) 1.1343 + { 1.1344 + png_crc_finish(png_ptr, length); 1.1345 + return; 1.1346 + } 1.1347 + 1.1348 + /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect 1.1349 + * this. 1.1350 + */ 1.1351 + if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) 1.1352 + { 1.1353 + uInt read_length, keyword_length; 1.1354 + char keyword[81]; 1.1355 + 1.1356 + /* Find the keyword; the keyword plus separator and compression method 1.1357 + * bytes can be at most 81 characters long. 1.1358 + */ 1.1359 + read_length = 81; /* maximum */ 1.1360 + if (read_length > length) 1.1361 + read_length = (uInt)length; 1.1362 + 1.1363 + png_crc_read(png_ptr, (png_bytep)keyword, read_length); 1.1364 + length -= read_length; 1.1365 + 1.1366 + keyword_length = 0; 1.1367 + while (keyword_length < 80 && keyword_length < read_length && 1.1368 + keyword[keyword_length] != 0) 1.1369 + ++keyword_length; 1.1370 + 1.1371 + /* TODO: make the keyword checking common */ 1.1372 + if (keyword_length >= 1 && keyword_length <= 79) 1.1373 + { 1.1374 + /* We only understand '0' compression - deflate - so if we get a 1.1375 + * different value we can't safely decode the chunk. 1.1376 + */ 1.1377 + if (keyword_length+1 < read_length && 1.1378 + keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) 1.1379 + { 1.1380 + read_length -= keyword_length+2; 1.1381 + 1.1382 + if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) 1.1383 + { 1.1384 + Byte profile_header[132]; 1.1385 + Byte local_buffer[PNG_INFLATE_BUF_SIZE]; 1.1386 + png_alloc_size_t size = (sizeof profile_header); 1.1387 + 1.1388 + png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); 1.1389 + png_ptr->zstream.avail_in = read_length; 1.1390 + (void)png_inflate_read(png_ptr, local_buffer, 1.1391 + (sizeof local_buffer), &length, profile_header, &size, 1.1392 + 0/*finish: don't, because the output is too small*/); 1.1393 + 1.1394 + if (size == 0) 1.1395 + { 1.1396 + /* We have the ICC profile header; do the basic header checks. 1.1397 + */ 1.1398 + const png_uint_32 profile_length = 1.1399 + png_get_uint_32(profile_header); 1.1400 + 1.1401 + if (png_icc_check_length(png_ptr, &png_ptr->colorspace, 1.1402 + keyword, profile_length)) 1.1403 + { 1.1404 + /* The length is apparently ok, so we can check the 132 1.1405 + * byte header. 1.1406 + */ 1.1407 + if (png_icc_check_header(png_ptr, &png_ptr->colorspace, 1.1408 + keyword, profile_length, profile_header, 1.1409 + png_ptr->color_type)) 1.1410 + { 1.1411 + /* Now read the tag table; a variable size buffer is 1.1412 + * needed at this point, allocate one for the whole 1.1413 + * profile. The header check has already validated 1.1414 + * that none of these stuff will overflow. 1.1415 + */ 1.1416 + const png_uint_32 tag_count = png_get_uint_32( 1.1417 + profile_header+128); 1.1418 + png_bytep profile = png_read_buffer(png_ptr, 1.1419 + profile_length, 2/*silent*/); 1.1420 + 1.1421 + if (profile != NULL) 1.1422 + { 1.1423 + memcpy(profile, profile_header, 1.1424 + (sizeof profile_header)); 1.1425 + 1.1426 + size = 12 * tag_count; 1.1427 + 1.1428 + (void)png_inflate_read(png_ptr, local_buffer, 1.1429 + (sizeof local_buffer), &length, 1.1430 + profile + (sizeof profile_header), &size, 0); 1.1431 + 1.1432 + /* Still expect a buffer error because we expect 1.1433 + * there to be some tag data! 1.1434 + */ 1.1435 + if (size == 0) 1.1436 + { 1.1437 + if (png_icc_check_tag_table(png_ptr, 1.1438 + &png_ptr->colorspace, keyword, profile_length, 1.1439 + profile)) 1.1440 + { 1.1441 + /* The profile has been validated for basic 1.1442 + * security issues, so read the whole thing in. 1.1443 + */ 1.1444 + size = profile_length - (sizeof profile_header) 1.1445 + - 12 * tag_count; 1.1446 + 1.1447 + (void)png_inflate_read(png_ptr, local_buffer, 1.1448 + (sizeof local_buffer), &length, 1.1449 + profile + (sizeof profile_header) + 1.1450 + 12 * tag_count, &size, 1/*finish*/); 1.1451 + 1.1452 + if (length > 0 && !(png_ptr->flags & 1.1453 + PNG_FLAG_BENIGN_ERRORS_WARN)) 1.1454 + errmsg = "extra compressed data"; 1.1455 + 1.1456 + /* But otherwise allow extra data: */ 1.1457 + else if (size == 0) 1.1458 + { 1.1459 + if (length > 0) 1.1460 + { 1.1461 + /* This can be handled completely, so 1.1462 + * keep going. 1.1463 + */ 1.1464 + png_chunk_warning(png_ptr, 1.1465 + "extra compressed data"); 1.1466 + } 1.1467 + 1.1468 + png_crc_finish(png_ptr, length); 1.1469 + finished = 1; 1.1470 + 1.1471 +# ifdef PNG_sRGB_SUPPORTED 1.1472 + /* Check for a match against sRGB */ 1.1473 + png_icc_set_sRGB(png_ptr, 1.1474 + &png_ptr->colorspace, profile, 1.1475 + png_ptr->zstream.adler); 1.1476 +# endif 1.1477 + 1.1478 + /* Steal the profile for info_ptr. */ 1.1479 + if (info_ptr != NULL) 1.1480 + { 1.1481 + png_free_data(png_ptr, info_ptr, 1.1482 + PNG_FREE_ICCP, 0); 1.1483 + 1.1484 + info_ptr->iccp_name = png_voidcast(char*, 1.1485 + png_malloc_base(png_ptr, 1.1486 + keyword_length+1)); 1.1487 + if (info_ptr->iccp_name != NULL) 1.1488 + { 1.1489 + memcpy(info_ptr->iccp_name, keyword, 1.1490 + keyword_length+1); 1.1491 + info_ptr->iccp_proflen = 1.1492 + profile_length; 1.1493 + info_ptr->iccp_profile = profile; 1.1494 + png_ptr->read_buffer = NULL; /*steal*/ 1.1495 + info_ptr->free_me |= PNG_FREE_ICCP; 1.1496 + info_ptr->valid |= PNG_INFO_iCCP; 1.1497 + } 1.1498 + 1.1499 + else 1.1500 + { 1.1501 + png_ptr->colorspace.flags |= 1.1502 + PNG_COLORSPACE_INVALID; 1.1503 + errmsg = "out of memory"; 1.1504 + } 1.1505 + } 1.1506 + 1.1507 + /* else the profile remains in the read 1.1508 + * buffer which gets reused for subsequent 1.1509 + * chunks. 1.1510 + */ 1.1511 + 1.1512 + if (info_ptr != NULL) 1.1513 + png_colorspace_sync(png_ptr, info_ptr); 1.1514 + 1.1515 + if (errmsg == NULL) 1.1516 + { 1.1517 + png_ptr->zowner = 0; 1.1518 + return; 1.1519 + } 1.1520 + } 1.1521 + 1.1522 + else if (size > 0) 1.1523 + errmsg = "truncated"; 1.1524 + 1.1525 + else 1.1526 + errmsg = png_ptr->zstream.msg; 1.1527 + } 1.1528 + 1.1529 + /* else png_icc_check_tag_table output an error */ 1.1530 + } 1.1531 + 1.1532 + else /* profile truncated */ 1.1533 + errmsg = png_ptr->zstream.msg; 1.1534 + } 1.1535 + 1.1536 + else 1.1537 + errmsg = "out of memory"; 1.1538 + } 1.1539 + 1.1540 + /* else png_icc_check_header output an error */ 1.1541 + } 1.1542 + 1.1543 + /* else png_icc_check_length output an error */ 1.1544 + } 1.1545 + 1.1546 + else /* profile truncated */ 1.1547 + errmsg = png_ptr->zstream.msg; 1.1548 + 1.1549 + /* Release the stream */ 1.1550 + png_ptr->zowner = 0; 1.1551 + } 1.1552 + 1.1553 + else /* png_inflate_claim failed */ 1.1554 + errmsg = png_ptr->zstream.msg; 1.1555 + } 1.1556 + 1.1557 + else 1.1558 + errmsg = "bad compression method"; /* or missing */ 1.1559 + } 1.1560 + 1.1561 + else 1.1562 + errmsg = "bad keyword"; 1.1563 + } 1.1564 + 1.1565 + else 1.1566 + errmsg = "too many profiles"; 1.1567 + 1.1568 + /* Failure: the reason is in 'errmsg' */ 1.1569 + if (!finished) 1.1570 + png_crc_finish(png_ptr, length); 1.1571 + 1.1572 + png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; 1.1573 + png_colorspace_sync(png_ptr, info_ptr); 1.1574 + if (errmsg != NULL) /* else already output */ 1.1575 + png_chunk_benign_error(png_ptr, errmsg); 1.1576 +} 1.1577 +#endif /* PNG_READ_iCCP_SUPPORTED */ 1.1578 + 1.1579 +#ifdef PNG_READ_sPLT_SUPPORTED 1.1580 +void /* PRIVATE */ 1.1581 +png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1582 +/* Note: this does not properly handle chunks that are > 64K under DOS */ 1.1583 +{ 1.1584 + png_bytep entry_start, buffer; 1.1585 + png_sPLT_t new_palette; 1.1586 + png_sPLT_entryp pp; 1.1587 + png_uint_32 data_length; 1.1588 + int entry_size, i; 1.1589 + png_uint_32 skip = 0; 1.1590 + png_uint_32 dl; 1.1591 + png_size_t max_dl; 1.1592 + 1.1593 + png_debug(1, "in png_handle_sPLT"); 1.1594 + 1.1595 +#ifdef PNG_USER_LIMITS_SUPPORTED 1.1596 + if (png_ptr->user_chunk_cache_max != 0) 1.1597 + { 1.1598 + if (png_ptr->user_chunk_cache_max == 1) 1.1599 + { 1.1600 + png_crc_finish(png_ptr, length); 1.1601 + return; 1.1602 + } 1.1603 + 1.1604 + if (--png_ptr->user_chunk_cache_max == 1) 1.1605 + { 1.1606 + png_warning(png_ptr, "No space in chunk cache for sPLT"); 1.1607 + png_crc_finish(png_ptr, length); 1.1608 + return; 1.1609 + } 1.1610 + } 1.1611 +#endif 1.1612 + 1.1613 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1614 + png_chunk_error(png_ptr, "missing IHDR"); 1.1615 + 1.1616 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1617 + { 1.1618 + png_crc_finish(png_ptr, length); 1.1619 + png_chunk_benign_error(png_ptr, "out of place"); 1.1620 + return; 1.1621 + } 1.1622 + 1.1623 +#ifdef PNG_MAX_MALLOC_64K 1.1624 + if (length > 65535U) 1.1625 + { 1.1626 + png_crc_finish(png_ptr, length); 1.1627 + png_chunk_benign_error(png_ptr, "too large to fit in memory"); 1.1628 + return; 1.1629 + } 1.1630 +#endif 1.1631 + 1.1632 + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); 1.1633 + if (buffer == NULL) 1.1634 + { 1.1635 + png_crc_finish(png_ptr, length); 1.1636 + png_chunk_benign_error(png_ptr, "out of memory"); 1.1637 + return; 1.1638 + } 1.1639 + 1.1640 + 1.1641 + /* WARNING: this may break if size_t is less than 32 bits; it is assumed 1.1642 + * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a 1.1643 + * potential breakage point if the types in pngconf.h aren't exactly right. 1.1644 + */ 1.1645 + png_crc_read(png_ptr, buffer, length); 1.1646 + 1.1647 + if (png_crc_finish(png_ptr, skip)) 1.1648 + return; 1.1649 + 1.1650 + buffer[length] = 0; 1.1651 + 1.1652 + for (entry_start = buffer; *entry_start; entry_start++) 1.1653 + /* Empty loop to find end of name */ ; 1.1654 + 1.1655 + ++entry_start; 1.1656 + 1.1657 + /* A sample depth should follow the separator, and we should be on it */ 1.1658 + if (entry_start > buffer + length - 2) 1.1659 + { 1.1660 + png_warning(png_ptr, "malformed sPLT chunk"); 1.1661 + return; 1.1662 + } 1.1663 + 1.1664 + new_palette.depth = *entry_start++; 1.1665 + entry_size = (new_palette.depth == 8 ? 6 : 10); 1.1666 + /* This must fit in a png_uint_32 because it is derived from the original 1.1667 + * chunk data length. 1.1668 + */ 1.1669 + data_length = length - (png_uint_32)(entry_start - buffer); 1.1670 + 1.1671 + /* Integrity-check the data length */ 1.1672 + if (data_length % entry_size) 1.1673 + { 1.1674 + png_warning(png_ptr, "sPLT chunk has bad length"); 1.1675 + return; 1.1676 + } 1.1677 + 1.1678 + dl = (png_int_32)(data_length / entry_size); 1.1679 + max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); 1.1680 + 1.1681 + if (dl > max_dl) 1.1682 + { 1.1683 + png_warning(png_ptr, "sPLT chunk too long"); 1.1684 + return; 1.1685 + } 1.1686 + 1.1687 + new_palette.nentries = (png_int_32)(data_length / entry_size); 1.1688 + 1.1689 + new_palette.entries = (png_sPLT_entryp)png_malloc_warn( 1.1690 + png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry))); 1.1691 + 1.1692 + if (new_palette.entries == NULL) 1.1693 + { 1.1694 + png_warning(png_ptr, "sPLT chunk requires too much memory"); 1.1695 + return; 1.1696 + } 1.1697 + 1.1698 +#ifdef PNG_POINTER_INDEXING_SUPPORTED 1.1699 + for (i = 0; i < new_palette.nentries; i++) 1.1700 + { 1.1701 + pp = new_palette.entries + i; 1.1702 + 1.1703 + if (new_palette.depth == 8) 1.1704 + { 1.1705 + pp->red = *entry_start++; 1.1706 + pp->green = *entry_start++; 1.1707 + pp->blue = *entry_start++; 1.1708 + pp->alpha = *entry_start++; 1.1709 + } 1.1710 + 1.1711 + else 1.1712 + { 1.1713 + pp->red = png_get_uint_16(entry_start); entry_start += 2; 1.1714 + pp->green = png_get_uint_16(entry_start); entry_start += 2; 1.1715 + pp->blue = png_get_uint_16(entry_start); entry_start += 2; 1.1716 + pp->alpha = png_get_uint_16(entry_start); entry_start += 2; 1.1717 + } 1.1718 + 1.1719 + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1.1720 + } 1.1721 +#else 1.1722 + pp = new_palette.entries; 1.1723 + 1.1724 + for (i = 0; i < new_palette.nentries; i++) 1.1725 + { 1.1726 + 1.1727 + if (new_palette.depth == 8) 1.1728 + { 1.1729 + pp[i].red = *entry_start++; 1.1730 + pp[i].green = *entry_start++; 1.1731 + pp[i].blue = *entry_start++; 1.1732 + pp[i].alpha = *entry_start++; 1.1733 + } 1.1734 + 1.1735 + else 1.1736 + { 1.1737 + pp[i].red = png_get_uint_16(entry_start); entry_start += 2; 1.1738 + pp[i].green = png_get_uint_16(entry_start); entry_start += 2; 1.1739 + pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; 1.1740 + pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; 1.1741 + } 1.1742 + 1.1743 + pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2; 1.1744 + } 1.1745 +#endif 1.1746 + 1.1747 + /* Discard all chunk data except the name and stash that */ 1.1748 + new_palette.name = (png_charp)buffer; 1.1749 + 1.1750 + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); 1.1751 + 1.1752 + png_free(png_ptr, new_palette.entries); 1.1753 +} 1.1754 +#endif /* PNG_READ_sPLT_SUPPORTED */ 1.1755 + 1.1756 +#ifdef PNG_READ_tRNS_SUPPORTED 1.1757 +void /* PRIVATE */ 1.1758 +png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1759 +{ 1.1760 + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; 1.1761 + 1.1762 + png_debug(1, "in png_handle_tRNS"); 1.1763 + 1.1764 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1765 + png_chunk_error(png_ptr, "missing IHDR"); 1.1766 + 1.1767 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1768 + { 1.1769 + png_crc_finish(png_ptr, length); 1.1770 + png_chunk_benign_error(png_ptr, "out of place"); 1.1771 + return; 1.1772 + } 1.1773 + 1.1774 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 1.1775 + { 1.1776 + png_crc_finish(png_ptr, length); 1.1777 + png_chunk_benign_error(png_ptr, "duplicate"); 1.1778 + return; 1.1779 + } 1.1780 + 1.1781 + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1.1782 + { 1.1783 + png_byte buf[2]; 1.1784 + 1.1785 + if (length != 2) 1.1786 + { 1.1787 + png_crc_finish(png_ptr, length); 1.1788 + png_chunk_benign_error(png_ptr, "invalid"); 1.1789 + return; 1.1790 + } 1.1791 + 1.1792 + png_crc_read(png_ptr, buf, 2); 1.1793 + png_ptr->num_trans = 1; 1.1794 + png_ptr->trans_color.gray = png_get_uint_16(buf); 1.1795 + } 1.1796 + 1.1797 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1.1798 + { 1.1799 + png_byte buf[6]; 1.1800 + 1.1801 + if (length != 6) 1.1802 + { 1.1803 + png_crc_finish(png_ptr, length); 1.1804 + png_chunk_benign_error(png_ptr, "invalid"); 1.1805 + return; 1.1806 + } 1.1807 + 1.1808 + png_crc_read(png_ptr, buf, length); 1.1809 + png_ptr->num_trans = 1; 1.1810 + png_ptr->trans_color.red = png_get_uint_16(buf); 1.1811 + png_ptr->trans_color.green = png_get_uint_16(buf + 2); 1.1812 + png_ptr->trans_color.blue = png_get_uint_16(buf + 4); 1.1813 + } 1.1814 + 1.1815 + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.1816 + { 1.1817 + if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1.1818 + { 1.1819 + /* TODO: is this actually an error in the ISO spec? */ 1.1820 + png_crc_finish(png_ptr, length); 1.1821 + png_chunk_benign_error(png_ptr, "out of place"); 1.1822 + return; 1.1823 + } 1.1824 + 1.1825 + if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH || 1.1826 + length == 0) 1.1827 + { 1.1828 + png_crc_finish(png_ptr, length); 1.1829 + png_chunk_benign_error(png_ptr, "invalid"); 1.1830 + return; 1.1831 + } 1.1832 + 1.1833 + png_crc_read(png_ptr, readbuf, length); 1.1834 + png_ptr->num_trans = (png_uint_16)length; 1.1835 + } 1.1836 + 1.1837 + else 1.1838 + { 1.1839 + png_crc_finish(png_ptr, length); 1.1840 + png_chunk_benign_error(png_ptr, "invalid with alpha channel"); 1.1841 + return; 1.1842 + } 1.1843 + 1.1844 + if (png_crc_finish(png_ptr, 0)) 1.1845 + { 1.1846 + png_ptr->num_trans = 0; 1.1847 + return; 1.1848 + } 1.1849 + 1.1850 + /* TODO: this is a horrible side effect in the palette case because the 1.1851 + * png_struct ends up with a pointer to the tRNS buffer owned by the 1.1852 + * png_info. Fix this. 1.1853 + */ 1.1854 + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, 1.1855 + &(png_ptr->trans_color)); 1.1856 +} 1.1857 +#endif 1.1858 + 1.1859 +#ifdef PNG_READ_bKGD_SUPPORTED 1.1860 +void /* PRIVATE */ 1.1861 +png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1862 +{ 1.1863 + unsigned int truelen; 1.1864 + png_byte buf[6]; 1.1865 + png_color_16 background; 1.1866 + 1.1867 + png_debug(1, "in png_handle_bKGD"); 1.1868 + 1.1869 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1870 + png_chunk_error(png_ptr, "missing IHDR"); 1.1871 + 1.1872 + else if ((png_ptr->mode & PNG_HAVE_IDAT) || 1.1873 + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 1.1874 + !(png_ptr->mode & PNG_HAVE_PLTE))) 1.1875 + { 1.1876 + png_crc_finish(png_ptr, length); 1.1877 + png_chunk_benign_error(png_ptr, "out of place"); 1.1878 + return; 1.1879 + } 1.1880 + 1.1881 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) 1.1882 + { 1.1883 + png_crc_finish(png_ptr, length); 1.1884 + png_chunk_benign_error(png_ptr, "duplicate"); 1.1885 + return; 1.1886 + } 1.1887 + 1.1888 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.1889 + truelen = 1; 1.1890 + 1.1891 + else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1.1892 + truelen = 6; 1.1893 + 1.1894 + else 1.1895 + truelen = 2; 1.1896 + 1.1897 + if (length != truelen) 1.1898 + { 1.1899 + png_crc_finish(png_ptr, length); 1.1900 + png_chunk_benign_error(png_ptr, "invalid"); 1.1901 + return; 1.1902 + } 1.1903 + 1.1904 + png_crc_read(png_ptr, buf, truelen); 1.1905 + 1.1906 + if (png_crc_finish(png_ptr, 0)) 1.1907 + return; 1.1908 + 1.1909 + /* We convert the index value into RGB components so that we can allow 1.1910 + * arbitrary RGB values for background when we have transparency, and 1.1911 + * so it is easy to determine the RGB values of the background color 1.1912 + * from the info_ptr struct. 1.1913 + */ 1.1914 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.1915 + { 1.1916 + background.index = buf[0]; 1.1917 + 1.1918 + if (info_ptr && info_ptr->num_palette) 1.1919 + { 1.1920 + if (buf[0] >= info_ptr->num_palette) 1.1921 + { 1.1922 + png_chunk_benign_error(png_ptr, "invalid index"); 1.1923 + return; 1.1924 + } 1.1925 + 1.1926 + background.red = (png_uint_16)png_ptr->palette[buf[0]].red; 1.1927 + background.green = (png_uint_16)png_ptr->palette[buf[0]].green; 1.1928 + background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; 1.1929 + } 1.1930 + 1.1931 + else 1.1932 + background.red = background.green = background.blue = 0; 1.1933 + 1.1934 + background.gray = 0; 1.1935 + } 1.1936 + 1.1937 + else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ 1.1938 + { 1.1939 + background.index = 0; 1.1940 + background.red = 1.1941 + background.green = 1.1942 + background.blue = 1.1943 + background.gray = png_get_uint_16(buf); 1.1944 + } 1.1945 + 1.1946 + else 1.1947 + { 1.1948 + background.index = 0; 1.1949 + background.red = png_get_uint_16(buf); 1.1950 + background.green = png_get_uint_16(buf + 2); 1.1951 + background.blue = png_get_uint_16(buf + 4); 1.1952 + background.gray = 0; 1.1953 + } 1.1954 + 1.1955 + png_set_bKGD(png_ptr, info_ptr, &background); 1.1956 +} 1.1957 +#endif 1.1958 + 1.1959 +#ifdef PNG_READ_hIST_SUPPORTED 1.1960 +void /* PRIVATE */ 1.1961 +png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.1962 +{ 1.1963 + unsigned int num, i; 1.1964 + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; 1.1965 + 1.1966 + png_debug(1, "in png_handle_hIST"); 1.1967 + 1.1968 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1969 + png_chunk_error(png_ptr, "missing IHDR"); 1.1970 + 1.1971 + else if ((png_ptr->mode & PNG_HAVE_IDAT) || !(png_ptr->mode & PNG_HAVE_PLTE)) 1.1972 + { 1.1973 + png_crc_finish(png_ptr, length); 1.1974 + png_chunk_benign_error(png_ptr, "out of place"); 1.1975 + return; 1.1976 + } 1.1977 + 1.1978 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) 1.1979 + { 1.1980 + png_crc_finish(png_ptr, length); 1.1981 + png_chunk_benign_error(png_ptr, "duplicate"); 1.1982 + return; 1.1983 + } 1.1984 + 1.1985 + num = length / 2 ; 1.1986 + 1.1987 + if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH) 1.1988 + { 1.1989 + png_crc_finish(png_ptr, length); 1.1990 + png_chunk_benign_error(png_ptr, "invalid"); 1.1991 + return; 1.1992 + } 1.1993 + 1.1994 + for (i = 0; i < num; i++) 1.1995 + { 1.1996 + png_byte buf[2]; 1.1997 + 1.1998 + png_crc_read(png_ptr, buf, 2); 1.1999 + readbuf[i] = png_get_uint_16(buf); 1.2000 + } 1.2001 + 1.2002 + if (png_crc_finish(png_ptr, 0)) 1.2003 + return; 1.2004 + 1.2005 + png_set_hIST(png_ptr, info_ptr, readbuf); 1.2006 +} 1.2007 +#endif 1.2008 + 1.2009 +#ifdef PNG_READ_pHYs_SUPPORTED 1.2010 +void /* PRIVATE */ 1.2011 +png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2012 +{ 1.2013 + png_byte buf[9]; 1.2014 + png_uint_32 res_x, res_y; 1.2015 + int unit_type; 1.2016 + 1.2017 + png_debug(1, "in png_handle_pHYs"); 1.2018 + 1.2019 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2020 + png_chunk_error(png_ptr, "missing IHDR"); 1.2021 + 1.2022 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.2023 + { 1.2024 + png_crc_finish(png_ptr, length); 1.2025 + png_chunk_benign_error(png_ptr, "out of place"); 1.2026 + return; 1.2027 + } 1.2028 + 1.2029 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) 1.2030 + { 1.2031 + png_crc_finish(png_ptr, length); 1.2032 + png_chunk_benign_error(png_ptr, "duplicate"); 1.2033 + return; 1.2034 + } 1.2035 + 1.2036 + if (length != 9) 1.2037 + { 1.2038 + png_crc_finish(png_ptr, length); 1.2039 + png_chunk_benign_error(png_ptr, "invalid"); 1.2040 + return; 1.2041 + } 1.2042 + 1.2043 + png_crc_read(png_ptr, buf, 9); 1.2044 + 1.2045 + if (png_crc_finish(png_ptr, 0)) 1.2046 + return; 1.2047 + 1.2048 + res_x = png_get_uint_32(buf); 1.2049 + res_y = png_get_uint_32(buf + 4); 1.2050 + unit_type = buf[8]; 1.2051 + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); 1.2052 +} 1.2053 +#endif 1.2054 + 1.2055 +#ifdef PNG_READ_oFFs_SUPPORTED 1.2056 +void /* PRIVATE */ 1.2057 +png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2058 +{ 1.2059 + png_byte buf[9]; 1.2060 + png_int_32 offset_x, offset_y; 1.2061 + int unit_type; 1.2062 + 1.2063 + png_debug(1, "in png_handle_oFFs"); 1.2064 + 1.2065 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2066 + png_chunk_error(png_ptr, "missing IHDR"); 1.2067 + 1.2068 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.2069 + { 1.2070 + png_crc_finish(png_ptr, length); 1.2071 + png_chunk_benign_error(png_ptr, "out of place"); 1.2072 + return; 1.2073 + } 1.2074 + 1.2075 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) 1.2076 + { 1.2077 + png_crc_finish(png_ptr, length); 1.2078 + png_chunk_benign_error(png_ptr, "duplicate"); 1.2079 + return; 1.2080 + } 1.2081 + 1.2082 + if (length != 9) 1.2083 + { 1.2084 + png_crc_finish(png_ptr, length); 1.2085 + png_chunk_benign_error(png_ptr, "invalid"); 1.2086 + return; 1.2087 + } 1.2088 + 1.2089 + png_crc_read(png_ptr, buf, 9); 1.2090 + 1.2091 + if (png_crc_finish(png_ptr, 0)) 1.2092 + return; 1.2093 + 1.2094 + offset_x = png_get_int_32(buf); 1.2095 + offset_y = png_get_int_32(buf + 4); 1.2096 + unit_type = buf[8]; 1.2097 + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); 1.2098 +} 1.2099 +#endif 1.2100 + 1.2101 +#ifdef PNG_READ_pCAL_SUPPORTED 1.2102 +/* Read the pCAL chunk (described in the PNG Extensions document) */ 1.2103 +void /* PRIVATE */ 1.2104 +png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2105 +{ 1.2106 + png_int_32 X0, X1; 1.2107 + png_byte type, nparams; 1.2108 + png_bytep buffer, buf, units, endptr; 1.2109 + png_charpp params; 1.2110 + int i; 1.2111 + 1.2112 + png_debug(1, "in png_handle_pCAL"); 1.2113 + 1.2114 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2115 + png_chunk_error(png_ptr, "missing IHDR"); 1.2116 + 1.2117 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.2118 + { 1.2119 + png_crc_finish(png_ptr, length); 1.2120 + png_chunk_benign_error(png_ptr, "out of place"); 1.2121 + return; 1.2122 + } 1.2123 + 1.2124 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) 1.2125 + { 1.2126 + png_crc_finish(png_ptr, length); 1.2127 + png_chunk_benign_error(png_ptr, "duplicate"); 1.2128 + return; 1.2129 + } 1.2130 + 1.2131 + png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", 1.2132 + length + 1); 1.2133 + 1.2134 + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); 1.2135 + 1.2136 + if (buffer == NULL) 1.2137 + { 1.2138 + png_crc_finish(png_ptr, length); 1.2139 + png_chunk_benign_error(png_ptr, "out of memory"); 1.2140 + return; 1.2141 + } 1.2142 + 1.2143 + png_crc_read(png_ptr, buffer, length); 1.2144 + 1.2145 + if (png_crc_finish(png_ptr, 0)) 1.2146 + return; 1.2147 + 1.2148 + buffer[length] = 0; /* Null terminate the last string */ 1.2149 + 1.2150 + png_debug(3, "Finding end of pCAL purpose string"); 1.2151 + for (buf = buffer; *buf; buf++) 1.2152 + /* Empty loop */ ; 1.2153 + 1.2154 + endptr = buffer + length; 1.2155 + 1.2156 + /* We need to have at least 12 bytes after the purpose string 1.2157 + * in order to get the parameter information. 1.2158 + */ 1.2159 + if (endptr <= buf + 12) 1.2160 + { 1.2161 + png_chunk_benign_error(png_ptr, "invalid"); 1.2162 + return; 1.2163 + } 1.2164 + 1.2165 + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); 1.2166 + X0 = png_get_int_32((png_bytep)buf+1); 1.2167 + X1 = png_get_int_32((png_bytep)buf+5); 1.2168 + type = buf[9]; 1.2169 + nparams = buf[10]; 1.2170 + units = buf + 11; 1.2171 + 1.2172 + png_debug(3, "Checking pCAL equation type and number of parameters"); 1.2173 + /* Check that we have the right number of parameters for known 1.2174 + * equation types. 1.2175 + */ 1.2176 + if ((type == PNG_EQUATION_LINEAR && nparams != 2) || 1.2177 + (type == PNG_EQUATION_BASE_E && nparams != 3) || 1.2178 + (type == PNG_EQUATION_ARBITRARY && nparams != 3) || 1.2179 + (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) 1.2180 + { 1.2181 + png_chunk_benign_error(png_ptr, "invalid parameter count"); 1.2182 + return; 1.2183 + } 1.2184 + 1.2185 + else if (type >= PNG_EQUATION_LAST) 1.2186 + { 1.2187 + png_chunk_benign_error(png_ptr, "unrecognized equation type"); 1.2188 + } 1.2189 + 1.2190 + for (buf = units; *buf; buf++) 1.2191 + /* Empty loop to move past the units string. */ ; 1.2192 + 1.2193 + png_debug(3, "Allocating pCAL parameters array"); 1.2194 + 1.2195 + params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, 1.2196 + nparams * (sizeof (png_charp)))); 1.2197 + 1.2198 + if (params == NULL) 1.2199 + { 1.2200 + png_chunk_benign_error(png_ptr, "out of memory"); 1.2201 + return; 1.2202 + } 1.2203 + 1.2204 + /* Get pointers to the start of each parameter string. */ 1.2205 + for (i = 0; i < nparams; i++) 1.2206 + { 1.2207 + buf++; /* Skip the null string terminator from previous parameter. */ 1.2208 + 1.2209 + png_debug1(3, "Reading pCAL parameter %d", i); 1.2210 + 1.2211 + for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) 1.2212 + /* Empty loop to move past each parameter string */ ; 1.2213 + 1.2214 + /* Make sure we haven't run out of data yet */ 1.2215 + if (buf > endptr) 1.2216 + { 1.2217 + png_free(png_ptr, params); 1.2218 + png_chunk_benign_error(png_ptr, "invalid data"); 1.2219 + return; 1.2220 + } 1.2221 + } 1.2222 + 1.2223 + png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, 1.2224 + (png_charp)units, params); 1.2225 + 1.2226 + png_free(png_ptr, params); 1.2227 +} 1.2228 +#endif 1.2229 + 1.2230 +#ifdef PNG_READ_sCAL_SUPPORTED 1.2231 +/* Read the sCAL chunk */ 1.2232 +void /* PRIVATE */ 1.2233 +png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2234 +{ 1.2235 + png_bytep buffer; 1.2236 + png_size_t i; 1.2237 + int state; 1.2238 + 1.2239 + png_debug(1, "in png_handle_sCAL"); 1.2240 + 1.2241 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2242 + png_chunk_error(png_ptr, "missing IHDR"); 1.2243 + 1.2244 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.2245 + { 1.2246 + png_crc_finish(png_ptr, length); 1.2247 + png_chunk_benign_error(png_ptr, "out of place"); 1.2248 + return; 1.2249 + } 1.2250 + 1.2251 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) 1.2252 + { 1.2253 + png_crc_finish(png_ptr, length); 1.2254 + png_chunk_benign_error(png_ptr, "duplicate"); 1.2255 + return; 1.2256 + } 1.2257 + 1.2258 + /* Need unit type, width, \0, height: minimum 4 bytes */ 1.2259 + else if (length < 4) 1.2260 + { 1.2261 + png_crc_finish(png_ptr, length); 1.2262 + png_chunk_benign_error(png_ptr, "invalid"); 1.2263 + return; 1.2264 + } 1.2265 + 1.2266 + png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", 1.2267 + length + 1); 1.2268 + 1.2269 + buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); 1.2270 + 1.2271 + if (buffer == NULL) 1.2272 + { 1.2273 + png_chunk_benign_error(png_ptr, "out of memory"); 1.2274 + png_crc_finish(png_ptr, length); 1.2275 + return; 1.2276 + } 1.2277 + 1.2278 + png_crc_read(png_ptr, buffer, length); 1.2279 + buffer[length] = 0; /* Null terminate the last string */ 1.2280 + 1.2281 + if (png_crc_finish(png_ptr, 0)) 1.2282 + return; 1.2283 + 1.2284 + /* Validate the unit. */ 1.2285 + if (buffer[0] != 1 && buffer[0] != 2) 1.2286 + { 1.2287 + png_chunk_benign_error(png_ptr, "invalid unit"); 1.2288 + return; 1.2289 + } 1.2290 + 1.2291 + /* Validate the ASCII numbers, need two ASCII numbers separated by 1.2292 + * a '\0' and they need to fit exactly in the chunk data. 1.2293 + */ 1.2294 + i = 1; 1.2295 + state = 0; 1.2296 + 1.2297 + if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) || 1.2298 + i >= length || buffer[i++] != 0) 1.2299 + png_chunk_benign_error(png_ptr, "bad width format"); 1.2300 + 1.2301 + else if (!PNG_FP_IS_POSITIVE(state)) 1.2302 + png_chunk_benign_error(png_ptr, "non-positive width"); 1.2303 + 1.2304 + else 1.2305 + { 1.2306 + png_size_t heighti = i; 1.2307 + 1.2308 + state = 0; 1.2309 + if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) || 1.2310 + i != length) 1.2311 + png_chunk_benign_error(png_ptr, "bad height format"); 1.2312 + 1.2313 + else if (!PNG_FP_IS_POSITIVE(state)) 1.2314 + png_chunk_benign_error(png_ptr, "non-positive height"); 1.2315 + 1.2316 + else 1.2317 + /* This is the (only) success case. */ 1.2318 + png_set_sCAL_s(png_ptr, info_ptr, buffer[0], 1.2319 + (png_charp)buffer+1, (png_charp)buffer+heighti); 1.2320 + } 1.2321 +} 1.2322 +#endif 1.2323 + 1.2324 +#ifdef PNG_READ_tIME_SUPPORTED 1.2325 +void /* PRIVATE */ 1.2326 +png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2327 +{ 1.2328 + png_byte buf[7]; 1.2329 + png_time mod_time; 1.2330 + 1.2331 + png_debug(1, "in png_handle_tIME"); 1.2332 + 1.2333 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2334 + png_chunk_error(png_ptr, "missing IHDR"); 1.2335 + 1.2336 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 1.2337 + { 1.2338 + png_crc_finish(png_ptr, length); 1.2339 + png_chunk_benign_error(png_ptr, "duplicate"); 1.2340 + return; 1.2341 + } 1.2342 + 1.2343 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.2344 + png_ptr->mode |= PNG_AFTER_IDAT; 1.2345 + 1.2346 + if (length != 7) 1.2347 + { 1.2348 + png_crc_finish(png_ptr, length); 1.2349 + png_chunk_benign_error(png_ptr, "invalid"); 1.2350 + return; 1.2351 + } 1.2352 + 1.2353 + png_crc_read(png_ptr, buf, 7); 1.2354 + 1.2355 + if (png_crc_finish(png_ptr, 0)) 1.2356 + return; 1.2357 + 1.2358 + mod_time.second = buf[6]; 1.2359 + mod_time.minute = buf[5]; 1.2360 + mod_time.hour = buf[4]; 1.2361 + mod_time.day = buf[3]; 1.2362 + mod_time.month = buf[2]; 1.2363 + mod_time.year = png_get_uint_16(buf); 1.2364 + 1.2365 + png_set_tIME(png_ptr, info_ptr, &mod_time); 1.2366 +} 1.2367 +#endif 1.2368 + 1.2369 +#ifdef PNG_READ_tEXt_SUPPORTED 1.2370 +/* Note: this does not properly handle chunks that are > 64K under DOS */ 1.2371 +void /* PRIVATE */ 1.2372 +png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2373 +{ 1.2374 + png_text text_info; 1.2375 + png_bytep buffer; 1.2376 + png_charp key; 1.2377 + png_charp text; 1.2378 + png_uint_32 skip = 0; 1.2379 + 1.2380 + png_debug(1, "in png_handle_tEXt"); 1.2381 + 1.2382 +#ifdef PNG_USER_LIMITS_SUPPORTED 1.2383 + if (png_ptr->user_chunk_cache_max != 0) 1.2384 + { 1.2385 + if (png_ptr->user_chunk_cache_max == 1) 1.2386 + { 1.2387 + png_crc_finish(png_ptr, length); 1.2388 + return; 1.2389 + } 1.2390 + 1.2391 + if (--png_ptr->user_chunk_cache_max == 1) 1.2392 + { 1.2393 + png_crc_finish(png_ptr, length); 1.2394 + png_chunk_benign_error(png_ptr, "no space in chunk cache"); 1.2395 + return; 1.2396 + } 1.2397 + } 1.2398 +#endif 1.2399 + 1.2400 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2401 + png_chunk_error(png_ptr, "missing IHDR"); 1.2402 + 1.2403 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.2404 + png_ptr->mode |= PNG_AFTER_IDAT; 1.2405 + 1.2406 +#ifdef PNG_MAX_MALLOC_64K 1.2407 + if (length > 65535U) 1.2408 + { 1.2409 + png_crc_finish(png_ptr, length); 1.2410 + png_chunk_benign_error(png_ptr, "too large to fit in memory"); 1.2411 + return; 1.2412 + } 1.2413 +#endif 1.2414 + 1.2415 + buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); 1.2416 + 1.2417 + if (buffer == NULL) 1.2418 + { 1.2419 + png_chunk_benign_error(png_ptr, "out of memory"); 1.2420 + return; 1.2421 + } 1.2422 + 1.2423 + png_crc_read(png_ptr, buffer, length); 1.2424 + 1.2425 + if (png_crc_finish(png_ptr, skip)) 1.2426 + return; 1.2427 + 1.2428 + key = (png_charp)buffer; 1.2429 + key[length] = 0; 1.2430 + 1.2431 + for (text = key; *text; text++) 1.2432 + /* Empty loop to find end of key */ ; 1.2433 + 1.2434 + if (text != key + length) 1.2435 + text++; 1.2436 + 1.2437 + text_info.compression = PNG_TEXT_COMPRESSION_NONE; 1.2438 + text_info.key = key; 1.2439 + text_info.lang = NULL; 1.2440 + text_info.lang_key = NULL; 1.2441 + text_info.itxt_length = 0; 1.2442 + text_info.text = text; 1.2443 + text_info.text_length = strlen(text); 1.2444 + 1.2445 + if (png_set_text_2(png_ptr, info_ptr, &text_info, 1)) 1.2446 + png_warning(png_ptr, "Insufficient memory to process text chunk"); 1.2447 +} 1.2448 +#endif 1.2449 + 1.2450 +#ifdef PNG_READ_zTXt_SUPPORTED 1.2451 +/* Note: this does not correctly handle chunks that are > 64K under DOS */ 1.2452 +void /* PRIVATE */ 1.2453 +png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2454 +{ 1.2455 + png_const_charp errmsg = NULL; 1.2456 + png_bytep buffer; 1.2457 + png_uint_32 keyword_length; 1.2458 + 1.2459 + png_debug(1, "in png_handle_zTXt"); 1.2460 + 1.2461 +#ifdef PNG_USER_LIMITS_SUPPORTED 1.2462 + if (png_ptr->user_chunk_cache_max != 0) 1.2463 + { 1.2464 + if (png_ptr->user_chunk_cache_max == 1) 1.2465 + { 1.2466 + png_crc_finish(png_ptr, length); 1.2467 + return; 1.2468 + } 1.2469 + 1.2470 + if (--png_ptr->user_chunk_cache_max == 1) 1.2471 + { 1.2472 + png_crc_finish(png_ptr, length); 1.2473 + png_chunk_benign_error(png_ptr, "no space in chunk cache"); 1.2474 + return; 1.2475 + } 1.2476 + } 1.2477 +#endif 1.2478 + 1.2479 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2480 + png_chunk_error(png_ptr, "missing IHDR"); 1.2481 + 1.2482 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.2483 + png_ptr->mode |= PNG_AFTER_IDAT; 1.2484 + 1.2485 + buffer = png_read_buffer(png_ptr, length, 2/*silent*/); 1.2486 + 1.2487 + if (buffer == NULL) 1.2488 + { 1.2489 + png_crc_finish(png_ptr, length); 1.2490 + png_chunk_benign_error(png_ptr, "out of memory"); 1.2491 + return; 1.2492 + } 1.2493 + 1.2494 + png_crc_read(png_ptr, buffer, length); 1.2495 + 1.2496 + if (png_crc_finish(png_ptr, 0)) 1.2497 + return; 1.2498 + 1.2499 + /* TODO: also check that the keyword contents match the spec! */ 1.2500 + for (keyword_length = 0; 1.2501 + keyword_length < length && buffer[keyword_length] != 0; 1.2502 + ++keyword_length) 1.2503 + /* Empty loop to find end of name */ ; 1.2504 + 1.2505 + if (keyword_length > 79 || keyword_length < 1) 1.2506 + errmsg = "bad keyword"; 1.2507 + 1.2508 + /* zTXt must have some LZ data after the keyword, although it may expand to 1.2509 + * zero bytes; we need a '\0' at the end of the keyword, the compression type 1.2510 + * then the LZ data: 1.2511 + */ 1.2512 + else if (keyword_length + 3 > length) 1.2513 + errmsg = "truncated"; 1.2514 + 1.2515 + else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) 1.2516 + errmsg = "unknown compression type"; 1.2517 + 1.2518 + else 1.2519 + { 1.2520 + png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; 1.2521 + 1.2522 + /* TODO: at present png_decompress_chunk imposes a single application 1.2523 + * level memory limit, this should be split to different values for iCCP 1.2524 + * and text chunks. 1.2525 + */ 1.2526 + if (png_decompress_chunk(png_ptr, length, keyword_length+2, 1.2527 + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) 1.2528 + { 1.2529 + png_text text; 1.2530 + 1.2531 + /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except 1.2532 + * for the extra compression type byte and the fact that it isn't 1.2533 + * necessarily '\0' terminated. 1.2534 + */ 1.2535 + buffer = png_ptr->read_buffer; 1.2536 + buffer[uncompressed_length+(keyword_length+2)] = 0; 1.2537 + 1.2538 + text.compression = PNG_TEXT_COMPRESSION_zTXt; 1.2539 + text.key = (png_charp)buffer; 1.2540 + text.text = (png_charp)(buffer + keyword_length+2); 1.2541 + text.text_length = uncompressed_length; 1.2542 + text.itxt_length = 0; 1.2543 + text.lang = NULL; 1.2544 + text.lang_key = NULL; 1.2545 + 1.2546 + if (png_set_text_2(png_ptr, info_ptr, &text, 1)) 1.2547 + errmsg = "insufficient memory"; 1.2548 + } 1.2549 + 1.2550 + else 1.2551 + errmsg = png_ptr->zstream.msg; 1.2552 + } 1.2553 + 1.2554 + if (errmsg != NULL) 1.2555 + png_chunk_benign_error(png_ptr, errmsg); 1.2556 +} 1.2557 +#endif 1.2558 + 1.2559 +#ifdef PNG_READ_iTXt_SUPPORTED 1.2560 +/* Note: this does not correctly handle chunks that are > 64K under DOS */ 1.2561 +void /* PRIVATE */ 1.2562 +png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) 1.2563 +{ 1.2564 + png_const_charp errmsg = NULL; 1.2565 + png_bytep buffer; 1.2566 + png_uint_32 prefix_length; 1.2567 + 1.2568 + png_debug(1, "in png_handle_iTXt"); 1.2569 + 1.2570 +#ifdef PNG_USER_LIMITS_SUPPORTED 1.2571 + if (png_ptr->user_chunk_cache_max != 0) 1.2572 + { 1.2573 + if (png_ptr->user_chunk_cache_max == 1) 1.2574 + { 1.2575 + png_crc_finish(png_ptr, length); 1.2576 + return; 1.2577 + } 1.2578 + 1.2579 + if (--png_ptr->user_chunk_cache_max == 1) 1.2580 + { 1.2581 + png_crc_finish(png_ptr, length); 1.2582 + png_chunk_benign_error(png_ptr, "no space in chunk cache"); 1.2583 + return; 1.2584 + } 1.2585 + } 1.2586 +#endif 1.2587 + 1.2588 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2589 + png_chunk_error(png_ptr, "missing IHDR"); 1.2590 + 1.2591 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.2592 + png_ptr->mode |= PNG_AFTER_IDAT; 1.2593 + 1.2594 + buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); 1.2595 + 1.2596 + if (buffer == NULL) 1.2597 + { 1.2598 + png_crc_finish(png_ptr, length); 1.2599 + png_chunk_benign_error(png_ptr, "out of memory"); 1.2600 + return; 1.2601 + } 1.2602 + 1.2603 + png_crc_read(png_ptr, buffer, length); 1.2604 + 1.2605 + if (png_crc_finish(png_ptr, 0)) 1.2606 + return; 1.2607 + 1.2608 + /* First the keyword. */ 1.2609 + for (prefix_length=0; 1.2610 + prefix_length < length && buffer[prefix_length] != 0; 1.2611 + ++prefix_length) 1.2612 + /* Empty loop */ ; 1.2613 + 1.2614 + /* Perform a basic check on the keyword length here. */ 1.2615 + if (prefix_length > 79 || prefix_length < 1) 1.2616 + errmsg = "bad keyword"; 1.2617 + 1.2618 + /* Expect keyword, compression flag, compression type, language, translated 1.2619 + * keyword (both may be empty but are 0 terminated) then the text, which may 1.2620 + * be empty. 1.2621 + */ 1.2622 + else if (prefix_length + 5 > length) 1.2623 + errmsg = "truncated"; 1.2624 + 1.2625 + else if (buffer[prefix_length+1] == 0 || 1.2626 + (buffer[prefix_length+1] == 1 && 1.2627 + buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) 1.2628 + { 1.2629 + int compressed = buffer[prefix_length+1] != 0; 1.2630 + png_uint_32 language_offset, translated_keyword_offset; 1.2631 + png_alloc_size_t uncompressed_length = 0; 1.2632 + 1.2633 + /* Now the language tag */ 1.2634 + prefix_length += 3; 1.2635 + language_offset = prefix_length; 1.2636 + 1.2637 + for (; prefix_length < length && buffer[prefix_length] != 0; 1.2638 + ++prefix_length) 1.2639 + /* Empty loop */ ; 1.2640 + 1.2641 + /* WARNING: the length may be invalid here, this is checked below. */ 1.2642 + translated_keyword_offset = ++prefix_length; 1.2643 + 1.2644 + for (; prefix_length < length && buffer[prefix_length] != 0; 1.2645 + ++prefix_length) 1.2646 + /* Empty loop */ ; 1.2647 + 1.2648 + /* prefix_length should now be at the trailing '\0' of the translated 1.2649 + * keyword, but it may already be over the end. None of this arithmetic 1.2650 + * can overflow because chunks are at most 2^31 bytes long, but on 16-bit 1.2651 + * systems the available allocaton may overflow. 1.2652 + */ 1.2653 + ++prefix_length; 1.2654 + 1.2655 + if (!compressed && prefix_length <= length) 1.2656 + uncompressed_length = length - prefix_length; 1.2657 + 1.2658 + else if (compressed && prefix_length < length) 1.2659 + { 1.2660 + uncompressed_length = PNG_SIZE_MAX; 1.2661 + 1.2662 + /* TODO: at present png_decompress_chunk imposes a single application 1.2663 + * level memory limit, this should be split to different values for 1.2664 + * iCCP and text chunks. 1.2665 + */ 1.2666 + if (png_decompress_chunk(png_ptr, length, prefix_length, 1.2667 + &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) 1.2668 + buffer = png_ptr->read_buffer; 1.2669 + 1.2670 + else 1.2671 + errmsg = png_ptr->zstream.msg; 1.2672 + } 1.2673 + 1.2674 + else 1.2675 + errmsg = "truncated"; 1.2676 + 1.2677 + if (errmsg == NULL) 1.2678 + { 1.2679 + png_text text; 1.2680 + 1.2681 + buffer[uncompressed_length+prefix_length] = 0; 1.2682 + 1.2683 + if (compressed) 1.2684 + text.compression = PNG_ITXT_COMPRESSION_NONE; 1.2685 + 1.2686 + else 1.2687 + text.compression = PNG_ITXT_COMPRESSION_zTXt; 1.2688 + 1.2689 + text.key = (png_charp)buffer; 1.2690 + text.lang = (png_charp)buffer + language_offset; 1.2691 + text.lang_key = (png_charp)buffer + translated_keyword_offset; 1.2692 + text.text = (png_charp)buffer + prefix_length; 1.2693 + text.text_length = 0; 1.2694 + text.itxt_length = uncompressed_length; 1.2695 + 1.2696 + if (png_set_text_2(png_ptr, info_ptr, &text, 1)) 1.2697 + errmsg = "insufficient memory"; 1.2698 + } 1.2699 + } 1.2700 + 1.2701 + else 1.2702 + errmsg = "bad compression info"; 1.2703 + 1.2704 + if (errmsg != NULL) 1.2705 + png_chunk_benign_error(png_ptr, errmsg); 1.2706 +} 1.2707 +#endif 1.2708 + 1.2709 +#ifdef PNG_READ_APNG_SUPPORTED 1.2710 +void /* PRIVATE */ 1.2711 +png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.2712 +{ 1.2713 + png_byte data[8]; 1.2714 + png_uint_32 num_frames; 1.2715 + png_uint_32 num_plays; 1.2716 + png_uint_32 didSet; 1.2717 + 1.2718 + png_debug(1, "in png_handle_acTL"); 1.2719 + 1.2720 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2721 + { 1.2722 + png_error(png_ptr, "Missing IHDR before acTL"); 1.2723 + } 1.2724 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.2725 + { 1.2726 + png_warning(png_ptr, "Invalid acTL after IDAT skipped"); 1.2727 + png_crc_finish(png_ptr, length); 1.2728 + return; 1.2729 + } 1.2730 + else if (png_ptr->mode & PNG_HAVE_acTL) 1.2731 + { 1.2732 + png_warning(png_ptr, "Duplicate acTL skipped"); 1.2733 + png_crc_finish(png_ptr, length); 1.2734 + return; 1.2735 + } 1.2736 + else if (length != 8) 1.2737 + { 1.2738 + png_warning(png_ptr, "acTL with invalid length skipped"); 1.2739 + png_crc_finish(png_ptr, length); 1.2740 + return; 1.2741 + } 1.2742 + 1.2743 + png_crc_read(png_ptr, data, 8); 1.2744 + png_crc_finish(png_ptr, 0); 1.2745 + 1.2746 + num_frames = png_get_uint_31(png_ptr, data); 1.2747 + num_plays = png_get_uint_31(png_ptr, data + 4); 1.2748 + 1.2749 + /* the set function will do error checking on num_frames */ 1.2750 + didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays); 1.2751 + if(didSet) 1.2752 + png_ptr->mode |= PNG_HAVE_acTL; 1.2753 +} 1.2754 + 1.2755 +void /* PRIVATE */ 1.2756 +png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.2757 +{ 1.2758 + png_byte data[22]; 1.2759 + png_uint_32 width; 1.2760 + png_uint_32 height; 1.2761 + png_uint_32 x_offset; 1.2762 + png_uint_32 y_offset; 1.2763 + png_uint_16 delay_num; 1.2764 + png_uint_16 delay_den; 1.2765 + png_byte dispose_op; 1.2766 + png_byte blend_op; 1.2767 + 1.2768 + png_debug(1, "in png_handle_fcTL"); 1.2769 + 1.2770 + png_ensure_sequence_number(png_ptr, length); 1.2771 + 1.2772 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2773 + { 1.2774 + png_error(png_ptr, "Missing IHDR before fcTL"); 1.2775 + } 1.2776 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.2777 + { 1.2778 + /* for any frames other then the first this message may be misleading, 1.2779 + * but correct. PNG_HAVE_IDAT is unset before the frame head is read 1.2780 + * i can't think of a better message */ 1.2781 + png_warning(png_ptr, "Invalid fcTL after IDAT skipped"); 1.2782 + png_crc_finish(png_ptr, length-4); 1.2783 + return; 1.2784 + } 1.2785 + else if (png_ptr->mode & PNG_HAVE_fcTL) 1.2786 + { 1.2787 + png_warning(png_ptr, "Duplicate fcTL within one frame skipped"); 1.2788 + png_crc_finish(png_ptr, length-4); 1.2789 + return; 1.2790 + } 1.2791 + else if (length != 26) 1.2792 + { 1.2793 + png_warning(png_ptr, "fcTL with invalid length skipped"); 1.2794 + png_crc_finish(png_ptr, length-4); 1.2795 + return; 1.2796 + } 1.2797 + 1.2798 + png_crc_read(png_ptr, data, 22); 1.2799 + png_crc_finish(png_ptr, 0); 1.2800 + 1.2801 + width = png_get_uint_31(png_ptr, data); 1.2802 + height = png_get_uint_31(png_ptr, data + 4); 1.2803 + x_offset = png_get_uint_31(png_ptr, data + 8); 1.2804 + y_offset = png_get_uint_31(png_ptr, data + 12); 1.2805 + delay_num = png_get_uint_16(data + 16); 1.2806 + delay_den = png_get_uint_16(data + 18); 1.2807 + dispose_op = data[20]; 1.2808 + blend_op = data[21]; 1.2809 + 1.2810 + if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0)) 1.2811 + { 1.2812 + png_warning(png_ptr, "fcTL for the first frame must have zero offset"); 1.2813 + return; 1.2814 + } 1.2815 + 1.2816 + if (info_ptr != NULL) 1.2817 + { 1.2818 + if (png_ptr->num_frames_read == 0 && 1.2819 + (width != info_ptr->width || height != info_ptr->height)) 1.2820 + { 1.2821 + png_warning(png_ptr, "size in first frame's fcTL must match " 1.2822 + "the size in IHDR"); 1.2823 + return; 1.2824 + } 1.2825 + 1.2826 + /* The set function will do more error checking */ 1.2827 + png_set_next_frame_fcTL(png_ptr, info_ptr, width, height, 1.2828 + x_offset, y_offset, delay_num, delay_den, 1.2829 + dispose_op, blend_op); 1.2830 + 1.2831 + png_read_reinit(png_ptr, info_ptr); 1.2832 + 1.2833 + png_ptr->mode |= PNG_HAVE_fcTL; 1.2834 + } 1.2835 +} 1.2836 + 1.2837 +void /* PRIVATE */ 1.2838 +png_have_info(png_structp png_ptr, png_infop info_ptr) 1.2839 +{ 1.2840 + if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL)) 1.2841 + { 1.2842 + png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN; 1.2843 + info_ptr->num_frames++; 1.2844 + } 1.2845 +} 1.2846 + 1.2847 +void /* PRIVATE */ 1.2848 +png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.2849 +{ 1.2850 + png_ensure_sequence_number(png_ptr, length); 1.2851 + 1.2852 + /* This function is only called from png_read_end(), png_read_info(), 1.2853 + * and png_push_read_chunk() which means that: 1.2854 + * - the user doesn't want to read this frame 1.2855 + * - or this is an out-of-place fdAT 1.2856 + * in either case it is safe to ignore the chunk with a warning */ 1.2857 + png_warning(png_ptr, "ignoring fdAT chunk"); 1.2858 + png_crc_finish(png_ptr, length - 4); 1.2859 + PNG_UNUSED(info_ptr) 1.2860 +} 1.2861 + 1.2862 +void /* PRIVATE */ 1.2863 +png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length) 1.2864 +{ 1.2865 + png_byte data[4]; 1.2866 + png_uint_32 sequence_number; 1.2867 + 1.2868 + if (length < 4) 1.2869 + png_error(png_ptr, "invalid fcTL or fdAT chunk found"); 1.2870 + 1.2871 + png_crc_read(png_ptr, data, 4); 1.2872 + sequence_number = png_get_uint_31(png_ptr, data); 1.2873 + 1.2874 + if (sequence_number != png_ptr->next_seq_num) 1.2875 + png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence " 1.2876 + "number found"); 1.2877 + 1.2878 + png_ptr->next_seq_num++; 1.2879 +} 1.2880 +#endif /* PNG_READ_APNG_SUPPORTED */ 1.2881 + 1.2882 +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 1.2883 +/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ 1.2884 +static int 1.2885 +png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) 1.2886 +{ 1.2887 + png_alloc_size_t limit = PNG_SIZE_MAX; 1.2888 + 1.2889 + if (png_ptr->unknown_chunk.data != NULL) 1.2890 + { 1.2891 + png_free(png_ptr, png_ptr->unknown_chunk.data); 1.2892 + png_ptr->unknown_chunk.data = NULL; 1.2893 + } 1.2894 + 1.2895 +# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED 1.2896 + if (png_ptr->user_chunk_malloc_max > 0 && 1.2897 + png_ptr->user_chunk_malloc_max < limit) 1.2898 + limit = png_ptr->user_chunk_malloc_max; 1.2899 + 1.2900 +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 1.2901 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) 1.2902 + limit = PNG_USER_CHUNK_MALLOC_MAX; 1.2903 +# endif 1.2904 + 1.2905 + if (length <= limit) 1.2906 + { 1.2907 + PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); 1.2908 + /* The following is safe because of the PNG_SIZE_MAX init above */ 1.2909 + png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/; 1.2910 + /* 'mode' is a flag array, only the bottom four bits matter here */ 1.2911 + png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; 1.2912 + 1.2913 + if (length == 0) 1.2914 + png_ptr->unknown_chunk.data = NULL; 1.2915 + 1.2916 + else 1.2917 + { 1.2918 + /* Do a 'warn' here - it is handled below. */ 1.2919 + png_ptr->unknown_chunk.data = png_voidcast(png_bytep, 1.2920 + png_malloc_warn(png_ptr, length)); 1.2921 + } 1.2922 + } 1.2923 + 1.2924 + if (png_ptr->unknown_chunk.data == NULL && length > 0) 1.2925 + { 1.2926 + /* This is benign because we clean up correctly */ 1.2927 + png_crc_finish(png_ptr, length); 1.2928 + png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); 1.2929 + return 0; 1.2930 + } 1.2931 + 1.2932 + else 1.2933 + { 1.2934 + if (length > 0) 1.2935 + png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); 1.2936 + png_crc_finish(png_ptr, 0); 1.2937 + return 1; 1.2938 + } 1.2939 +} 1.2940 +#endif /* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ 1.2941 + 1.2942 +/* Handle an unknown, or known but disabled, chunk */ 1.2943 +void /* PRIVATE */ 1.2944 +png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, 1.2945 + png_uint_32 length, int keep) 1.2946 +{ 1.2947 + int handled = 0; /* the chunk was handled */ 1.2948 + 1.2949 + png_debug(1, "in png_handle_unknown"); 1.2950 + 1.2951 +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 1.2952 + /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing 1.2953 + * the bug which meant that setting a non-default behavior for a specific 1.2954 + * chunk would be ignored (the default was always used unless a user 1.2955 + * callback was installed). 1.2956 + * 1.2957 + * 'keep' is the value from the png_chunk_unknown_handling, the setting for 1.2958 + * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it 1.2959 + * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. 1.2960 + * This is just an optimization to avoid multiple calls to the lookup 1.2961 + * function. 1.2962 + */ 1.2963 +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 1.2964 +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED 1.2965 + keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); 1.2966 +# endif 1.2967 +# endif 1.2968 + 1.2969 + /* One of the following methods will read the chunk or skip it (at least one 1.2970 + * of these is always defined because this is the only way to switch on 1.2971 + * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 1.2972 + */ 1.2973 +# ifdef PNG_READ_USER_CHUNKS_SUPPORTED 1.2974 + /* The user callback takes precedence over the chunk keep value, but the 1.2975 + * keep value is still required to validate a save of a critical chunk. 1.2976 + */ 1.2977 + if (png_ptr->read_user_chunk_fn != NULL) 1.2978 + { 1.2979 + if (png_cache_unknown_chunk(png_ptr, length)) 1.2980 + { 1.2981 + /* Callback to user unknown chunk handler */ 1.2982 + int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, 1.2983 + &png_ptr->unknown_chunk); 1.2984 + 1.2985 + /* ret is: 1.2986 + * negative: An error occured, png_chunk_error will be called. 1.2987 + * zero: The chunk was not handled, the chunk will be discarded 1.2988 + * unless png_set_keep_unknown_chunks has been used to set 1.2989 + * a 'keep' behavior for this particular chunk, in which 1.2990 + * case that will be used. A critical chunk will cause an 1.2991 + * error at this point unless it is to be saved. 1.2992 + * positive: The chunk was handled, libpng will ignore/discard it. 1.2993 + */ 1.2994 + if (ret < 0) 1.2995 + png_chunk_error(png_ptr, "error in user chunk"); 1.2996 + 1.2997 + else if (ret == 0) 1.2998 + { 1.2999 + /* If the keep value is 'default' or 'never' override it, but 1.3000 + * still error out on critical chunks unless the keep value is 1.3001 + * 'always' While this is weird it is the behavior in 1.4.12. 1.3002 + * A possible improvement would be to obey the value set for the 1.3003 + * chunk, but this would be an API change that would probably 1.3004 + * damage some applications. 1.3005 + * 1.3006 + * The png_app_warning below catches the case that matters, where 1.3007 + * the application has not set specific save or ignore for this 1.3008 + * chunk or global save or ignore. 1.3009 + */ 1.3010 + if (keep < PNG_HANDLE_CHUNK_IF_SAFE) 1.3011 + { 1.3012 +# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED 1.3013 + if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) 1.3014 + { 1.3015 + png_chunk_warning(png_ptr, "Saving unknown chunk:"); 1.3016 + png_app_warning(png_ptr, 1.3017 + "forcing save of an unhandled chunk;" 1.3018 + " please call png_set_keep_unknown_chunks"); 1.3019 + /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ 1.3020 + } 1.3021 +# endif 1.3022 + keep = PNG_HANDLE_CHUNK_IF_SAFE; 1.3023 + } 1.3024 + } 1.3025 + 1.3026 + else /* chunk was handled */ 1.3027 + { 1.3028 + handled = 1; 1.3029 + /* Critical chunks can be safely discarded at this point. */ 1.3030 + keep = PNG_HANDLE_CHUNK_NEVER; 1.3031 + } 1.3032 + } 1.3033 + 1.3034 + else 1.3035 + keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ 1.3036 + } 1.3037 + 1.3038 + else 1.3039 + /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ 1.3040 +# endif /* PNG_READ_USER_CHUNKS_SUPPORTED */ 1.3041 + 1.3042 +# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED 1.3043 + { 1.3044 + /* keep is currently just the per-chunk setting, if there was no 1.3045 + * setting change it to the global default now (not that this may 1.3046 + * still be AS_DEFAULT) then obtain the cache of the chunk if required, 1.3047 + * if not simply skip the chunk. 1.3048 + */ 1.3049 + if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) 1.3050 + keep = png_ptr->unknown_default; 1.3051 + 1.3052 + if (keep == PNG_HANDLE_CHUNK_ALWAYS || 1.3053 + (keep == PNG_HANDLE_CHUNK_IF_SAFE && 1.3054 + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) 1.3055 + { 1.3056 + if (!png_cache_unknown_chunk(png_ptr, length)) 1.3057 + keep = PNG_HANDLE_CHUNK_NEVER; 1.3058 + } 1.3059 + 1.3060 + else 1.3061 + png_crc_finish(png_ptr, length); 1.3062 + } 1.3063 +# else 1.3064 +# ifndef PNG_READ_USER_CHUNKS_SUPPORTED 1.3065 +# error no method to support READ_UNKNOWN_CHUNKS 1.3066 +# endif 1.3067 + 1.3068 + { 1.3069 + /* If here there is no read callback pointer set and no support is 1.3070 + * compiled in to just save the unknown chunks, so simply skip this 1.3071 + * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then 1.3072 + * the app has erroneously asked for unknown chunk saving when there 1.3073 + * is no support. 1.3074 + */ 1.3075 + if (keep > PNG_HANDLE_CHUNK_NEVER) 1.3076 + png_app_error(png_ptr, "no unknown chunk support available"); 1.3077 + 1.3078 + png_crc_finish(png_ptr, length); 1.3079 + } 1.3080 +# endif 1.3081 + 1.3082 +# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED 1.3083 + /* Now store the chunk in the chunk list if appropriate, and if the limits 1.3084 + * permit it. 1.3085 + */ 1.3086 + if (keep == PNG_HANDLE_CHUNK_ALWAYS || 1.3087 + (keep == PNG_HANDLE_CHUNK_IF_SAFE && 1.3088 + PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) 1.3089 + { 1.3090 +# ifdef PNG_USER_LIMITS_SUPPORTED 1.3091 + switch (png_ptr->user_chunk_cache_max) 1.3092 + { 1.3093 + case 2: 1.3094 + png_ptr->user_chunk_cache_max = 1; 1.3095 + png_chunk_benign_error(png_ptr, "no space in chunk cache"); 1.3096 + /* FALL THROUGH */ 1.3097 + case 1: 1.3098 + /* NOTE: prior to 1.6.0 this case resulted in an unknown critical 1.3099 + * chunk being skipped, now there will be a hard error below. 1.3100 + */ 1.3101 + break; 1.3102 + 1.3103 + default: /* not at limit */ 1.3104 + --(png_ptr->user_chunk_cache_max); 1.3105 + /* FALL THROUGH */ 1.3106 + case 0: /* no limit */ 1.3107 +# endif /* PNG_USER_LIMITS_SUPPORTED */ 1.3108 + /* Here when the limit isn't reached or when limits are compiled 1.3109 + * out; store the chunk. 1.3110 + */ 1.3111 + png_set_unknown_chunks(png_ptr, info_ptr, 1.3112 + &png_ptr->unknown_chunk, 1); 1.3113 + handled = 1; 1.3114 +# ifdef PNG_USER_LIMITS_SUPPORTED 1.3115 + break; 1.3116 + } 1.3117 +# endif 1.3118 + } 1.3119 +# else /* no store support: the chunk must be handled by the user callback */ 1.3120 + PNG_UNUSED(info_ptr) 1.3121 +# endif 1.3122 + 1.3123 + /* Regardless of the error handling below the cached data (if any) can be 1.3124 + * freed now. Notice that the data is not freed if there is a png_error, but 1.3125 + * it will be freed by destroy_read_struct. 1.3126 + */ 1.3127 + if (png_ptr->unknown_chunk.data != NULL) 1.3128 + png_free(png_ptr, png_ptr->unknown_chunk.data); 1.3129 + png_ptr->unknown_chunk.data = NULL; 1.3130 + 1.3131 +#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ 1.3132 + /* There is no support to read an unknown chunk, so just skip it. */ 1.3133 + png_crc_finish(png_ptr, length); 1.3134 + PNG_UNUSED(info_ptr) 1.3135 + PNG_UNUSED(keep) 1.3136 +#endif /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ 1.3137 + 1.3138 + /* Check for unhandled critical chunks */ 1.3139 + if (!handled && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) 1.3140 + png_chunk_error(png_ptr, "unhandled critical chunk"); 1.3141 +} 1.3142 + 1.3143 +/* This function is called to verify that a chunk name is valid. 1.3144 + * This function can't have the "critical chunk check" incorporated 1.3145 + * into it, since in the future we will need to be able to call user 1.3146 + * functions to handle unknown critical chunks after we check that 1.3147 + * the chunk name itself is valid. 1.3148 + */ 1.3149 + 1.3150 +/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: 1.3151 + * 1.3152 + * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 1.3153 + */ 1.3154 + 1.3155 +void /* PRIVATE */ 1.3156 +png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name) 1.3157 +{ 1.3158 + int i; 1.3159 + 1.3160 + png_debug(1, "in png_check_chunk_name"); 1.3161 + 1.3162 + for (i=1; i<=4; ++i) 1.3163 + { 1.3164 + int c = chunk_name & 0xff; 1.3165 + 1.3166 + if (c < 65 || c > 122 || (c > 90 && c < 97)) 1.3167 + png_chunk_error(png_ptr, "invalid chunk type"); 1.3168 + 1.3169 + chunk_name >>= 8; 1.3170 + } 1.3171 +} 1.3172 + 1.3173 +/* Combines the row recently read in with the existing pixels in the row. This 1.3174 + * routine takes care of alpha and transparency if requested. This routine also 1.3175 + * handles the two methods of progressive display of interlaced images, 1.3176 + * depending on the 'display' value; if 'display' is true then the whole row 1.3177 + * (dp) is filled from the start by replicating the available pixels. If 1.3178 + * 'display' is false only those pixels present in the pass are filled in. 1.3179 + */ 1.3180 +void /* PRIVATE */ 1.3181 +png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) 1.3182 +{ 1.3183 + unsigned int pixel_depth = png_ptr->transformed_pixel_depth; 1.3184 + png_const_bytep sp = png_ptr->row_buf + 1; 1.3185 + png_uint_32 row_width = png_ptr->width; 1.3186 + unsigned int pass = png_ptr->pass; 1.3187 + png_bytep end_ptr = 0; 1.3188 + png_byte end_byte = 0; 1.3189 + unsigned int end_mask; 1.3190 + 1.3191 + png_debug(1, "in png_combine_row"); 1.3192 + 1.3193 + /* Added in 1.5.6: it should not be possible to enter this routine until at 1.3194 + * least one row has been read from the PNG data and transformed. 1.3195 + */ 1.3196 + if (pixel_depth == 0) 1.3197 + png_error(png_ptr, "internal row logic error"); 1.3198 + 1.3199 + /* Added in 1.5.4: the pixel depth should match the information returned by 1.3200 + * any call to png_read_update_info at this point. Do not continue if we got 1.3201 + * this wrong. 1.3202 + */ 1.3203 + if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != 1.3204 + PNG_ROWBYTES(pixel_depth, row_width)) 1.3205 + png_error(png_ptr, "internal row size calculation error"); 1.3206 + 1.3207 + /* Don't expect this to ever happen: */ 1.3208 + if (row_width == 0) 1.3209 + png_error(png_ptr, "internal row width error"); 1.3210 + 1.3211 + /* Preserve the last byte in cases where only part of it will be overwritten, 1.3212 + * the multiply below may overflow, we don't care because ANSI-C guarantees 1.3213 + * we get the low bits. 1.3214 + */ 1.3215 + end_mask = (pixel_depth * row_width) & 7; 1.3216 + if (end_mask != 0) 1.3217 + { 1.3218 + /* end_ptr == NULL is a flag to say do nothing */ 1.3219 + end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; 1.3220 + end_byte = *end_ptr; 1.3221 +# ifdef PNG_READ_PACKSWAP_SUPPORTED 1.3222 + if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */ 1.3223 + end_mask = 0xff << end_mask; 1.3224 + 1.3225 + else /* big-endian byte */ 1.3226 +# endif 1.3227 + end_mask = 0xff >> end_mask; 1.3228 + /* end_mask is now the bits to *keep* from the destination row */ 1.3229 + } 1.3230 + 1.3231 + /* For non-interlaced images this reduces to a memcpy(). A memcpy() 1.3232 + * will also happen if interlacing isn't supported or if the application 1.3233 + * does not call png_set_interlace_handling(). In the latter cases the 1.3234 + * caller just gets a sequence of the unexpanded rows from each interlace 1.3235 + * pass. 1.3236 + */ 1.3237 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.3238 + if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) && 1.3239 + pass < 6 && (display == 0 || 1.3240 + /* The following copies everything for 'display' on passes 0, 2 and 4. */ 1.3241 + (display == 1 && (pass & 1) != 0))) 1.3242 + { 1.3243 + /* Narrow images may have no bits in a pass; the caller should handle 1.3244 + * this, but this test is cheap: 1.3245 + */ 1.3246 + if (row_width <= PNG_PASS_START_COL(pass)) 1.3247 + return; 1.3248 + 1.3249 + if (pixel_depth < 8) 1.3250 + { 1.3251 + /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit 1.3252 + * into 32 bits, then a single loop over the bytes using the four byte 1.3253 + * values in the 32-bit mask can be used. For the 'display' option the 1.3254 + * expanded mask may also not require any masking within a byte. To 1.3255 + * make this work the PACKSWAP option must be taken into account - it 1.3256 + * simply requires the pixels to be reversed in each byte. 1.3257 + * 1.3258 + * The 'regular' case requires a mask for each of the first 6 passes, 1.3259 + * the 'display' case does a copy for the even passes in the range 1.3260 + * 0..6. This has already been handled in the test above. 1.3261 + * 1.3262 + * The masks are arranged as four bytes with the first byte to use in 1.3263 + * the lowest bits (little-endian) regardless of the order (PACKSWAP or 1.3264 + * not) of the pixels in each byte. 1.3265 + * 1.3266 + * NOTE: the whole of this logic depends on the caller of this function 1.3267 + * only calling it on rows appropriate to the pass. This function only 1.3268 + * understands the 'x' logic; the 'y' logic is handled by the caller. 1.3269 + * 1.3270 + * The following defines allow generation of compile time constant bit 1.3271 + * masks for each pixel depth and each possibility of swapped or not 1.3272 + * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, 1.3273 + * is in the range 0..7; and the result is 1 if the pixel is to be 1.3274 + * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' 1.3275 + * for the block method. 1.3276 + * 1.3277 + * With some compilers a compile time expression of the general form: 1.3278 + * 1.3279 + * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) 1.3280 + * 1.3281 + * Produces warnings with values of 'shift' in the range 33 to 63 1.3282 + * because the right hand side of the ?: expression is evaluated by 1.3283 + * the compiler even though it isn't used. Microsoft Visual C (various 1.3284 + * versions) and the Intel C compiler are known to do this. To avoid 1.3285 + * this the following macros are used in 1.5.6. This is a temporary 1.3286 + * solution to avoid destabilizing the code during the release process. 1.3287 + */ 1.3288 +# if PNG_USE_COMPILE_TIME_MASKS 1.3289 +# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) 1.3290 +# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) 1.3291 +# else 1.3292 +# define PNG_LSR(x,s) ((x)>>(s)) 1.3293 +# define PNG_LSL(x,s) ((x)<<(s)) 1.3294 +# endif 1.3295 +# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ 1.3296 + PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) 1.3297 +# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ 1.3298 + PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) 1.3299 + 1.3300 + /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is 1.3301 + * little endian - the first pixel is at bit 0 - however the extra 1.3302 + * parameter 's' can be set to cause the mask position to be swapped 1.3303 + * within each byte, to match the PNG format. This is done by XOR of 1.3304 + * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. 1.3305 + */ 1.3306 +# define PIXEL_MASK(p,x,d,s) \ 1.3307 + (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) 1.3308 + 1.3309 + /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. 1.3310 + */ 1.3311 +# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) 1.3312 +# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) 1.3313 + 1.3314 + /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp 1.3315 + * cases the result needs replicating, for the 4-bpp case the above 1.3316 + * generates a full 32 bits. 1.3317 + */ 1.3318 +# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) 1.3319 + 1.3320 +# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ 1.3321 + S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ 1.3322 + S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) 1.3323 + 1.3324 +# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ 1.3325 + B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ 1.3326 + B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) 1.3327 + 1.3328 +#if PNG_USE_COMPILE_TIME_MASKS 1.3329 + /* Utility macros to construct all the masks for a depth/swap 1.3330 + * combination. The 's' parameter says whether the format is PNG 1.3331 + * (big endian bytes) or not. Only the three odd-numbered passes are 1.3332 + * required for the display/block algorithm. 1.3333 + */ 1.3334 +# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ 1.3335 + S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } 1.3336 + 1.3337 +# define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) } 1.3338 + 1.3339 +# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) 1.3340 + 1.3341 + /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and 1.3342 + * then pass: 1.3343 + */ 1.3344 + static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = 1.3345 + { 1.3346 + /* Little-endian byte masks for PACKSWAP */ 1.3347 + { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, 1.3348 + /* Normal (big-endian byte) masks - PNG format */ 1.3349 + { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } 1.3350 + }; 1.3351 + 1.3352 + /* display_mask has only three entries for the odd passes, so index by 1.3353 + * pass>>1. 1.3354 + */ 1.3355 + static PNG_CONST png_uint_32 display_mask[2][3][3] = 1.3356 + { 1.3357 + /* Little-endian byte masks for PACKSWAP */ 1.3358 + { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, 1.3359 + /* Normal (big-endian byte) masks - PNG format */ 1.3360 + { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } 1.3361 + }; 1.3362 + 1.3363 +# define MASK(pass,depth,display,png)\ 1.3364 + ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ 1.3365 + row_mask[png][DEPTH_INDEX(depth)][pass]) 1.3366 + 1.3367 +#else /* !PNG_USE_COMPILE_TIME_MASKS */ 1.3368 + /* This is the runtime alternative: it seems unlikely that this will 1.3369 + * ever be either smaller or faster than the compile time approach. 1.3370 + */ 1.3371 +# define MASK(pass,depth,display,png)\ 1.3372 + ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) 1.3373 +#endif /* !PNG_USE_COMPILE_TIME_MASKS */ 1.3374 + 1.3375 + /* Use the appropriate mask to copy the required bits. In some cases 1.3376 + * the byte mask will be 0 or 0xff, optimize these cases. row_width is 1.3377 + * the number of pixels, but the code copies bytes, so it is necessary 1.3378 + * to special case the end. 1.3379 + */ 1.3380 + png_uint_32 pixels_per_byte = 8 / pixel_depth; 1.3381 + png_uint_32 mask; 1.3382 + 1.3383 +# ifdef PNG_READ_PACKSWAP_SUPPORTED 1.3384 + if (png_ptr->transformations & PNG_PACKSWAP) 1.3385 + mask = MASK(pass, pixel_depth, display, 0); 1.3386 + 1.3387 + else 1.3388 +# endif 1.3389 + mask = MASK(pass, pixel_depth, display, 1); 1.3390 + 1.3391 + for (;;) 1.3392 + { 1.3393 + png_uint_32 m; 1.3394 + 1.3395 + /* It doesn't matter in the following if png_uint_32 has more than 1.3396 + * 32 bits because the high bits always match those in m<<24; it is, 1.3397 + * however, essential to use OR here, not +, because of this. 1.3398 + */ 1.3399 + m = mask; 1.3400 + mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ 1.3401 + m &= 0xff; 1.3402 + 1.3403 + if (m != 0) /* something to copy */ 1.3404 + { 1.3405 + if (m != 0xff) 1.3406 + *dp = (png_byte)((*dp & ~m) | (*sp & m)); 1.3407 + else 1.3408 + *dp = *sp; 1.3409 + } 1.3410 + 1.3411 + /* NOTE: this may overwrite the last byte with garbage if the image 1.3412 + * is not an exact number of bytes wide; libpng has always done 1.3413 + * this. 1.3414 + */ 1.3415 + if (row_width <= pixels_per_byte) 1.3416 + break; /* May need to restore part of the last byte */ 1.3417 + 1.3418 + row_width -= pixels_per_byte; 1.3419 + ++dp; 1.3420 + ++sp; 1.3421 + } 1.3422 + } 1.3423 + 1.3424 + else /* pixel_depth >= 8 */ 1.3425 + { 1.3426 + unsigned int bytes_to_copy, bytes_to_jump; 1.3427 + 1.3428 + /* Validate the depth - it must be a multiple of 8 */ 1.3429 + if (pixel_depth & 7) 1.3430 + png_error(png_ptr, "invalid user transform pixel depth"); 1.3431 + 1.3432 + pixel_depth >>= 3; /* now in bytes */ 1.3433 + row_width *= pixel_depth; 1.3434 + 1.3435 + /* Regardless of pass number the Adam 7 interlace always results in a 1.3436 + * fixed number of pixels to copy then to skip. There may be a 1.3437 + * different number of pixels to skip at the start though. 1.3438 + */ 1.3439 + { 1.3440 + unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; 1.3441 + 1.3442 + row_width -= offset; 1.3443 + dp += offset; 1.3444 + sp += offset; 1.3445 + } 1.3446 + 1.3447 + /* Work out the bytes to copy. */ 1.3448 + if (display) 1.3449 + { 1.3450 + /* When doing the 'block' algorithm the pixel in the pass gets 1.3451 + * replicated to adjacent pixels. This is why the even (0,2,4,6) 1.3452 + * passes are skipped above - the entire expanded row is copied. 1.3453 + */ 1.3454 + bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; 1.3455 + 1.3456 + /* But don't allow this number to exceed the actual row width. */ 1.3457 + if (bytes_to_copy > row_width) 1.3458 + bytes_to_copy = row_width; 1.3459 + } 1.3460 + 1.3461 + else /* normal row; Adam7 only ever gives us one pixel to copy. */ 1.3462 + bytes_to_copy = pixel_depth; 1.3463 + 1.3464 + /* In Adam7 there is a constant offset between where the pixels go. */ 1.3465 + bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; 1.3466 + 1.3467 + /* And simply copy these bytes. Some optimization is possible here, 1.3468 + * depending on the value of 'bytes_to_copy'. Special case the low 1.3469 + * byte counts, which we know to be frequent. 1.3470 + * 1.3471 + * Notice that these cases all 'return' rather than 'break' - this 1.3472 + * avoids an unnecessary test on whether to restore the last byte 1.3473 + * below. 1.3474 + */ 1.3475 + switch (bytes_to_copy) 1.3476 + { 1.3477 + case 1: 1.3478 + for (;;) 1.3479 + { 1.3480 + *dp = *sp; 1.3481 + 1.3482 + if (row_width <= bytes_to_jump) 1.3483 + return; 1.3484 + 1.3485 + dp += bytes_to_jump; 1.3486 + sp += bytes_to_jump; 1.3487 + row_width -= bytes_to_jump; 1.3488 + } 1.3489 + 1.3490 + case 2: 1.3491 + /* There is a possibility of a partial copy at the end here; this 1.3492 + * slows the code down somewhat. 1.3493 + */ 1.3494 + do 1.3495 + { 1.3496 + dp[0] = sp[0], dp[1] = sp[1]; 1.3497 + 1.3498 + if (row_width <= bytes_to_jump) 1.3499 + return; 1.3500 + 1.3501 + sp += bytes_to_jump; 1.3502 + dp += bytes_to_jump; 1.3503 + row_width -= bytes_to_jump; 1.3504 + } 1.3505 + while (row_width > 1); 1.3506 + 1.3507 + /* And there can only be one byte left at this point: */ 1.3508 + *dp = *sp; 1.3509 + return; 1.3510 + 1.3511 + case 3: 1.3512 + /* This can only be the RGB case, so each copy is exactly one 1.3513 + * pixel and it is not necessary to check for a partial copy. 1.3514 + */ 1.3515 + for(;;) 1.3516 + { 1.3517 + dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; 1.3518 + 1.3519 + if (row_width <= bytes_to_jump) 1.3520 + return; 1.3521 + 1.3522 + sp += bytes_to_jump; 1.3523 + dp += bytes_to_jump; 1.3524 + row_width -= bytes_to_jump; 1.3525 + } 1.3526 + 1.3527 + default: 1.3528 +#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE 1.3529 + /* Check for double byte alignment and, if possible, use a 1.3530 + * 16-bit copy. Don't attempt this for narrow images - ones that 1.3531 + * are less than an interlace panel wide. Don't attempt it for 1.3532 + * wide bytes_to_copy either - use the memcpy there. 1.3533 + */ 1.3534 + if (bytes_to_copy < 16 /*else use memcpy*/ && 1.3535 + png_isaligned(dp, png_uint_16) && 1.3536 + png_isaligned(sp, png_uint_16) && 1.3537 + bytes_to_copy % (sizeof (png_uint_16)) == 0 && 1.3538 + bytes_to_jump % (sizeof (png_uint_16)) == 0) 1.3539 + { 1.3540 + /* Everything is aligned for png_uint_16 copies, but try for 1.3541 + * png_uint_32 first. 1.3542 + */ 1.3543 + if (png_isaligned(dp, png_uint_32) && 1.3544 + png_isaligned(sp, png_uint_32) && 1.3545 + bytes_to_copy % (sizeof (png_uint_32)) == 0 && 1.3546 + bytes_to_jump % (sizeof (png_uint_32)) == 0) 1.3547 + { 1.3548 + png_uint_32p dp32 = png_aligncast(png_uint_32p,dp); 1.3549 + png_const_uint_32p sp32 = png_aligncastconst( 1.3550 + png_const_uint_32p, sp); 1.3551 + size_t skip = (bytes_to_jump-bytes_to_copy) / 1.3552 + (sizeof (png_uint_32)); 1.3553 + 1.3554 + do 1.3555 + { 1.3556 + size_t c = bytes_to_copy; 1.3557 + do 1.3558 + { 1.3559 + *dp32++ = *sp32++; 1.3560 + c -= (sizeof (png_uint_32)); 1.3561 + } 1.3562 + while (c > 0); 1.3563 + 1.3564 + if (row_width <= bytes_to_jump) 1.3565 + return; 1.3566 + 1.3567 + dp32 += skip; 1.3568 + sp32 += skip; 1.3569 + row_width -= bytes_to_jump; 1.3570 + } 1.3571 + while (bytes_to_copy <= row_width); 1.3572 + 1.3573 + /* Get to here when the row_width truncates the final copy. 1.3574 + * There will be 1-3 bytes left to copy, so don't try the 1.3575 + * 16-bit loop below. 1.3576 + */ 1.3577 + dp = (png_bytep)dp32; 1.3578 + sp = (png_const_bytep)sp32; 1.3579 + do 1.3580 + *dp++ = *sp++; 1.3581 + while (--row_width > 0); 1.3582 + return; 1.3583 + } 1.3584 + 1.3585 + /* Else do it in 16-bit quantities, but only if the size is 1.3586 + * not too large. 1.3587 + */ 1.3588 + else 1.3589 + { 1.3590 + png_uint_16p dp16 = png_aligncast(png_uint_16p, dp); 1.3591 + png_const_uint_16p sp16 = png_aligncastconst( 1.3592 + png_const_uint_16p, sp); 1.3593 + size_t skip = (bytes_to_jump-bytes_to_copy) / 1.3594 + (sizeof (png_uint_16)); 1.3595 + 1.3596 + do 1.3597 + { 1.3598 + size_t c = bytes_to_copy; 1.3599 + do 1.3600 + { 1.3601 + *dp16++ = *sp16++; 1.3602 + c -= (sizeof (png_uint_16)); 1.3603 + } 1.3604 + while (c > 0); 1.3605 + 1.3606 + if (row_width <= bytes_to_jump) 1.3607 + return; 1.3608 + 1.3609 + dp16 += skip; 1.3610 + sp16 += skip; 1.3611 + row_width -= bytes_to_jump; 1.3612 + } 1.3613 + while (bytes_to_copy <= row_width); 1.3614 + 1.3615 + /* End of row - 1 byte left, bytes_to_copy > row_width: */ 1.3616 + dp = (png_bytep)dp16; 1.3617 + sp = (png_const_bytep)sp16; 1.3618 + do 1.3619 + *dp++ = *sp++; 1.3620 + while (--row_width > 0); 1.3621 + return; 1.3622 + } 1.3623 + } 1.3624 +#endif /* PNG_ALIGN_ code */ 1.3625 + 1.3626 + /* The true default - use a memcpy: */ 1.3627 + for (;;) 1.3628 + { 1.3629 + memcpy(dp, sp, bytes_to_copy); 1.3630 + 1.3631 + if (row_width <= bytes_to_jump) 1.3632 + return; 1.3633 + 1.3634 + sp += bytes_to_jump; 1.3635 + dp += bytes_to_jump; 1.3636 + row_width -= bytes_to_jump; 1.3637 + if (bytes_to_copy > row_width) 1.3638 + bytes_to_copy = row_width; 1.3639 + } 1.3640 + } 1.3641 + 1.3642 + /* NOT REACHED*/ 1.3643 + } /* pixel_depth >= 8 */ 1.3644 + 1.3645 + /* Here if pixel_depth < 8 to check 'end_ptr' below. */ 1.3646 + } 1.3647 + else 1.3648 +#endif 1.3649 + 1.3650 + /* If here then the switch above wasn't used so just memcpy the whole row 1.3651 + * from the temporary row buffer (notice that this overwrites the end of the 1.3652 + * destination row if it is a partial byte.) 1.3653 + */ 1.3654 + memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); 1.3655 + 1.3656 + /* Restore the overwritten bits from the last byte if necessary. */ 1.3657 + if (end_ptr != NULL) 1.3658 + *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); 1.3659 +} 1.3660 + 1.3661 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.3662 +void /* PRIVATE */ 1.3663 +png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 1.3664 + png_uint_32 transformations /* Because these may affect the byte layout */) 1.3665 +{ 1.3666 + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1.3667 + /* Offset to next interlace block */ 1.3668 + static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 1.3669 + 1.3670 + png_debug(1, "in png_do_read_interlace"); 1.3671 + if (row != NULL && row_info != NULL) 1.3672 + { 1.3673 + png_uint_32 final_width; 1.3674 + 1.3675 + final_width = row_info->width * png_pass_inc[pass]; 1.3676 + 1.3677 + switch (row_info->pixel_depth) 1.3678 + { 1.3679 + case 1: 1.3680 + { 1.3681 + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 1.3682 + png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 1.3683 + int sshift, dshift; 1.3684 + int s_start, s_end, s_inc; 1.3685 + int jstop = png_pass_inc[pass]; 1.3686 + png_byte v; 1.3687 + png_uint_32 i; 1.3688 + int j; 1.3689 + 1.3690 +#ifdef PNG_READ_PACKSWAP_SUPPORTED 1.3691 + if (transformations & PNG_PACKSWAP) 1.3692 + { 1.3693 + sshift = (int)((row_info->width + 7) & 0x07); 1.3694 + dshift = (int)((final_width + 7) & 0x07); 1.3695 + s_start = 7; 1.3696 + s_end = 0; 1.3697 + s_inc = -1; 1.3698 + } 1.3699 + 1.3700 + else 1.3701 +#endif 1.3702 + { 1.3703 + sshift = 7 - (int)((row_info->width + 7) & 0x07); 1.3704 + dshift = 7 - (int)((final_width + 7) & 0x07); 1.3705 + s_start = 0; 1.3706 + s_end = 7; 1.3707 + s_inc = 1; 1.3708 + } 1.3709 + 1.3710 + for (i = 0; i < row_info->width; i++) 1.3711 + { 1.3712 + v = (png_byte)((*sp >> sshift) & 0x01); 1.3713 + for (j = 0; j < jstop; j++) 1.3714 + { 1.3715 + unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); 1.3716 + tmp |= v << dshift; 1.3717 + *dp = (png_byte)(tmp & 0xff); 1.3718 + 1.3719 + if (dshift == s_end) 1.3720 + { 1.3721 + dshift = s_start; 1.3722 + dp--; 1.3723 + } 1.3724 + 1.3725 + else 1.3726 + dshift += s_inc; 1.3727 + } 1.3728 + 1.3729 + if (sshift == s_end) 1.3730 + { 1.3731 + sshift = s_start; 1.3732 + sp--; 1.3733 + } 1.3734 + 1.3735 + else 1.3736 + sshift += s_inc; 1.3737 + } 1.3738 + break; 1.3739 + } 1.3740 + 1.3741 + case 2: 1.3742 + { 1.3743 + png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 1.3744 + png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 1.3745 + int sshift, dshift; 1.3746 + int s_start, s_end, s_inc; 1.3747 + int jstop = png_pass_inc[pass]; 1.3748 + png_uint_32 i; 1.3749 + 1.3750 +#ifdef PNG_READ_PACKSWAP_SUPPORTED 1.3751 + if (transformations & PNG_PACKSWAP) 1.3752 + { 1.3753 + sshift = (int)(((row_info->width + 3) & 0x03) << 1); 1.3754 + dshift = (int)(((final_width + 3) & 0x03) << 1); 1.3755 + s_start = 6; 1.3756 + s_end = 0; 1.3757 + s_inc = -2; 1.3758 + } 1.3759 + 1.3760 + else 1.3761 +#endif 1.3762 + { 1.3763 + sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 1.3764 + dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 1.3765 + s_start = 0; 1.3766 + s_end = 6; 1.3767 + s_inc = 2; 1.3768 + } 1.3769 + 1.3770 + for (i = 0; i < row_info->width; i++) 1.3771 + { 1.3772 + png_byte v; 1.3773 + int j; 1.3774 + 1.3775 + v = (png_byte)((*sp >> sshift) & 0x03); 1.3776 + for (j = 0; j < jstop; j++) 1.3777 + { 1.3778 + unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); 1.3779 + tmp |= v << dshift; 1.3780 + *dp = (png_byte)(tmp & 0xff); 1.3781 + 1.3782 + if (dshift == s_end) 1.3783 + { 1.3784 + dshift = s_start; 1.3785 + dp--; 1.3786 + } 1.3787 + 1.3788 + else 1.3789 + dshift += s_inc; 1.3790 + } 1.3791 + 1.3792 + if (sshift == s_end) 1.3793 + { 1.3794 + sshift = s_start; 1.3795 + sp--; 1.3796 + } 1.3797 + 1.3798 + else 1.3799 + sshift += s_inc; 1.3800 + } 1.3801 + break; 1.3802 + } 1.3803 + 1.3804 + case 4: 1.3805 + { 1.3806 + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 1.3807 + png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 1.3808 + int sshift, dshift; 1.3809 + int s_start, s_end, s_inc; 1.3810 + png_uint_32 i; 1.3811 + int jstop = png_pass_inc[pass]; 1.3812 + 1.3813 +#ifdef PNG_READ_PACKSWAP_SUPPORTED 1.3814 + if (transformations & PNG_PACKSWAP) 1.3815 + { 1.3816 + sshift = (int)(((row_info->width + 1) & 0x01) << 2); 1.3817 + dshift = (int)(((final_width + 1) & 0x01) << 2); 1.3818 + s_start = 4; 1.3819 + s_end = 0; 1.3820 + s_inc = -4; 1.3821 + } 1.3822 + 1.3823 + else 1.3824 +#endif 1.3825 + { 1.3826 + sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 1.3827 + dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 1.3828 + s_start = 0; 1.3829 + s_end = 4; 1.3830 + s_inc = 4; 1.3831 + } 1.3832 + 1.3833 + for (i = 0; i < row_info->width; i++) 1.3834 + { 1.3835 + png_byte v = (png_byte)((*sp >> sshift) & 0x0f); 1.3836 + int j; 1.3837 + 1.3838 + for (j = 0; j < jstop; j++) 1.3839 + { 1.3840 + unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); 1.3841 + tmp |= v << dshift; 1.3842 + *dp = (png_byte)(tmp & 0xff); 1.3843 + 1.3844 + if (dshift == s_end) 1.3845 + { 1.3846 + dshift = s_start; 1.3847 + dp--; 1.3848 + } 1.3849 + 1.3850 + else 1.3851 + dshift += s_inc; 1.3852 + } 1.3853 + 1.3854 + if (sshift == s_end) 1.3855 + { 1.3856 + sshift = s_start; 1.3857 + sp--; 1.3858 + } 1.3859 + 1.3860 + else 1.3861 + sshift += s_inc; 1.3862 + } 1.3863 + break; 1.3864 + } 1.3865 + 1.3866 + default: 1.3867 + { 1.3868 + png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 1.3869 + 1.3870 + png_bytep sp = row + (png_size_t)(row_info->width - 1) 1.3871 + * pixel_bytes; 1.3872 + 1.3873 + png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 1.3874 + 1.3875 + int jstop = png_pass_inc[pass]; 1.3876 + png_uint_32 i; 1.3877 + 1.3878 + for (i = 0; i < row_info->width; i++) 1.3879 + { 1.3880 + png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */ 1.3881 + int j; 1.3882 + 1.3883 + memcpy(v, sp, pixel_bytes); 1.3884 + 1.3885 + for (j = 0; j < jstop; j++) 1.3886 + { 1.3887 + memcpy(dp, v, pixel_bytes); 1.3888 + dp -= pixel_bytes; 1.3889 + } 1.3890 + 1.3891 + sp -= pixel_bytes; 1.3892 + } 1.3893 + break; 1.3894 + } 1.3895 + } 1.3896 + 1.3897 + row_info->width = final_width; 1.3898 + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); 1.3899 + } 1.3900 +#ifndef PNG_READ_PACKSWAP_SUPPORTED 1.3901 + PNG_UNUSED(transformations) /* Silence compiler warning */ 1.3902 +#endif 1.3903 +} 1.3904 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.3905 + 1.3906 +static void 1.3907 +png_read_filter_row_sub(png_row_infop row_info, png_bytep row, 1.3908 + png_const_bytep prev_row) 1.3909 +{ 1.3910 + png_size_t i; 1.3911 + png_size_t istop = row_info->rowbytes; 1.3912 + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; 1.3913 + png_bytep rp = row + bpp; 1.3914 + 1.3915 + PNG_UNUSED(prev_row) 1.3916 + 1.3917 + for (i = bpp; i < istop; i++) 1.3918 + { 1.3919 + *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); 1.3920 + rp++; 1.3921 + } 1.3922 +} 1.3923 + 1.3924 +static void 1.3925 +png_read_filter_row_up(png_row_infop row_info, png_bytep row, 1.3926 + png_const_bytep prev_row) 1.3927 +{ 1.3928 + png_size_t i; 1.3929 + png_size_t istop = row_info->rowbytes; 1.3930 + png_bytep rp = row; 1.3931 + png_const_bytep pp = prev_row; 1.3932 + 1.3933 + for (i = 0; i < istop; i++) 1.3934 + { 1.3935 + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 1.3936 + rp++; 1.3937 + } 1.3938 +} 1.3939 + 1.3940 +static void 1.3941 +png_read_filter_row_avg(png_row_infop row_info, png_bytep row, 1.3942 + png_const_bytep prev_row) 1.3943 +{ 1.3944 + png_size_t i; 1.3945 + png_bytep rp = row; 1.3946 + png_const_bytep pp = prev_row; 1.3947 + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; 1.3948 + png_size_t istop = row_info->rowbytes - bpp; 1.3949 + 1.3950 + for (i = 0; i < bpp; i++) 1.3951 + { 1.3952 + *rp = (png_byte)(((int)(*rp) + 1.3953 + ((int)(*pp++) / 2 )) & 0xff); 1.3954 + 1.3955 + rp++; 1.3956 + } 1.3957 + 1.3958 + for (i = 0; i < istop; i++) 1.3959 + { 1.3960 + *rp = (png_byte)(((int)(*rp) + 1.3961 + (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); 1.3962 + 1.3963 + rp++; 1.3964 + } 1.3965 +} 1.3966 + 1.3967 +static void 1.3968 +png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, 1.3969 + png_const_bytep prev_row) 1.3970 +{ 1.3971 + png_bytep rp_end = row + row_info->rowbytes; 1.3972 + int a, c; 1.3973 + 1.3974 + /* First pixel/byte */ 1.3975 + c = *prev_row++; 1.3976 + a = *row + c; 1.3977 + *row++ = (png_byte)a; 1.3978 + 1.3979 + /* Remainder */ 1.3980 + while (row < rp_end) 1.3981 + { 1.3982 + int b, pa, pb, pc, p; 1.3983 + 1.3984 + a &= 0xff; /* From previous iteration or start */ 1.3985 + b = *prev_row++; 1.3986 + 1.3987 + p = b - c; 1.3988 + pc = a - c; 1.3989 + 1.3990 +# ifdef PNG_USE_ABS 1.3991 + pa = abs(p); 1.3992 + pb = abs(pc); 1.3993 + pc = abs(p + pc); 1.3994 +# else 1.3995 + pa = p < 0 ? -p : p; 1.3996 + pb = pc < 0 ? -pc : pc; 1.3997 + pc = (p + pc) < 0 ? -(p + pc) : p + pc; 1.3998 +# endif 1.3999 + 1.4000 + /* Find the best predictor, the least of pa, pb, pc favoring the earlier 1.4001 + * ones in the case of a tie. 1.4002 + */ 1.4003 + if (pb < pa) pa = pb, a = b; 1.4004 + if (pc < pa) a = c; 1.4005 + 1.4006 + /* Calculate the current pixel in a, and move the previous row pixel to c 1.4007 + * for the next time round the loop 1.4008 + */ 1.4009 + c = b; 1.4010 + a += *row; 1.4011 + *row++ = (png_byte)a; 1.4012 + } 1.4013 +} 1.4014 + 1.4015 +static void 1.4016 +png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, 1.4017 + png_const_bytep prev_row) 1.4018 +{ 1.4019 + int bpp = (row_info->pixel_depth + 7) >> 3; 1.4020 + png_bytep rp_end = row + bpp; 1.4021 + 1.4022 + /* Process the first pixel in the row completely (this is the same as 'up' 1.4023 + * because there is only one candidate predictor for the first row). 1.4024 + */ 1.4025 + while (row < rp_end) 1.4026 + { 1.4027 + int a = *row + *prev_row++; 1.4028 + *row++ = (png_byte)a; 1.4029 + } 1.4030 + 1.4031 + /* Remainder */ 1.4032 + rp_end += row_info->rowbytes - bpp; 1.4033 + 1.4034 + while (row < rp_end) 1.4035 + { 1.4036 + int a, b, c, pa, pb, pc, p; 1.4037 + 1.4038 + c = *(prev_row - bpp); 1.4039 + a = *(row - bpp); 1.4040 + b = *prev_row++; 1.4041 + 1.4042 + p = b - c; 1.4043 + pc = a - c; 1.4044 + 1.4045 +# ifdef PNG_USE_ABS 1.4046 + pa = abs(p); 1.4047 + pb = abs(pc); 1.4048 + pc = abs(p + pc); 1.4049 +# else 1.4050 + pa = p < 0 ? -p : p; 1.4051 + pb = pc < 0 ? -pc : pc; 1.4052 + pc = (p + pc) < 0 ? -(p + pc) : p + pc; 1.4053 +# endif 1.4054 + 1.4055 + if (pb < pa) pa = pb, a = b; 1.4056 + if (pc < pa) a = c; 1.4057 + 1.4058 + a += *row; 1.4059 + *row++ = (png_byte)a; 1.4060 + } 1.4061 +} 1.4062 + 1.4063 +static void 1.4064 +png_init_filter_functions(png_structrp pp) 1.4065 + /* This function is called once for every PNG image (except for PNG images 1.4066 + * that only use PNG_FILTER_VALUE_NONE for all rows) to set the 1.4067 + * implementations required to reverse the filtering of PNG rows. Reversing 1.4068 + * the filter is the first transformation performed on the row data. It is 1.4069 + * performed in place, therefore an implementation can be selected based on 1.4070 + * the image pixel format. If the implementation depends on image width then 1.4071 + * take care to ensure that it works correctly if the image is interlaced - 1.4072 + * interlacing causes the actual row width to vary. 1.4073 + */ 1.4074 +{ 1.4075 + unsigned int bpp = (pp->pixel_depth + 7) >> 3; 1.4076 + 1.4077 + pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; 1.4078 + pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; 1.4079 + pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; 1.4080 + if (bpp == 1) 1.4081 + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 1.4082 + png_read_filter_row_paeth_1byte_pixel; 1.4083 + else 1.4084 + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 1.4085 + png_read_filter_row_paeth_multibyte_pixel; 1.4086 + 1.4087 +#ifdef PNG_FILTER_OPTIMIZATIONS 1.4088 + /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to 1.4089 + * call to install hardware optimizations for the above functions; simply 1.4090 + * replace whatever elements of the pp->read_filter[] array with a hardware 1.4091 + * specific (or, for that matter, generic) optimization. 1.4092 + * 1.4093 + * To see an example of this examine what configure.ac does when 1.4094 + * --enable-arm-neon is specified on the command line. 1.4095 + */ 1.4096 + PNG_FILTER_OPTIMIZATIONS(pp, bpp); 1.4097 +#endif 1.4098 +} 1.4099 + 1.4100 +void /* PRIVATE */ 1.4101 +png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, 1.4102 + png_const_bytep prev_row, int filter) 1.4103 +{ 1.4104 + /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define 1.4105 + * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic 1.4106 + * implementations. See png_init_filter_functions above. 1.4107 + */ 1.4108 + if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) 1.4109 + { 1.4110 + if (pp->read_filter[0] == NULL) 1.4111 + png_init_filter_functions(pp); 1.4112 + 1.4113 + pp->read_filter[filter-1](row_info, row, prev_row); 1.4114 + } 1.4115 +} 1.4116 + 1.4117 +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 1.4118 +void /* PRIVATE */ 1.4119 +png_read_IDAT_data(png_structrp png_ptr, png_bytep output, 1.4120 + png_alloc_size_t avail_out) 1.4121 +{ 1.4122 + /* Loop reading IDATs and decompressing the result into output[avail_out] */ 1.4123 + png_ptr->zstream.next_out = output; 1.4124 + png_ptr->zstream.avail_out = 0; /* safety: set below */ 1.4125 + 1.4126 + if (output == NULL) 1.4127 + avail_out = 0; 1.4128 + 1.4129 + do 1.4130 + { 1.4131 + int ret; 1.4132 + png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; 1.4133 + 1.4134 + if (png_ptr->zstream.avail_in == 0) 1.4135 + { 1.4136 + uInt avail_in; 1.4137 + png_bytep buffer; 1.4138 + 1.4139 +#ifdef PNG_READ_APNG_SUPPORTED 1.4140 + png_uint_32 bytes_to_skip = 0; 1.4141 + 1.4142 + while (png_ptr->idat_size == 0 || bytes_to_skip != 0) 1.4143 + { 1.4144 + png_crc_finish(png_ptr, bytes_to_skip); 1.4145 + bytes_to_skip = 0; 1.4146 + 1.4147 + png_ptr->idat_size = png_read_chunk_header(png_ptr); 1.4148 + if (png_ptr->num_frames_read == 0) 1.4149 + { 1.4150 + if (png_ptr->chunk_name != png_IDAT) 1.4151 + png_error(png_ptr, "Not enough image data"); 1.4152 + } 1.4153 + else 1.4154 + { 1.4155 + if (png_ptr->chunk_name == png_IEND) 1.4156 + png_error(png_ptr, "Not enough image data"); 1.4157 + if (png_ptr->chunk_name != png_fdAT) 1.4158 + { 1.4159 + png_warning(png_ptr, "Skipped (ignored) a chunk " 1.4160 + "between APNG chunks"); 1.4161 + bytes_to_skip = png_ptr->idat_size; 1.4162 + continue; 1.4163 + } 1.4164 + 1.4165 + png_ensure_sequence_number(png_ptr, png_ptr->idat_size); 1.4166 + 1.4167 + png_ptr->idat_size -= 4; 1.4168 + } 1.4169 + } 1.4170 +#else 1.4171 + while (png_ptr->idat_size == 0) 1.4172 + { 1.4173 + png_crc_finish(png_ptr, 0); 1.4174 + 1.4175 + png_ptr->idat_size = png_read_chunk_header(png_ptr); 1.4176 + /* This is an error even in the 'check' case because the code just 1.4177 + * consumed a non-IDAT header. 1.4178 + */ 1.4179 + if (png_ptr->chunk_name != png_IDAT) 1.4180 + png_error(png_ptr, "Not enough image data"); 1.4181 + } 1.4182 +#endif /* PNG_READ_APNG_SUPPORTED */ 1.4183 + 1.4184 + avail_in = png_ptr->IDAT_read_size; 1.4185 + 1.4186 + if (avail_in > png_ptr->idat_size) 1.4187 + avail_in = (uInt)png_ptr->idat_size; 1.4188 + 1.4189 + /* A PNG with a gradually increasing IDAT size will defeat this attempt 1.4190 + * to minimize memory usage by causing lots of re-allocs, but 1.4191 + * realistically doing IDAT_read_size re-allocs is not likely to be a 1.4192 + * big problem. 1.4193 + */ 1.4194 + buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); 1.4195 + 1.4196 + png_crc_read(png_ptr, buffer, avail_in); 1.4197 + png_ptr->idat_size -= avail_in; 1.4198 + 1.4199 + png_ptr->zstream.next_in = buffer; 1.4200 + png_ptr->zstream.avail_in = avail_in; 1.4201 + } 1.4202 + 1.4203 + /* And set up the output side. */ 1.4204 + if (output != NULL) /* standard read */ 1.4205 + { 1.4206 + uInt out = ZLIB_IO_MAX; 1.4207 + 1.4208 + if (out > avail_out) 1.4209 + out = (uInt)avail_out; 1.4210 + 1.4211 + avail_out -= out; 1.4212 + png_ptr->zstream.avail_out = out; 1.4213 + } 1.4214 + 1.4215 + else /* after last row, checking for end */ 1.4216 + { 1.4217 + png_ptr->zstream.next_out = tmpbuf; 1.4218 + png_ptr->zstream.avail_out = (sizeof tmpbuf); 1.4219 + } 1.4220 + 1.4221 + /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the 1.4222 + * process. If the LZ stream is truncated the sequential reader will 1.4223 + * terminally damage the stream, above, by reading the chunk header of the 1.4224 + * following chunk (it then exits with png_error). 1.4225 + * 1.4226 + * TODO: deal more elegantly with truncated IDAT lists. 1.4227 + */ 1.4228 + ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); 1.4229 + 1.4230 + /* Take the unconsumed output back. */ 1.4231 + if (output != NULL) 1.4232 + avail_out += png_ptr->zstream.avail_out; 1.4233 + 1.4234 + else /* avail_out counts the extra bytes */ 1.4235 + avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; 1.4236 + 1.4237 + png_ptr->zstream.avail_out = 0; 1.4238 + 1.4239 + if (ret == Z_STREAM_END) 1.4240 + { 1.4241 + /* Do this for safety; we won't read any more into this row. */ 1.4242 + png_ptr->zstream.next_out = NULL; 1.4243 + 1.4244 + png_ptr->mode |= PNG_AFTER_IDAT; 1.4245 + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 1.4246 +#ifdef PNG_READ_APNG_SUPPORTED 1.4247 + png_ptr->num_frames_read++; 1.4248 +#endif 1.4249 + 1.4250 + if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) 1.4251 + png_chunk_benign_error(png_ptr, "Extra compressed data"); 1.4252 + break; 1.4253 + } 1.4254 + 1.4255 + if (ret != Z_OK) 1.4256 + { 1.4257 + png_zstream_error(png_ptr, ret); 1.4258 + 1.4259 + if (output != NULL) 1.4260 + png_chunk_error(png_ptr, png_ptr->zstream.msg); 1.4261 + 1.4262 + else /* checking */ 1.4263 + { 1.4264 + png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); 1.4265 + return; 1.4266 + } 1.4267 + } 1.4268 + } while (avail_out > 0); 1.4269 + 1.4270 + if (avail_out > 0) 1.4271 + { 1.4272 + /* The stream ended before the image; this is the same as too few IDATs so 1.4273 + * should be handled the same way. 1.4274 + */ 1.4275 + if (output != NULL) 1.4276 + png_error(png_ptr, "Not enough image data"); 1.4277 + 1.4278 + else /* the deflate stream contained extra data */ 1.4279 + png_chunk_benign_error(png_ptr, "Too much image data"); 1.4280 + } 1.4281 +} 1.4282 + 1.4283 +void /* PRIVATE */ 1.4284 +png_read_finish_IDAT(png_structrp png_ptr) 1.4285 +{ 1.4286 + /* We don't need any more data and the stream should have ended, however the 1.4287 + * LZ end code may actually not have been processed. In this case we must 1.4288 + * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk 1.4289 + * may still remain to be consumed. 1.4290 + */ 1.4291 + if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 1.4292 + { 1.4293 + /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in 1.4294 + * the compressed stream, but the stream may be damaged too, so even after 1.4295 + * this call we may need to terminate the zstream ownership. 1.4296 + */ 1.4297 + png_read_IDAT_data(png_ptr, NULL, 0); 1.4298 + png_ptr->zstream.next_out = NULL; /* safety */ 1.4299 + 1.4300 + /* Now clear everything out for safety; the following may not have been 1.4301 + * done. 1.4302 + */ 1.4303 + if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 1.4304 + { 1.4305 + png_ptr->mode |= PNG_AFTER_IDAT; 1.4306 + png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 1.4307 + } 1.4308 + } 1.4309 + 1.4310 + /* If the zstream has not been released do it now *and* terminate the reading 1.4311 + * of the final IDAT chunk. 1.4312 + */ 1.4313 + if (png_ptr->zowner == png_IDAT) 1.4314 + { 1.4315 + /* Always do this; the pointers otherwise point into the read buffer. */ 1.4316 + png_ptr->zstream.next_in = NULL; 1.4317 + png_ptr->zstream.avail_in = 0; 1.4318 + 1.4319 + /* Now we no longer own the zstream. */ 1.4320 + png_ptr->zowner = 0; 1.4321 + 1.4322 + /* The slightly weird semantics of the sequential IDAT reading is that we 1.4323 + * are always in or at the end of an IDAT chunk, so we always need to do a 1.4324 + * crc_finish here. If idat_size is non-zero we also need to read the 1.4325 + * spurious bytes at the end of the chunk now. 1.4326 + */ 1.4327 + (void)png_crc_finish(png_ptr, png_ptr->idat_size); 1.4328 + } 1.4329 +} 1.4330 + 1.4331 +void /* PRIVATE */ 1.4332 +png_read_finish_row(png_structrp png_ptr) 1.4333 +{ 1.4334 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.4335 + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1.4336 + 1.4337 + /* Start of interlace block */ 1.4338 + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 1.4339 + 1.4340 + /* Offset to next interlace block */ 1.4341 + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 1.4342 + 1.4343 + /* Start of interlace block in the y direction */ 1.4344 + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 1.4345 + 1.4346 + /* Offset to next interlace block in the y direction */ 1.4347 + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 1.4348 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.4349 + 1.4350 + png_debug(1, "in png_read_finish_row"); 1.4351 + png_ptr->row_number++; 1.4352 + if (png_ptr->row_number < png_ptr->num_rows) 1.4353 + return; 1.4354 + 1.4355 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.4356 + if (png_ptr->interlaced) 1.4357 + { 1.4358 + png_ptr->row_number = 0; 1.4359 + 1.4360 + /* TO DO: don't do this if prev_row isn't needed (requires 1.4361 + * read-ahead of the next row's filter byte. 1.4362 + */ 1.4363 + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 1.4364 + 1.4365 + do 1.4366 + { 1.4367 + png_ptr->pass++; 1.4368 + 1.4369 + if (png_ptr->pass >= 7) 1.4370 + break; 1.4371 + 1.4372 + png_ptr->iwidth = (png_ptr->width + 1.4373 + png_pass_inc[png_ptr->pass] - 1 - 1.4374 + png_pass_start[png_ptr->pass]) / 1.4375 + png_pass_inc[png_ptr->pass]; 1.4376 + 1.4377 + if (!(png_ptr->transformations & PNG_INTERLACE)) 1.4378 + { 1.4379 + png_ptr->num_rows = (png_ptr->height + 1.4380 + png_pass_yinc[png_ptr->pass] - 1 - 1.4381 + png_pass_ystart[png_ptr->pass]) / 1.4382 + png_pass_yinc[png_ptr->pass]; 1.4383 + } 1.4384 + 1.4385 + else /* if (png_ptr->transformations & PNG_INTERLACE) */ 1.4386 + break; /* libpng deinterlacing sees every row */ 1.4387 + 1.4388 + } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); 1.4389 + 1.4390 + if (png_ptr->pass < 7) 1.4391 + return; 1.4392 + } 1.4393 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.4394 + 1.4395 + /* Here after at the end of the last row of the last pass. */ 1.4396 + png_read_finish_IDAT(png_ptr); 1.4397 +} 1.4398 +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 1.4399 + 1.4400 +void /* PRIVATE */ 1.4401 +png_read_start_row(png_structrp png_ptr) 1.4402 +{ 1.4403 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.4404 + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1.4405 + 1.4406 + /* Start of interlace block */ 1.4407 + static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 1.4408 + 1.4409 + /* Offset to next interlace block */ 1.4410 + static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 1.4411 + 1.4412 + /* Start of interlace block in the y direction */ 1.4413 + static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 1.4414 + 1.4415 + /* Offset to next interlace block in the y direction */ 1.4416 + static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 1.4417 +#endif 1.4418 + 1.4419 + int max_pixel_depth; 1.4420 + png_size_t row_bytes; 1.4421 + 1.4422 + png_debug(1, "in png_read_start_row"); 1.4423 + 1.4424 +#ifdef PNG_READ_TRANSFORMS_SUPPORTED 1.4425 + png_init_read_transformations(png_ptr); 1.4426 +#endif 1.4427 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.4428 + if (png_ptr->interlaced) 1.4429 + { 1.4430 + if (!(png_ptr->transformations & PNG_INTERLACE)) 1.4431 + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 1.4432 + png_pass_ystart[0]) / png_pass_yinc[0]; 1.4433 + 1.4434 + else 1.4435 + png_ptr->num_rows = png_ptr->height; 1.4436 + 1.4437 + png_ptr->iwidth = (png_ptr->width + 1.4438 + png_pass_inc[png_ptr->pass] - 1 - 1.4439 + png_pass_start[png_ptr->pass]) / 1.4440 + png_pass_inc[png_ptr->pass]; 1.4441 + } 1.4442 + 1.4443 + else 1.4444 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.4445 + { 1.4446 + png_ptr->num_rows = png_ptr->height; 1.4447 + png_ptr->iwidth = png_ptr->width; 1.4448 + } 1.4449 + 1.4450 + max_pixel_depth = png_ptr->pixel_depth; 1.4451 + 1.4452 + /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of 1.4453 + * calculations to calculate the final pixel depth, then 1.4454 + * png_do_read_transforms actually does the transforms. This means that the 1.4455 + * code which effectively calculates this value is actually repeated in three 1.4456 + * separate places. They must all match. Innocent changes to the order of 1.4457 + * transformations can and will break libpng in a way that causes memory 1.4458 + * overwrites. 1.4459 + * 1.4460 + * TODO: fix this. 1.4461 + */ 1.4462 +#ifdef PNG_READ_PACK_SUPPORTED 1.4463 + if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 1.4464 + max_pixel_depth = 8; 1.4465 +#endif 1.4466 + 1.4467 +#ifdef PNG_READ_EXPAND_SUPPORTED 1.4468 + if (png_ptr->transformations & PNG_EXPAND) 1.4469 + { 1.4470 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.4471 + { 1.4472 + if (png_ptr->num_trans) 1.4473 + max_pixel_depth = 32; 1.4474 + 1.4475 + else 1.4476 + max_pixel_depth = 24; 1.4477 + } 1.4478 + 1.4479 + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1.4480 + { 1.4481 + if (max_pixel_depth < 8) 1.4482 + max_pixel_depth = 8; 1.4483 + 1.4484 + if (png_ptr->num_trans) 1.4485 + max_pixel_depth *= 2; 1.4486 + } 1.4487 + 1.4488 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1.4489 + { 1.4490 + if (png_ptr->num_trans) 1.4491 + { 1.4492 + max_pixel_depth *= 4; 1.4493 + max_pixel_depth /= 3; 1.4494 + } 1.4495 + } 1.4496 + } 1.4497 +#endif 1.4498 + 1.4499 +#ifdef PNG_READ_EXPAND_16_SUPPORTED 1.4500 + if (png_ptr->transformations & PNG_EXPAND_16) 1.4501 + { 1.4502 +# ifdef PNG_READ_EXPAND_SUPPORTED 1.4503 + /* In fact it is an error if it isn't supported, but checking is 1.4504 + * the safe way. 1.4505 + */ 1.4506 + if (png_ptr->transformations & PNG_EXPAND) 1.4507 + { 1.4508 + if (png_ptr->bit_depth < 16) 1.4509 + max_pixel_depth *= 2; 1.4510 + } 1.4511 + else 1.4512 +# endif 1.4513 + png_ptr->transformations &= ~PNG_EXPAND_16; 1.4514 + } 1.4515 +#endif 1.4516 + 1.4517 +#ifdef PNG_READ_FILLER_SUPPORTED 1.4518 + if (png_ptr->transformations & (PNG_FILLER)) 1.4519 + { 1.4520 + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1.4521 + { 1.4522 + if (max_pixel_depth <= 8) 1.4523 + max_pixel_depth = 16; 1.4524 + 1.4525 + else 1.4526 + max_pixel_depth = 32; 1.4527 + } 1.4528 + 1.4529 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || 1.4530 + png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.4531 + { 1.4532 + if (max_pixel_depth <= 32) 1.4533 + max_pixel_depth = 32; 1.4534 + 1.4535 + else 1.4536 + max_pixel_depth = 64; 1.4537 + } 1.4538 + } 1.4539 +#endif 1.4540 + 1.4541 +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 1.4542 + if (png_ptr->transformations & PNG_GRAY_TO_RGB) 1.4543 + { 1.4544 + if ( 1.4545 +#ifdef PNG_READ_EXPAND_SUPPORTED 1.4546 + (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 1.4547 +#endif 1.4548 +#ifdef PNG_READ_FILLER_SUPPORTED 1.4549 + (png_ptr->transformations & (PNG_FILLER)) || 1.4550 +#endif 1.4551 + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 1.4552 + { 1.4553 + if (max_pixel_depth <= 16) 1.4554 + max_pixel_depth = 32; 1.4555 + 1.4556 + else 1.4557 + max_pixel_depth = 64; 1.4558 + } 1.4559 + 1.4560 + else 1.4561 + { 1.4562 + if (max_pixel_depth <= 8) 1.4563 + { 1.4564 + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 1.4565 + max_pixel_depth = 32; 1.4566 + 1.4567 + else 1.4568 + max_pixel_depth = 24; 1.4569 + } 1.4570 + 1.4571 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 1.4572 + max_pixel_depth = 64; 1.4573 + 1.4574 + else 1.4575 + max_pixel_depth = 48; 1.4576 + } 1.4577 + } 1.4578 +#endif 1.4579 + 1.4580 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 1.4581 +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 1.4582 + if (png_ptr->transformations & PNG_USER_TRANSFORM) 1.4583 + { 1.4584 + int user_pixel_depth = png_ptr->user_transform_depth * 1.4585 + png_ptr->user_transform_channels; 1.4586 + 1.4587 + if (user_pixel_depth > max_pixel_depth) 1.4588 + max_pixel_depth = user_pixel_depth; 1.4589 + } 1.4590 +#endif 1.4591 + 1.4592 + /* This value is stored in png_struct and double checked in the row read 1.4593 + * code. 1.4594 + */ 1.4595 + png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; 1.4596 + png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ 1.4597 + 1.4598 + /* Align the width on the next larger 8 pixels. Mainly used 1.4599 + * for interlacing 1.4600 + */ 1.4601 + row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 1.4602 + /* Calculate the maximum bytes needed, adding a byte and a pixel 1.4603 + * for safety's sake 1.4604 + */ 1.4605 + row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 1.4606 + 1 + ((max_pixel_depth + 7) >> 3); 1.4607 + 1.4608 +#ifdef PNG_MAX_MALLOC_64K 1.4609 + if (row_bytes > (png_uint_32)65536L) 1.4610 + png_error(png_ptr, "This image requires a row greater than 64KB"); 1.4611 +#endif 1.4612 + 1.4613 + if (row_bytes + 48 > png_ptr->old_big_row_buf_size) 1.4614 + { 1.4615 + png_free(png_ptr, png_ptr->big_row_buf); 1.4616 + png_free(png_ptr, png_ptr->big_prev_row); 1.4617 + 1.4618 + if (png_ptr->interlaced) 1.4619 + png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, 1.4620 + row_bytes + 48); 1.4621 + 1.4622 + else 1.4623 + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); 1.4624 + 1.4625 + png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); 1.4626 + 1.4627 +#ifdef PNG_ALIGNED_MEMORY_SUPPORTED 1.4628 + /* Use 16-byte aligned memory for row_buf with at least 16 bytes 1.4629 + * of padding before and after row_buf; treat prev_row similarly. 1.4630 + * NOTE: the alignment is to the start of the pixels, one beyond the start 1.4631 + * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this 1.4632 + * was incorrect; the filter byte was aligned, which had the exact 1.4633 + * opposite effect of that intended. 1.4634 + */ 1.4635 + { 1.4636 + png_bytep temp = png_ptr->big_row_buf + 32; 1.4637 + int extra = (int)((temp - (png_bytep)0) & 0x0f); 1.4638 + png_ptr->row_buf = temp - extra - 1/*filter byte*/; 1.4639 + 1.4640 + temp = png_ptr->big_prev_row + 32; 1.4641 + extra = (int)((temp - (png_bytep)0) & 0x0f); 1.4642 + png_ptr->prev_row = temp - extra - 1/*filter byte*/; 1.4643 + } 1.4644 + 1.4645 +#else 1.4646 + /* Use 31 bytes of padding before and 17 bytes after row_buf. */ 1.4647 + png_ptr->row_buf = png_ptr->big_row_buf + 31; 1.4648 + png_ptr->prev_row = png_ptr->big_prev_row + 31; 1.4649 +#endif 1.4650 + png_ptr->old_big_row_buf_size = row_bytes + 48; 1.4651 + } 1.4652 + 1.4653 +#ifdef PNG_MAX_MALLOC_64K 1.4654 + if (png_ptr->rowbytes > 65535) 1.4655 + png_error(png_ptr, "This image requires a row greater than 64KB"); 1.4656 + 1.4657 +#endif 1.4658 + if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) 1.4659 + png_error(png_ptr, "Row has too many bytes to allocate in memory"); 1.4660 + 1.4661 + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 1.4662 + 1.4663 + png_debug1(3, "width = %u,", png_ptr->width); 1.4664 + png_debug1(3, "height = %u,", png_ptr->height); 1.4665 + png_debug1(3, "iwidth = %u,", png_ptr->iwidth); 1.4666 + png_debug1(3, "num_rows = %u,", png_ptr->num_rows); 1.4667 + png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); 1.4668 + png_debug1(3, "irowbytes = %lu", 1.4669 + (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); 1.4670 + 1.4671 + /* The sequential reader needs a buffer for IDAT, but the progressive reader 1.4672 + * does not, so free the read buffer now regardless; the sequential reader 1.4673 + * reallocates it on demand. 1.4674 + */ 1.4675 + if (png_ptr->read_buffer) 1.4676 + { 1.4677 + png_bytep buffer = png_ptr->read_buffer; 1.4678 + 1.4679 + png_ptr->read_buffer_size = 0; 1.4680 + png_ptr->read_buffer = NULL; 1.4681 + png_free(png_ptr, buffer); 1.4682 + } 1.4683 + 1.4684 + /* Finally claim the zstream for the inflate of the IDAT data, use the bits 1.4685 + * value from the stream (note that this will result in a fatal error if the 1.4686 + * IDAT stream has a bogus deflate header window_bits value, but this should 1.4687 + * not be happening any longer!) 1.4688 + */ 1.4689 + if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) 1.4690 + png_error(png_ptr, png_ptr->zstream.msg); 1.4691 + 1.4692 + png_ptr->flags |= PNG_FLAG_ROW_INIT; 1.4693 +} 1.4694 + 1.4695 +#ifdef PNG_READ_APNG_SUPPORTED 1.4696 +/* This function is to be called after the main IDAT set has been read and 1.4697 + * before a new IDAT is read. It resets some parts of png_ptr 1.4698 + * to make them usable by the read functions again */ 1.4699 +void /* PRIVATE */ 1.4700 +png_read_reset(png_structp png_ptr) 1.4701 +{ 1.4702 + png_ptr->mode &= ~PNG_HAVE_IDAT; 1.4703 + png_ptr->mode &= ~PNG_AFTER_IDAT; 1.4704 + png_ptr->row_number = 0; 1.4705 + png_ptr->pass = 0; 1.4706 +} 1.4707 + 1.4708 +void /* PRIVATE */ 1.4709 +png_read_reinit(png_structp png_ptr, png_infop info_ptr) 1.4710 +{ 1.4711 + png_ptr->width = info_ptr->next_frame_width; 1.4712 + png_ptr->height = info_ptr->next_frame_height; 1.4713 + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); 1.4714 + png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, 1.4715 + png_ptr->width); 1.4716 + if (png_ptr->prev_row) 1.4717 + memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 1.4718 +} 1.4719 + 1.4720 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 1.4721 +/* same as png_read_reset() but for the progressive reader */ 1.4722 +void /* PRIVATE */ 1.4723 +png_progressive_read_reset(png_structp png_ptr) 1.4724 +{ 1.4725 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.4726 + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1.4727 + 1.4728 + /* Start of interlace block */ 1.4729 + static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; 1.4730 + 1.4731 + /* Offset to next interlace block */ 1.4732 + static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; 1.4733 + 1.4734 + /* Start of interlace block in the y direction */ 1.4735 + static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; 1.4736 + 1.4737 + /* Offset to next interlace block in the y direction */ 1.4738 + static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; 1.4739 + 1.4740 + if (png_ptr->interlaced) 1.4741 + { 1.4742 + if (!(png_ptr->transformations & PNG_INTERLACE)) 1.4743 + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 1.4744 + png_pass_ystart[0]) / png_pass_yinc[0]; 1.4745 + else 1.4746 + png_ptr->num_rows = png_ptr->height; 1.4747 + 1.4748 + png_ptr->iwidth = (png_ptr->width + 1.4749 + png_pass_inc[png_ptr->pass] - 1 - 1.4750 + png_pass_start[png_ptr->pass]) / 1.4751 + png_pass_inc[png_ptr->pass]; 1.4752 + } 1.4753 + else 1.4754 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.4755 + { 1.4756 + png_ptr->num_rows = png_ptr->height; 1.4757 + png_ptr->iwidth = png_ptr->width; 1.4758 + } 1.4759 + png_ptr->flags &= ~PNG_FLAG_ZSTREAM_ENDED; 1.4760 + if (inflateReset(&(png_ptr->zstream)) != Z_OK) 1.4761 + png_error(png_ptr, "inflateReset failed"); 1.4762 + png_ptr->zstream.avail_in = 0; 1.4763 + png_ptr->zstream.next_in = 0; 1.4764 + png_ptr->zstream.next_out = png_ptr->row_buf; 1.4765 + png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth, 1.4766 + png_ptr->iwidth) + 1; 1.4767 +} 1.4768 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ 1.4769 +#endif /* PNG_READ_APNG_SUPPORTED */ 1.4770 +#endif /* PNG_READ_SUPPORTED */