istereo
diff libs/libpng/pngrutil.c @ 26:862a3329a8f0
wohooo, added a shitload of code from zlib/libpng/libjpeg. When the good lord was raining shared libraries the iphone held a fucking umbrella...
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Thu, 08 Sep 2011 06:28:38 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/libpng/pngrutil.c Thu Sep 08 06:28:38 2011 +0300 1.3 @@ -0,0 +1,3234 @@ 1.4 + 1.5 +/* pngrutil.c - utilities to read a PNG file 1.6 + * 1.7 + * Last changed in libpng 1.2.33 [October 31, 2008] 1.8 + * For conditions of distribution and use, see copyright notice in png.h 1.9 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson 1.10 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 1.11 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 1.12 + * 1.13 + * This file contains routines that are only called from within 1.14 + * libpng itself during the course of reading an image. 1.15 + */ 1.16 + 1.17 +#define PNG_INTERNAL 1.18 +#include "png.h" 1.19 +#if defined(PNG_READ_SUPPORTED) 1.20 + 1.21 +#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) 1.22 +# define WIN32_WCE_OLD 1.23 +#endif 1.24 + 1.25 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.26 +# if defined(WIN32_WCE_OLD) 1.27 +/* strtod() function is not supported on WindowsCE */ 1.28 +__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr) 1.29 +{ 1.30 + double result = 0; 1.31 + int len; 1.32 + wchar_t *str, *end; 1.33 + 1.34 + len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); 1.35 + str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t)); 1.36 + if ( NULL != str ) 1.37 + { 1.38 + MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); 1.39 + result = wcstod(str, &end); 1.40 + len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); 1.41 + *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); 1.42 + png_free(png_ptr, str); 1.43 + } 1.44 + return result; 1.45 +} 1.46 +# else 1.47 +# define png_strtod(p,a,b) strtod(a,b) 1.48 +# endif 1.49 +#endif 1.50 + 1.51 +png_uint_32 PNGAPI 1.52 +png_get_uint_31(png_structp png_ptr, png_bytep buf) 1.53 +{ 1.54 +#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED 1.55 + png_uint_32 i = png_get_uint_32(buf); 1.56 +#else 1.57 + /* Avoid an extra function call by inlining the result. */ 1.58 + png_uint_32 i = ((png_uint_32)(*buf) << 24) + 1.59 + ((png_uint_32)(*(buf + 1)) << 16) + 1.60 + ((png_uint_32)(*(buf + 2)) << 8) + 1.61 + (png_uint_32)(*(buf + 3)); 1.62 +#endif 1.63 + if (i > PNG_UINT_31_MAX) 1.64 + png_error(png_ptr, "PNG unsigned integer out of range."); 1.65 + return (i); 1.66 +} 1.67 +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED 1.68 +/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ 1.69 +png_uint_32 PNGAPI 1.70 +png_get_uint_32(png_bytep buf) 1.71 +{ 1.72 + png_uint_32 i = ((png_uint_32)(*buf) << 24) + 1.73 + ((png_uint_32)(*(buf + 1)) << 16) + 1.74 + ((png_uint_32)(*(buf + 2)) << 8) + 1.75 + (png_uint_32)(*(buf + 3)); 1.76 + 1.77 + return (i); 1.78 +} 1.79 + 1.80 +/* Grab a signed 32-bit integer from a buffer in big-endian format. The 1.81 + * data is stored in the PNG file in two's complement format, and it is 1.82 + * assumed that the machine format for signed integers is the same. */ 1.83 +png_int_32 PNGAPI 1.84 +png_get_int_32(png_bytep buf) 1.85 +{ 1.86 + png_int_32 i = ((png_int_32)(*buf) << 24) + 1.87 + ((png_int_32)(*(buf + 1)) << 16) + 1.88 + ((png_int_32)(*(buf + 2)) << 8) + 1.89 + (png_int_32)(*(buf + 3)); 1.90 + 1.91 + return (i); 1.92 +} 1.93 + 1.94 +/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ 1.95 +png_uint_16 PNGAPI 1.96 +png_get_uint_16(png_bytep buf) 1.97 +{ 1.98 + png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + 1.99 + (png_uint_16)(*(buf + 1))); 1.100 + 1.101 + return (i); 1.102 +} 1.103 +#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ 1.104 + 1.105 +/* Read the chunk header (length + type name). 1.106 + * Put the type name into png_ptr->chunk_name, and return the length. 1.107 + */ 1.108 +png_uint_32 /* PRIVATE */ 1.109 +png_read_chunk_header(png_structp png_ptr) 1.110 +{ 1.111 + png_byte buf[8]; 1.112 + png_uint_32 length; 1.113 + 1.114 + /* read the length and the chunk name */ 1.115 + png_read_data(png_ptr, buf, 8); 1.116 + length = png_get_uint_31(png_ptr, buf); 1.117 + 1.118 + /* put the chunk name into png_ptr->chunk_name */ 1.119 + png_memcpy(png_ptr->chunk_name, buf + 4, 4); 1.120 + 1.121 + png_debug2(0, "Reading %s chunk, length = %lu\n", 1.122 + png_ptr->chunk_name, length); 1.123 + 1.124 + /* reset the crc and run it over the chunk name */ 1.125 + png_reset_crc(png_ptr); 1.126 + png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); 1.127 + 1.128 + /* check to see if chunk name is valid */ 1.129 + png_check_chunk_name(png_ptr, png_ptr->chunk_name); 1.130 + 1.131 + return length; 1.132 +} 1.133 + 1.134 +/* Read data, and (optionally) run it through the CRC. */ 1.135 +void /* PRIVATE */ 1.136 +png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) 1.137 +{ 1.138 + if (png_ptr == NULL) return; 1.139 + png_read_data(png_ptr, buf, length); 1.140 + png_calculate_crc(png_ptr, buf, length); 1.141 +} 1.142 + 1.143 +/* Optionally skip data and then check the CRC. Depending on whether we 1.144 + are reading a ancillary or critical chunk, and how the program has set 1.145 + things up, we may calculate the CRC on the data and print a message. 1.146 + Returns '1' if there was a CRC error, '0' otherwise. */ 1.147 +int /* PRIVATE */ 1.148 +png_crc_finish(png_structp png_ptr, png_uint_32 skip) 1.149 +{ 1.150 + png_size_t i; 1.151 + png_size_t istop = png_ptr->zbuf_size; 1.152 + 1.153 + for (i = (png_size_t)skip; i > istop; i -= istop) 1.154 + { 1.155 + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 1.156 + } 1.157 + if (i) 1.158 + { 1.159 + png_crc_read(png_ptr, png_ptr->zbuf, i); 1.160 + } 1.161 + 1.162 + if (png_crc_error(png_ptr)) 1.163 + { 1.164 + if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ 1.165 + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || 1.166 + (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ 1.167 + (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) 1.168 + { 1.169 + png_chunk_warning(png_ptr, "CRC error"); 1.170 + } 1.171 + else 1.172 + { 1.173 + png_chunk_error(png_ptr, "CRC error"); 1.174 + } 1.175 + return (1); 1.176 + } 1.177 + 1.178 + return (0); 1.179 +} 1.180 + 1.181 +/* Compare the CRC stored in the PNG file with that calculated by libpng from 1.182 + the data it has read thus far. */ 1.183 +int /* PRIVATE */ 1.184 +png_crc_error(png_structp png_ptr) 1.185 +{ 1.186 + png_byte crc_bytes[4]; 1.187 + png_uint_32 crc; 1.188 + int need_crc = 1; 1.189 + 1.190 + if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ 1.191 + { 1.192 + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 1.193 + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 1.194 + need_crc = 0; 1.195 + } 1.196 + else /* critical */ 1.197 + { 1.198 + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 1.199 + need_crc = 0; 1.200 + } 1.201 + 1.202 + png_read_data(png_ptr, crc_bytes, 4); 1.203 + 1.204 + if (need_crc) 1.205 + { 1.206 + crc = png_get_uint_32(crc_bytes); 1.207 + return ((int)(crc != png_ptr->crc)); 1.208 + } 1.209 + else 1.210 + return (0); 1.211 +} 1.212 + 1.213 +#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ 1.214 + defined(PNG_READ_iCCP_SUPPORTED) 1.215 +/* 1.216 + * Decompress trailing data in a chunk. The assumption is that chunkdata 1.217 + * points at an allocated area holding the contents of a chunk with a 1.218 + * trailing compressed part. What we get back is an allocated area 1.219 + * holding the original prefix part and an uncompressed version of the 1.220 + * trailing part (the malloc area passed in is freed). 1.221 + */ 1.222 +void /* PRIVATE */ 1.223 +png_decompress_chunk(png_structp png_ptr, int comp_type, 1.224 + png_size_t chunklength, 1.225 + png_size_t prefix_size, png_size_t *newlength) 1.226 +{ 1.227 + static PNG_CONST char msg[] = "Error decoding compressed text"; 1.228 + png_charp text; 1.229 + png_size_t text_size; 1.230 + 1.231 + if (comp_type == PNG_COMPRESSION_TYPE_BASE) 1.232 + { 1.233 + int ret = Z_OK; 1.234 + png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size); 1.235 + png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); 1.236 + png_ptr->zstream.next_out = png_ptr->zbuf; 1.237 + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 1.238 + 1.239 + text_size = 0; 1.240 + text = NULL; 1.241 + 1.242 + while (png_ptr->zstream.avail_in) 1.243 + { 1.244 + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 1.245 + if (ret != Z_OK && ret != Z_STREAM_END) 1.246 + { 1.247 + if (png_ptr->zstream.msg != NULL) 1.248 + png_warning(png_ptr, png_ptr->zstream.msg); 1.249 + else 1.250 + png_warning(png_ptr, msg); 1.251 + inflateReset(&png_ptr->zstream); 1.252 + png_ptr->zstream.avail_in = 0; 1.253 + 1.254 + if (text == NULL) 1.255 + { 1.256 + text_size = prefix_size + png_sizeof(msg) + 1; 1.257 + text = (png_charp)png_malloc_warn(png_ptr, text_size); 1.258 + if (text == NULL) 1.259 + { 1.260 + png_free(png_ptr, png_ptr->chunkdata); 1.261 + png_ptr->chunkdata = NULL; 1.262 + png_error(png_ptr, "Not enough memory to decompress chunk"); 1.263 + } 1.264 + png_memcpy(text, png_ptr->chunkdata, prefix_size); 1.265 + } 1.266 + 1.267 + text[text_size - 1] = 0x00; 1.268 + 1.269 + /* Copy what we can of the error message into the text chunk */ 1.270 + text_size = (png_size_t)(chunklength - 1.271 + (text - png_ptr->chunkdata) - 1); 1.272 + if (text_size > png_sizeof(msg)) 1.273 + text_size = png_sizeof(msg); 1.274 + png_memcpy(text + prefix_size, msg, text_size); 1.275 + break; 1.276 + } 1.277 + if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) 1.278 + { 1.279 + if (text == NULL) 1.280 + { 1.281 + text_size = prefix_size + 1.282 + png_ptr->zbuf_size - png_ptr->zstream.avail_out; 1.283 + text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); 1.284 + if (text == NULL) 1.285 + { 1.286 + png_free(png_ptr, png_ptr->chunkdata); 1.287 + png_ptr->chunkdata = NULL; 1.288 + png_error(png_ptr, 1.289 + "Not enough memory to decompress chunk."); 1.290 + } 1.291 + png_memcpy(text + prefix_size, png_ptr->zbuf, 1.292 + text_size - prefix_size); 1.293 + png_memcpy(text, png_ptr->chunkdata, prefix_size); 1.294 + *(text + text_size) = 0x00; 1.295 + } 1.296 + else 1.297 + { 1.298 + png_charp tmp; 1.299 + 1.300 + tmp = text; 1.301 + text = (png_charp)png_malloc_warn(png_ptr, 1.302 + (png_uint_32)(text_size + 1.303 + png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); 1.304 + if (text == NULL) 1.305 + { 1.306 + png_free(png_ptr, tmp); 1.307 + png_free(png_ptr, png_ptr->chunkdata); 1.308 + png_ptr->chunkdata = NULL; 1.309 + png_error(png_ptr, 1.310 + "Not enough memory to decompress chunk.."); 1.311 + } 1.312 + png_memcpy(text, tmp, text_size); 1.313 + png_free(png_ptr, tmp); 1.314 + png_memcpy(text + text_size, png_ptr->zbuf, 1.315 + (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); 1.316 + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; 1.317 + *(text + text_size) = 0x00; 1.318 + } 1.319 + if (ret == Z_STREAM_END) 1.320 + break; 1.321 + else 1.322 + { 1.323 + png_ptr->zstream.next_out = png_ptr->zbuf; 1.324 + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 1.325 + } 1.326 + } 1.327 + } 1.328 + if (ret != Z_STREAM_END) 1.329 + { 1.330 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 1.331 + char umsg[52]; 1.332 + 1.333 + if (ret == Z_BUF_ERROR) 1.334 + png_snprintf(umsg, 52, 1.335 + "Buffer error in compressed datastream in %s chunk", 1.336 + png_ptr->chunk_name); 1.337 + else if (ret == Z_DATA_ERROR) 1.338 + png_snprintf(umsg, 52, 1.339 + "Data error in compressed datastream in %s chunk", 1.340 + png_ptr->chunk_name); 1.341 + else 1.342 + png_snprintf(umsg, 52, 1.343 + "Incomplete compressed datastream in %s chunk", 1.344 + png_ptr->chunk_name); 1.345 + png_warning(png_ptr, umsg); 1.346 +#else 1.347 + png_warning(png_ptr, 1.348 + "Incomplete compressed datastream in chunk other than IDAT"); 1.349 +#endif 1.350 + text_size = prefix_size; 1.351 + if (text == NULL) 1.352 + { 1.353 + text = (png_charp)png_malloc_warn(png_ptr, text_size+1); 1.354 + if (text == NULL) 1.355 + { 1.356 + png_free(png_ptr, png_ptr->chunkdata); 1.357 + png_ptr->chunkdata = NULL; 1.358 + png_error(png_ptr, "Not enough memory for text."); 1.359 + } 1.360 + png_memcpy(text, png_ptr->chunkdata, prefix_size); 1.361 + } 1.362 + *(text + text_size) = 0x00; 1.363 + } 1.364 + 1.365 + inflateReset(&png_ptr->zstream); 1.366 + png_ptr->zstream.avail_in = 0; 1.367 + 1.368 + png_free(png_ptr, png_ptr->chunkdata); 1.369 + png_ptr->chunkdata = text; 1.370 + *newlength=text_size; 1.371 + } 1.372 + else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ 1.373 + { 1.374 +#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 1.375 + char umsg[50]; 1.376 + 1.377 + png_snprintf(umsg, 50, "Unknown zTXt compression type %d", comp_type); 1.378 + png_warning(png_ptr, umsg); 1.379 +#else 1.380 + png_warning(png_ptr, "Unknown zTXt compression type"); 1.381 +#endif 1.382 + 1.383 + *(png_ptr->chunkdata + prefix_size) = 0x00; 1.384 + *newlength = prefix_size; 1.385 + } 1.386 +} 1.387 +#endif 1.388 + 1.389 +/* read and check the IDHR chunk */ 1.390 +void /* PRIVATE */ 1.391 +png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.392 +{ 1.393 + png_byte buf[13]; 1.394 + png_uint_32 width, height; 1.395 + int bit_depth, color_type, compression_type, filter_type; 1.396 + int interlace_type; 1.397 + 1.398 + png_debug(1, "in png_handle_IHDR\n"); 1.399 + 1.400 + if (png_ptr->mode & PNG_HAVE_IHDR) 1.401 + png_error(png_ptr, "Out of place IHDR"); 1.402 + 1.403 + /* check the length */ 1.404 + if (length != 13) 1.405 + png_error(png_ptr, "Invalid IHDR chunk"); 1.406 + 1.407 + png_ptr->mode |= PNG_HAVE_IHDR; 1.408 + 1.409 + png_crc_read(png_ptr, buf, 13); 1.410 + png_crc_finish(png_ptr, 0); 1.411 + 1.412 + width = png_get_uint_31(png_ptr, buf); 1.413 + height = png_get_uint_31(png_ptr, buf + 4); 1.414 + bit_depth = buf[8]; 1.415 + color_type = buf[9]; 1.416 + compression_type = buf[10]; 1.417 + filter_type = buf[11]; 1.418 + interlace_type = buf[12]; 1.419 + 1.420 + /* set internal variables */ 1.421 + png_ptr->width = width; 1.422 + png_ptr->height = height; 1.423 + png_ptr->bit_depth = (png_byte)bit_depth; 1.424 + png_ptr->interlaced = (png_byte)interlace_type; 1.425 + png_ptr->color_type = (png_byte)color_type; 1.426 +#if defined(PNG_MNG_FEATURES_SUPPORTED) 1.427 + png_ptr->filter_type = (png_byte)filter_type; 1.428 +#endif 1.429 + png_ptr->compression_type = (png_byte)compression_type; 1.430 + 1.431 + /* find number of channels */ 1.432 + switch (png_ptr->color_type) 1.433 + { 1.434 + case PNG_COLOR_TYPE_GRAY: 1.435 + case PNG_COLOR_TYPE_PALETTE: 1.436 + png_ptr->channels = 1; 1.437 + break; 1.438 + case PNG_COLOR_TYPE_RGB: 1.439 + png_ptr->channels = 3; 1.440 + break; 1.441 + case PNG_COLOR_TYPE_GRAY_ALPHA: 1.442 + png_ptr->channels = 2; 1.443 + break; 1.444 + case PNG_COLOR_TYPE_RGB_ALPHA: 1.445 + png_ptr->channels = 4; 1.446 + break; 1.447 + } 1.448 + 1.449 + /* set up other useful info */ 1.450 + png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 1.451 + png_ptr->channels); 1.452 + png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); 1.453 + png_debug1(3, "bit_depth = %d\n", png_ptr->bit_depth); 1.454 + png_debug1(3, "channels = %d\n", png_ptr->channels); 1.455 + png_debug1(3, "rowbytes = %lu\n", png_ptr->rowbytes); 1.456 + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 1.457 + color_type, interlace_type, compression_type, filter_type); 1.458 +} 1.459 + 1.460 +/* read and check the palette */ 1.461 +void /* PRIVATE */ 1.462 +png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.463 +{ 1.464 + png_color palette[PNG_MAX_PALETTE_LENGTH]; 1.465 + int num, i; 1.466 +#ifndef PNG_NO_POINTER_INDEXING 1.467 + png_colorp pal_ptr; 1.468 +#endif 1.469 + 1.470 + png_debug(1, "in png_handle_PLTE\n"); 1.471 + 1.472 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.473 + png_error(png_ptr, "Missing IHDR before PLTE"); 1.474 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.475 + { 1.476 + png_warning(png_ptr, "Invalid PLTE after IDAT"); 1.477 + png_crc_finish(png_ptr, length); 1.478 + return; 1.479 + } 1.480 + else if (png_ptr->mode & PNG_HAVE_PLTE) 1.481 + png_error(png_ptr, "Duplicate PLTE chunk"); 1.482 + 1.483 + png_ptr->mode |= PNG_HAVE_PLTE; 1.484 + 1.485 + if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 1.486 + { 1.487 + png_warning(png_ptr, 1.488 + "Ignoring PLTE chunk in grayscale PNG"); 1.489 + png_crc_finish(png_ptr, length); 1.490 + return; 1.491 + } 1.492 +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) 1.493 + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 1.494 + { 1.495 + png_crc_finish(png_ptr, length); 1.496 + return; 1.497 + } 1.498 +#endif 1.499 + 1.500 + if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) 1.501 + { 1.502 + if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 1.503 + { 1.504 + png_warning(png_ptr, "Invalid palette chunk"); 1.505 + png_crc_finish(png_ptr, length); 1.506 + return; 1.507 + } 1.508 + else 1.509 + { 1.510 + png_error(png_ptr, "Invalid palette chunk"); 1.511 + } 1.512 + } 1.513 + 1.514 + num = (int)length / 3; 1.515 + 1.516 +#ifndef PNG_NO_POINTER_INDEXING 1.517 + for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) 1.518 + { 1.519 + png_byte buf[3]; 1.520 + 1.521 + png_crc_read(png_ptr, buf, 3); 1.522 + pal_ptr->red = buf[0]; 1.523 + pal_ptr->green = buf[1]; 1.524 + pal_ptr->blue = buf[2]; 1.525 + } 1.526 +#else 1.527 + for (i = 0; i < num; i++) 1.528 + { 1.529 + png_byte buf[3]; 1.530 + 1.531 + png_crc_read(png_ptr, buf, 3); 1.532 + /* don't depend upon png_color being any order */ 1.533 + palette[i].red = buf[0]; 1.534 + palette[i].green = buf[1]; 1.535 + palette[i].blue = buf[2]; 1.536 + } 1.537 +#endif 1.538 + 1.539 + /* If we actually NEED the PLTE chunk (ie for a paletted image), we do 1.540 + whatever the normal CRC configuration tells us. However, if we 1.541 + have an RGB image, the PLTE can be considered ancillary, so 1.542 + we will act as though it is. */ 1.543 +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) 1.544 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.545 +#endif 1.546 + { 1.547 + png_crc_finish(png_ptr, 0); 1.548 + } 1.549 +#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) 1.550 + else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ 1.551 + { 1.552 + /* If we don't want to use the data from an ancillary chunk, 1.553 + we have two options: an error abort, or a warning and we 1.554 + ignore the data in this chunk (which should be OK, since 1.555 + it's considered ancillary for a RGB or RGBA image). */ 1.556 + if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) 1.557 + { 1.558 + if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) 1.559 + { 1.560 + png_chunk_error(png_ptr, "CRC error"); 1.561 + } 1.562 + else 1.563 + { 1.564 + png_chunk_warning(png_ptr, "CRC error"); 1.565 + return; 1.566 + } 1.567 + } 1.568 + /* Otherwise, we (optionally) emit a warning and use the chunk. */ 1.569 + else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) 1.570 + { 1.571 + png_chunk_warning(png_ptr, "CRC error"); 1.572 + } 1.573 + } 1.574 +#endif 1.575 + 1.576 + png_set_PLTE(png_ptr, info_ptr, palette, num); 1.577 + 1.578 +#if defined(PNG_READ_tRNS_SUPPORTED) 1.579 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.580 + { 1.581 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 1.582 + { 1.583 + if (png_ptr->num_trans > (png_uint_16)num) 1.584 + { 1.585 + png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); 1.586 + png_ptr->num_trans = (png_uint_16)num; 1.587 + } 1.588 + if (info_ptr->num_trans > (png_uint_16)num) 1.589 + { 1.590 + png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); 1.591 + info_ptr->num_trans = (png_uint_16)num; 1.592 + } 1.593 + } 1.594 + } 1.595 +#endif 1.596 + 1.597 +} 1.598 + 1.599 +void /* PRIVATE */ 1.600 +png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.601 +{ 1.602 + png_debug(1, "in png_handle_IEND\n"); 1.603 + 1.604 + if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) 1.605 + { 1.606 + png_error(png_ptr, "No image in file"); 1.607 + } 1.608 + 1.609 + png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); 1.610 + 1.611 + if (length != 0) 1.612 + { 1.613 + png_warning(png_ptr, "Incorrect IEND chunk length"); 1.614 + } 1.615 + png_crc_finish(png_ptr, length); 1.616 + 1.617 + info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */ 1.618 +} 1.619 + 1.620 +#if defined(PNG_READ_gAMA_SUPPORTED) 1.621 +void /* PRIVATE */ 1.622 +png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.623 +{ 1.624 + png_fixed_point igamma; 1.625 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.626 + float file_gamma; 1.627 +#endif 1.628 + png_byte buf[4]; 1.629 + 1.630 + png_debug(1, "in png_handle_gAMA\n"); 1.631 + 1.632 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.633 + png_error(png_ptr, "Missing IHDR before gAMA"); 1.634 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.635 + { 1.636 + png_warning(png_ptr, "Invalid gAMA after IDAT"); 1.637 + png_crc_finish(png_ptr, length); 1.638 + return; 1.639 + } 1.640 + else if (png_ptr->mode & PNG_HAVE_PLTE) 1.641 + /* Should be an error, but we can cope with it */ 1.642 + png_warning(png_ptr, "Out of place gAMA chunk"); 1.643 + 1.644 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) 1.645 +#if defined(PNG_READ_sRGB_SUPPORTED) 1.646 + && !(info_ptr->valid & PNG_INFO_sRGB) 1.647 +#endif 1.648 + ) 1.649 + { 1.650 + png_warning(png_ptr, "Duplicate gAMA chunk"); 1.651 + png_crc_finish(png_ptr, length); 1.652 + return; 1.653 + } 1.654 + 1.655 + if (length != 4) 1.656 + { 1.657 + png_warning(png_ptr, "Incorrect gAMA chunk length"); 1.658 + png_crc_finish(png_ptr, length); 1.659 + return; 1.660 + } 1.661 + 1.662 + png_crc_read(png_ptr, buf, 4); 1.663 + if (png_crc_finish(png_ptr, 0)) 1.664 + return; 1.665 + 1.666 + igamma = (png_fixed_point)png_get_uint_32(buf); 1.667 + /* check for zero gamma */ 1.668 + if (igamma == 0) 1.669 + { 1.670 + png_warning(png_ptr, 1.671 + "Ignoring gAMA chunk with gamma=0"); 1.672 + return; 1.673 + } 1.674 + 1.675 +#if defined(PNG_READ_sRGB_SUPPORTED) 1.676 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 1.677 + if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 1.678 + { 1.679 + png_warning(png_ptr, 1.680 + "Ignoring incorrect gAMA value when sRGB is also present"); 1.681 +#ifndef PNG_NO_CONSOLE_IO 1.682 + fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma); 1.683 +#endif 1.684 + return; 1.685 + } 1.686 +#endif /* PNG_READ_sRGB_SUPPORTED */ 1.687 + 1.688 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.689 + file_gamma = (float)igamma / (float)100000.0; 1.690 +# ifdef PNG_READ_GAMMA_SUPPORTED 1.691 + png_ptr->gamma = file_gamma; 1.692 +# endif 1.693 + png_set_gAMA(png_ptr, info_ptr, file_gamma); 1.694 +#endif 1.695 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.696 + png_set_gAMA_fixed(png_ptr, info_ptr, igamma); 1.697 +#endif 1.698 +} 1.699 +#endif 1.700 + 1.701 +#if defined(PNG_READ_sBIT_SUPPORTED) 1.702 +void /* PRIVATE */ 1.703 +png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.704 +{ 1.705 + png_size_t truelen; 1.706 + png_byte buf[4]; 1.707 + 1.708 + png_debug(1, "in png_handle_sBIT\n"); 1.709 + 1.710 + buf[0] = buf[1] = buf[2] = buf[3] = 0; 1.711 + 1.712 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.713 + png_error(png_ptr, "Missing IHDR before sBIT"); 1.714 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.715 + { 1.716 + png_warning(png_ptr, "Invalid sBIT after IDAT"); 1.717 + png_crc_finish(png_ptr, length); 1.718 + return; 1.719 + } 1.720 + else if (png_ptr->mode & PNG_HAVE_PLTE) 1.721 + { 1.722 + /* Should be an error, but we can cope with it */ 1.723 + png_warning(png_ptr, "Out of place sBIT chunk"); 1.724 + } 1.725 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) 1.726 + { 1.727 + png_warning(png_ptr, "Duplicate sBIT chunk"); 1.728 + png_crc_finish(png_ptr, length); 1.729 + return; 1.730 + } 1.731 + 1.732 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.733 + truelen = 3; 1.734 + else 1.735 + truelen = (png_size_t)png_ptr->channels; 1.736 + 1.737 + if (length != truelen || length > 4) 1.738 + { 1.739 + png_warning(png_ptr, "Incorrect sBIT chunk length"); 1.740 + png_crc_finish(png_ptr, length); 1.741 + return; 1.742 + } 1.743 + 1.744 + png_crc_read(png_ptr, buf, truelen); 1.745 + if (png_crc_finish(png_ptr, 0)) 1.746 + return; 1.747 + 1.748 + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1.749 + { 1.750 + png_ptr->sig_bit.red = buf[0]; 1.751 + png_ptr->sig_bit.green = buf[1]; 1.752 + png_ptr->sig_bit.blue = buf[2]; 1.753 + png_ptr->sig_bit.alpha = buf[3]; 1.754 + } 1.755 + else 1.756 + { 1.757 + png_ptr->sig_bit.gray = buf[0]; 1.758 + png_ptr->sig_bit.red = buf[0]; 1.759 + png_ptr->sig_bit.green = buf[0]; 1.760 + png_ptr->sig_bit.blue = buf[0]; 1.761 + png_ptr->sig_bit.alpha = buf[1]; 1.762 + } 1.763 + png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); 1.764 +} 1.765 +#endif 1.766 + 1.767 +#if defined(PNG_READ_cHRM_SUPPORTED) 1.768 +void /* PRIVATE */ 1.769 +png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.770 +{ 1.771 + png_byte buf[32]; 1.772 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.773 + float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; 1.774 +#endif 1.775 + png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 1.776 + int_y_green, int_x_blue, int_y_blue; 1.777 + 1.778 + png_uint_32 uint_x, uint_y; 1.779 + 1.780 + png_debug(1, "in png_handle_cHRM\n"); 1.781 + 1.782 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.783 + png_error(png_ptr, "Missing IHDR before cHRM"); 1.784 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.785 + { 1.786 + png_warning(png_ptr, "Invalid cHRM after IDAT"); 1.787 + png_crc_finish(png_ptr, length); 1.788 + return; 1.789 + } 1.790 + else if (png_ptr->mode & PNG_HAVE_PLTE) 1.791 + /* Should be an error, but we can cope with it */ 1.792 + png_warning(png_ptr, "Missing PLTE before cHRM"); 1.793 + 1.794 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) 1.795 +#if defined(PNG_READ_sRGB_SUPPORTED) 1.796 + && !(info_ptr->valid & PNG_INFO_sRGB) 1.797 +#endif 1.798 + ) 1.799 + { 1.800 + png_warning(png_ptr, "Duplicate cHRM chunk"); 1.801 + png_crc_finish(png_ptr, length); 1.802 + return; 1.803 + } 1.804 + 1.805 + if (length != 32) 1.806 + { 1.807 + png_warning(png_ptr, "Incorrect cHRM chunk length"); 1.808 + png_crc_finish(png_ptr, length); 1.809 + return; 1.810 + } 1.811 + 1.812 + png_crc_read(png_ptr, buf, 32); 1.813 + if (png_crc_finish(png_ptr, 0)) 1.814 + return; 1.815 + 1.816 + uint_x = png_get_uint_32(buf); 1.817 + uint_y = png_get_uint_32(buf + 4); 1.818 + if (uint_x > 80000L || uint_y > 80000L || 1.819 + uint_x + uint_y > 100000L) 1.820 + { 1.821 + png_warning(png_ptr, "Invalid cHRM white point"); 1.822 + return; 1.823 + } 1.824 + int_x_white = (png_fixed_point)uint_x; 1.825 + int_y_white = (png_fixed_point)uint_y; 1.826 + 1.827 + uint_x = png_get_uint_32(buf + 8); 1.828 + uint_y = png_get_uint_32(buf + 12); 1.829 + if (uint_x + uint_y > 100000L) 1.830 + { 1.831 + png_warning(png_ptr, "Invalid cHRM red point"); 1.832 + return; 1.833 + } 1.834 + int_x_red = (png_fixed_point)uint_x; 1.835 + int_y_red = (png_fixed_point)uint_y; 1.836 + 1.837 + uint_x = png_get_uint_32(buf + 16); 1.838 + uint_y = png_get_uint_32(buf + 20); 1.839 + if (uint_x + uint_y > 100000L) 1.840 + { 1.841 + png_warning(png_ptr, "Invalid cHRM green point"); 1.842 + return; 1.843 + } 1.844 + int_x_green = (png_fixed_point)uint_x; 1.845 + int_y_green = (png_fixed_point)uint_y; 1.846 + 1.847 + uint_x = png_get_uint_32(buf + 24); 1.848 + uint_y = png_get_uint_32(buf + 28); 1.849 + if (uint_x + uint_y > 100000L) 1.850 + { 1.851 + png_warning(png_ptr, "Invalid cHRM blue point"); 1.852 + return; 1.853 + } 1.854 + int_x_blue = (png_fixed_point)uint_x; 1.855 + int_y_blue = (png_fixed_point)uint_y; 1.856 + 1.857 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.858 + white_x = (float)int_x_white / (float)100000.0; 1.859 + white_y = (float)int_y_white / (float)100000.0; 1.860 + red_x = (float)int_x_red / (float)100000.0; 1.861 + red_y = (float)int_y_red / (float)100000.0; 1.862 + green_x = (float)int_x_green / (float)100000.0; 1.863 + green_y = (float)int_y_green / (float)100000.0; 1.864 + blue_x = (float)int_x_blue / (float)100000.0; 1.865 + blue_y = (float)int_y_blue / (float)100000.0; 1.866 +#endif 1.867 + 1.868 +#if defined(PNG_READ_sRGB_SUPPORTED) 1.869 + if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) 1.870 + { 1.871 + if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || 1.872 + PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || 1.873 + PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || 1.874 + PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || 1.875 + PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || 1.876 + PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || 1.877 + PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || 1.878 + PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) 1.879 + { 1.880 + png_warning(png_ptr, 1.881 + "Ignoring incorrect cHRM value when sRGB is also present"); 1.882 +#ifndef PNG_NO_CONSOLE_IO 1.883 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.884 + fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", 1.885 + white_x, white_y, red_x, red_y); 1.886 + fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", 1.887 + green_x, green_y, blue_x, blue_y); 1.888 +#else 1.889 + fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", 1.890 + int_x_white, int_y_white, int_x_red, int_y_red); 1.891 + fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", 1.892 + int_x_green, int_y_green, int_x_blue, int_y_blue); 1.893 +#endif 1.894 +#endif /* PNG_NO_CONSOLE_IO */ 1.895 + } 1.896 + return; 1.897 + } 1.898 +#endif /* PNG_READ_sRGB_SUPPORTED */ 1.899 + 1.900 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.901 + png_set_cHRM(png_ptr, info_ptr, 1.902 + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); 1.903 +#endif 1.904 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.905 + png_set_cHRM_fixed(png_ptr, info_ptr, 1.906 + int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 1.907 + int_y_green, int_x_blue, int_y_blue); 1.908 +#endif 1.909 +} 1.910 +#endif 1.911 + 1.912 +#if defined(PNG_READ_sRGB_SUPPORTED) 1.913 +void /* PRIVATE */ 1.914 +png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.915 +{ 1.916 + int intent; 1.917 + png_byte buf[1]; 1.918 + 1.919 + png_debug(1, "in png_handle_sRGB\n"); 1.920 + 1.921 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.922 + png_error(png_ptr, "Missing IHDR before sRGB"); 1.923 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.924 + { 1.925 + png_warning(png_ptr, "Invalid sRGB after IDAT"); 1.926 + png_crc_finish(png_ptr, length); 1.927 + return; 1.928 + } 1.929 + else if (png_ptr->mode & PNG_HAVE_PLTE) 1.930 + /* Should be an error, but we can cope with it */ 1.931 + png_warning(png_ptr, "Out of place sRGB chunk"); 1.932 + 1.933 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 1.934 + { 1.935 + png_warning(png_ptr, "Duplicate sRGB chunk"); 1.936 + png_crc_finish(png_ptr, length); 1.937 + return; 1.938 + } 1.939 + 1.940 + if (length != 1) 1.941 + { 1.942 + png_warning(png_ptr, "Incorrect sRGB chunk length"); 1.943 + png_crc_finish(png_ptr, length); 1.944 + return; 1.945 + } 1.946 + 1.947 + png_crc_read(png_ptr, buf, 1); 1.948 + if (png_crc_finish(png_ptr, 0)) 1.949 + return; 1.950 + 1.951 + intent = buf[0]; 1.952 + /* check for bad intent */ 1.953 + if (intent >= PNG_sRGB_INTENT_LAST) 1.954 + { 1.955 + png_warning(png_ptr, "Unknown sRGB intent"); 1.956 + return; 1.957 + } 1.958 + 1.959 +#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) 1.960 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) 1.961 + { 1.962 + png_fixed_point igamma; 1.963 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.964 + igamma=info_ptr->int_gamma; 1.965 +#else 1.966 +# ifdef PNG_FLOATING_POINT_SUPPORTED 1.967 + igamma=(png_fixed_point)(info_ptr->gamma * 100000.); 1.968 +# endif 1.969 +#endif 1.970 + if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 1.971 + { 1.972 + png_warning(png_ptr, 1.973 + "Ignoring incorrect gAMA value when sRGB is also present"); 1.974 +#ifndef PNG_NO_CONSOLE_IO 1.975 +# ifdef PNG_FIXED_POINT_SUPPORTED 1.976 + fprintf(stderr, "incorrect gamma=(%d/100000)\n", 1.977 + (int)png_ptr->int_gamma); 1.978 +# else 1.979 +# ifdef PNG_FLOATING_POINT_SUPPORTED 1.980 + fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma); 1.981 +# endif 1.982 +# endif 1.983 +#endif 1.984 + } 1.985 + } 1.986 +#endif /* PNG_READ_gAMA_SUPPORTED */ 1.987 + 1.988 +#ifdef PNG_READ_cHRM_SUPPORTED 1.989 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.990 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) 1.991 + if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || 1.992 + PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || 1.993 + PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || 1.994 + PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || 1.995 + PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || 1.996 + PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || 1.997 + PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || 1.998 + PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) 1.999 + { 1.1000 + png_warning(png_ptr, 1.1001 + "Ignoring incorrect cHRM value when sRGB is also present"); 1.1002 + } 1.1003 +#endif /* PNG_FIXED_POINT_SUPPORTED */ 1.1004 +#endif /* PNG_READ_cHRM_SUPPORTED */ 1.1005 + 1.1006 + png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); 1.1007 +} 1.1008 +#endif /* PNG_READ_sRGB_SUPPORTED */ 1.1009 + 1.1010 +#if defined(PNG_READ_iCCP_SUPPORTED) 1.1011 +void /* PRIVATE */ 1.1012 +png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1013 +/* Note: this does not properly handle chunks that are > 64K under DOS */ 1.1014 +{ 1.1015 + png_byte compression_type; 1.1016 + png_bytep pC; 1.1017 + png_charp profile; 1.1018 + png_uint_32 skip = 0; 1.1019 + png_uint_32 profile_size, profile_length; 1.1020 + png_size_t slength, prefix_length, data_length; 1.1021 + 1.1022 + png_debug(1, "in png_handle_iCCP\n"); 1.1023 + 1.1024 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1025 + png_error(png_ptr, "Missing IHDR before iCCP"); 1.1026 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1027 + { 1.1028 + png_warning(png_ptr, "Invalid iCCP after IDAT"); 1.1029 + png_crc_finish(png_ptr, length); 1.1030 + return; 1.1031 + } 1.1032 + else if (png_ptr->mode & PNG_HAVE_PLTE) 1.1033 + /* Should be an error, but we can cope with it */ 1.1034 + png_warning(png_ptr, "Out of place iCCP chunk"); 1.1035 + 1.1036 + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) 1.1037 + { 1.1038 + png_warning(png_ptr, "Duplicate iCCP chunk"); 1.1039 + png_crc_finish(png_ptr, length); 1.1040 + return; 1.1041 + } 1.1042 + 1.1043 +#ifdef PNG_MAX_MALLOC_64K 1.1044 + if (length > (png_uint_32)65535L) 1.1045 + { 1.1046 + png_warning(png_ptr, "iCCP chunk too large to fit in memory"); 1.1047 + skip = length - (png_uint_32)65535L; 1.1048 + length = (png_uint_32)65535L; 1.1049 + } 1.1050 +#endif 1.1051 + 1.1052 + png_free(png_ptr, png_ptr->chunkdata); 1.1053 + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1.1054 + slength = (png_size_t)length; 1.1055 + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1.1056 + 1.1057 + if (png_crc_finish(png_ptr, skip)) 1.1058 + { 1.1059 + png_free(png_ptr, png_ptr->chunkdata); 1.1060 + png_ptr->chunkdata = NULL; 1.1061 + return; 1.1062 + } 1.1063 + 1.1064 + png_ptr->chunkdata[slength] = 0x00; 1.1065 + 1.1066 + for (profile = png_ptr->chunkdata; *profile; profile++) 1.1067 + /* empty loop to find end of name */ ; 1.1068 + 1.1069 + ++profile; 1.1070 + 1.1071 + /* there should be at least one zero (the compression type byte) 1.1072 + following the separator, and we should be on it */ 1.1073 + if ( profile >= png_ptr->chunkdata + slength - 1) 1.1074 + { 1.1075 + png_free(png_ptr, png_ptr->chunkdata); 1.1076 + png_ptr->chunkdata = NULL; 1.1077 + png_warning(png_ptr, "Malformed iCCP chunk"); 1.1078 + return; 1.1079 + } 1.1080 + 1.1081 + /* compression_type should always be zero */ 1.1082 + compression_type = *profile++; 1.1083 + if (compression_type) 1.1084 + { 1.1085 + png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); 1.1086 + compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 1.1087 + wrote nonzero) */ 1.1088 + } 1.1089 + 1.1090 + prefix_length = profile - png_ptr->chunkdata; 1.1091 + png_decompress_chunk(png_ptr, compression_type, 1.1092 + slength, prefix_length, &data_length); 1.1093 + 1.1094 + profile_length = data_length - prefix_length; 1.1095 + 1.1096 + if ( prefix_length > data_length || profile_length < 4) 1.1097 + { 1.1098 + png_free(png_ptr, png_ptr->chunkdata); 1.1099 + png_ptr->chunkdata = NULL; 1.1100 + png_warning(png_ptr, "Profile size field missing from iCCP chunk"); 1.1101 + return; 1.1102 + } 1.1103 + 1.1104 + /* Check the profile_size recorded in the first 32 bits of the ICC profile */ 1.1105 + pC = (png_bytep)(png_ptr->chunkdata + prefix_length); 1.1106 + profile_size = ((*(pC ))<<24) | 1.1107 + ((*(pC + 1))<<16) | 1.1108 + ((*(pC + 2))<< 8) | 1.1109 + ((*(pC + 3)) ); 1.1110 + 1.1111 + if (profile_size < profile_length) 1.1112 + profile_length = profile_size; 1.1113 + 1.1114 + if (profile_size > profile_length) 1.1115 + { 1.1116 + png_free(png_ptr, png_ptr->chunkdata); 1.1117 + png_ptr->chunkdata = NULL; 1.1118 + png_warning(png_ptr, "Ignoring truncated iCCP profile."); 1.1119 + return; 1.1120 + } 1.1121 + 1.1122 + png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, 1.1123 + compression_type, png_ptr->chunkdata + prefix_length, profile_length); 1.1124 + png_free(png_ptr, png_ptr->chunkdata); 1.1125 + png_ptr->chunkdata = NULL; 1.1126 +} 1.1127 +#endif /* PNG_READ_iCCP_SUPPORTED */ 1.1128 + 1.1129 +#if defined(PNG_READ_sPLT_SUPPORTED) 1.1130 +void /* PRIVATE */ 1.1131 +png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1132 +/* Note: this does not properly handle chunks that are > 64K under DOS */ 1.1133 +{ 1.1134 + png_bytep entry_start; 1.1135 + png_sPLT_t new_palette; 1.1136 +#ifdef PNG_NO_POINTER_INDEXING 1.1137 + png_sPLT_entryp pp; 1.1138 +#endif 1.1139 + int data_length, entry_size, i; 1.1140 + png_uint_32 skip = 0; 1.1141 + png_size_t slength; 1.1142 + 1.1143 + png_debug(1, "in png_handle_sPLT\n"); 1.1144 + 1.1145 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1146 + png_error(png_ptr, "Missing IHDR before sPLT"); 1.1147 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1148 + { 1.1149 + png_warning(png_ptr, "Invalid sPLT after IDAT"); 1.1150 + png_crc_finish(png_ptr, length); 1.1151 + return; 1.1152 + } 1.1153 + 1.1154 +#ifdef PNG_MAX_MALLOC_64K 1.1155 + if (length > (png_uint_32)65535L) 1.1156 + { 1.1157 + png_warning(png_ptr, "sPLT chunk too large to fit in memory"); 1.1158 + skip = length - (png_uint_32)65535L; 1.1159 + length = (png_uint_32)65535L; 1.1160 + } 1.1161 +#endif 1.1162 + 1.1163 + png_free(png_ptr, png_ptr->chunkdata); 1.1164 + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1.1165 + slength = (png_size_t)length; 1.1166 + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1.1167 + 1.1168 + if (png_crc_finish(png_ptr, skip)) 1.1169 + { 1.1170 + png_free(png_ptr, png_ptr->chunkdata); 1.1171 + png_ptr->chunkdata = NULL; 1.1172 + return; 1.1173 + } 1.1174 + 1.1175 + png_ptr->chunkdata[slength] = 0x00; 1.1176 + 1.1177 + for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; entry_start++) 1.1178 + /* empty loop to find end of name */ ; 1.1179 + ++entry_start; 1.1180 + 1.1181 + /* a sample depth should follow the separator, and we should be on it */ 1.1182 + if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) 1.1183 + { 1.1184 + png_free(png_ptr, png_ptr->chunkdata); 1.1185 + png_ptr->chunkdata = NULL; 1.1186 + png_warning(png_ptr, "malformed sPLT chunk"); 1.1187 + return; 1.1188 + } 1.1189 + 1.1190 + new_palette.depth = *entry_start++; 1.1191 + entry_size = (new_palette.depth == 8 ? 6 : 10); 1.1192 + data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata)); 1.1193 + 1.1194 + /* integrity-check the data length */ 1.1195 + if (data_length % entry_size) 1.1196 + { 1.1197 + png_free(png_ptr, png_ptr->chunkdata); 1.1198 + png_ptr->chunkdata = NULL; 1.1199 + png_warning(png_ptr, "sPLT chunk has bad length"); 1.1200 + return; 1.1201 + } 1.1202 + 1.1203 + new_palette.nentries = (png_int_32) ( data_length / entry_size); 1.1204 + if ((png_uint_32) new_palette.nentries > 1.1205 + (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry))) 1.1206 + { 1.1207 + png_warning(png_ptr, "sPLT chunk too long"); 1.1208 + return; 1.1209 + } 1.1210 + new_palette.entries = (png_sPLT_entryp)png_malloc_warn( 1.1211 + png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); 1.1212 + if (new_palette.entries == NULL) 1.1213 + { 1.1214 + png_warning(png_ptr, "sPLT chunk requires too much memory"); 1.1215 + return; 1.1216 + } 1.1217 + 1.1218 +#ifndef PNG_NO_POINTER_INDEXING 1.1219 + for (i = 0; i < new_palette.nentries; i++) 1.1220 + { 1.1221 + png_sPLT_entryp pp = new_palette.entries + i; 1.1222 + 1.1223 + if (new_palette.depth == 8) 1.1224 + { 1.1225 + pp->red = *entry_start++; 1.1226 + pp->green = *entry_start++; 1.1227 + pp->blue = *entry_start++; 1.1228 + pp->alpha = *entry_start++; 1.1229 + } 1.1230 + else 1.1231 + { 1.1232 + pp->red = png_get_uint_16(entry_start); entry_start += 2; 1.1233 + pp->green = png_get_uint_16(entry_start); entry_start += 2; 1.1234 + pp->blue = png_get_uint_16(entry_start); entry_start += 2; 1.1235 + pp->alpha = png_get_uint_16(entry_start); entry_start += 2; 1.1236 + } 1.1237 + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1.1238 + } 1.1239 +#else 1.1240 + pp = new_palette.entries; 1.1241 + for (i = 0; i < new_palette.nentries; i++) 1.1242 + { 1.1243 + 1.1244 + if (new_palette.depth == 8) 1.1245 + { 1.1246 + pp[i].red = *entry_start++; 1.1247 + pp[i].green = *entry_start++; 1.1248 + pp[i].blue = *entry_start++; 1.1249 + pp[i].alpha = *entry_start++; 1.1250 + } 1.1251 + else 1.1252 + { 1.1253 + pp[i].red = png_get_uint_16(entry_start); entry_start += 2; 1.1254 + pp[i].green = png_get_uint_16(entry_start); entry_start += 2; 1.1255 + pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; 1.1256 + pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; 1.1257 + } 1.1258 + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1.1259 + } 1.1260 +#endif 1.1261 + 1.1262 + /* discard all chunk data except the name and stash that */ 1.1263 + new_palette.name = png_ptr->chunkdata; 1.1264 + 1.1265 + png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); 1.1266 + 1.1267 + png_free(png_ptr, png_ptr->chunkdata); 1.1268 + png_ptr->chunkdata = NULL; 1.1269 + png_free(png_ptr, new_palette.entries); 1.1270 +} 1.1271 +#endif /* PNG_READ_sPLT_SUPPORTED */ 1.1272 + 1.1273 +#if defined(PNG_READ_tRNS_SUPPORTED) 1.1274 +void /* PRIVATE */ 1.1275 +png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1276 +{ 1.1277 + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; 1.1278 + 1.1279 + png_debug(1, "in png_handle_tRNS\n"); 1.1280 + 1.1281 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1282 + png_error(png_ptr, "Missing IHDR before tRNS"); 1.1283 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1284 + { 1.1285 + png_warning(png_ptr, "Invalid tRNS after IDAT"); 1.1286 + png_crc_finish(png_ptr, length); 1.1287 + return; 1.1288 + } 1.1289 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 1.1290 + { 1.1291 + png_warning(png_ptr, "Duplicate tRNS chunk"); 1.1292 + png_crc_finish(png_ptr, length); 1.1293 + return; 1.1294 + } 1.1295 + 1.1296 + if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1.1297 + { 1.1298 + png_byte buf[2]; 1.1299 + 1.1300 + if (length != 2) 1.1301 + { 1.1302 + png_warning(png_ptr, "Incorrect tRNS chunk length"); 1.1303 + png_crc_finish(png_ptr, length); 1.1304 + return; 1.1305 + } 1.1306 + 1.1307 + png_crc_read(png_ptr, buf, 2); 1.1308 + png_ptr->num_trans = 1; 1.1309 + png_ptr->trans_values.gray = png_get_uint_16(buf); 1.1310 + } 1.1311 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1.1312 + { 1.1313 + png_byte buf[6]; 1.1314 + 1.1315 + if (length != 6) 1.1316 + { 1.1317 + png_warning(png_ptr, "Incorrect tRNS chunk length"); 1.1318 + png_crc_finish(png_ptr, length); 1.1319 + return; 1.1320 + } 1.1321 + png_crc_read(png_ptr, buf, (png_size_t)length); 1.1322 + png_ptr->num_trans = 1; 1.1323 + png_ptr->trans_values.red = png_get_uint_16(buf); 1.1324 + png_ptr->trans_values.green = png_get_uint_16(buf + 2); 1.1325 + png_ptr->trans_values.blue = png_get_uint_16(buf + 4); 1.1326 + } 1.1327 + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.1328 + { 1.1329 + if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1.1330 + { 1.1331 + /* Should be an error, but we can cope with it. */ 1.1332 + png_warning(png_ptr, "Missing PLTE before tRNS"); 1.1333 + } 1.1334 + if (length > (png_uint_32)png_ptr->num_palette || 1.1335 + length > PNG_MAX_PALETTE_LENGTH) 1.1336 + { 1.1337 + png_warning(png_ptr, "Incorrect tRNS chunk length"); 1.1338 + png_crc_finish(png_ptr, length); 1.1339 + return; 1.1340 + } 1.1341 + if (length == 0) 1.1342 + { 1.1343 + png_warning(png_ptr, "Zero length tRNS chunk"); 1.1344 + png_crc_finish(png_ptr, length); 1.1345 + return; 1.1346 + } 1.1347 + png_crc_read(png_ptr, readbuf, (png_size_t)length); 1.1348 + png_ptr->num_trans = (png_uint_16)length; 1.1349 + } 1.1350 + else 1.1351 + { 1.1352 + png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); 1.1353 + png_crc_finish(png_ptr, length); 1.1354 + return; 1.1355 + } 1.1356 + 1.1357 + if (png_crc_finish(png_ptr, 0)) 1.1358 + { 1.1359 + png_ptr->num_trans = 0; 1.1360 + return; 1.1361 + } 1.1362 + 1.1363 + png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, 1.1364 + &(png_ptr->trans_values)); 1.1365 +} 1.1366 +#endif 1.1367 + 1.1368 +#if defined(PNG_READ_bKGD_SUPPORTED) 1.1369 +void /* PRIVATE */ 1.1370 +png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1371 +{ 1.1372 + png_size_t truelen; 1.1373 + png_byte buf[6]; 1.1374 + 1.1375 + png_debug(1, "in png_handle_bKGD\n"); 1.1376 + 1.1377 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1378 + png_error(png_ptr, "Missing IHDR before bKGD"); 1.1379 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1380 + { 1.1381 + png_warning(png_ptr, "Invalid bKGD after IDAT"); 1.1382 + png_crc_finish(png_ptr, length); 1.1383 + return; 1.1384 + } 1.1385 + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 1.1386 + !(png_ptr->mode & PNG_HAVE_PLTE)) 1.1387 + { 1.1388 + png_warning(png_ptr, "Missing PLTE before bKGD"); 1.1389 + png_crc_finish(png_ptr, length); 1.1390 + return; 1.1391 + } 1.1392 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) 1.1393 + { 1.1394 + png_warning(png_ptr, "Duplicate bKGD chunk"); 1.1395 + png_crc_finish(png_ptr, length); 1.1396 + return; 1.1397 + } 1.1398 + 1.1399 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.1400 + truelen = 1; 1.1401 + else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1.1402 + truelen = 6; 1.1403 + else 1.1404 + truelen = 2; 1.1405 + 1.1406 + if (length != truelen) 1.1407 + { 1.1408 + png_warning(png_ptr, "Incorrect bKGD chunk length"); 1.1409 + png_crc_finish(png_ptr, length); 1.1410 + return; 1.1411 + } 1.1412 + 1.1413 + png_crc_read(png_ptr, buf, truelen); 1.1414 + if (png_crc_finish(png_ptr, 0)) 1.1415 + return; 1.1416 + 1.1417 + /* We convert the index value into RGB components so that we can allow 1.1418 + * arbitrary RGB values for background when we have transparency, and 1.1419 + * so it is easy to determine the RGB values of the background color 1.1420 + * from the info_ptr struct. */ 1.1421 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.1422 + { 1.1423 + png_ptr->background.index = buf[0]; 1.1424 + if (info_ptr && info_ptr->num_palette) 1.1425 + { 1.1426 + if (buf[0] > info_ptr->num_palette) 1.1427 + { 1.1428 + png_warning(png_ptr, "Incorrect bKGD chunk index value"); 1.1429 + return; 1.1430 + } 1.1431 + png_ptr->background.red = 1.1432 + (png_uint_16)png_ptr->palette[buf[0]].red; 1.1433 + png_ptr->background.green = 1.1434 + (png_uint_16)png_ptr->palette[buf[0]].green; 1.1435 + png_ptr->background.blue = 1.1436 + (png_uint_16)png_ptr->palette[buf[0]].blue; 1.1437 + } 1.1438 + } 1.1439 + else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ 1.1440 + { 1.1441 + png_ptr->background.red = 1.1442 + png_ptr->background.green = 1.1443 + png_ptr->background.blue = 1.1444 + png_ptr->background.gray = png_get_uint_16(buf); 1.1445 + } 1.1446 + else 1.1447 + { 1.1448 + png_ptr->background.red = png_get_uint_16(buf); 1.1449 + png_ptr->background.green = png_get_uint_16(buf + 2); 1.1450 + png_ptr->background.blue = png_get_uint_16(buf + 4); 1.1451 + } 1.1452 + 1.1453 + png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); 1.1454 +} 1.1455 +#endif 1.1456 + 1.1457 +#if defined(PNG_READ_hIST_SUPPORTED) 1.1458 +void /* PRIVATE */ 1.1459 +png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1460 +{ 1.1461 + unsigned int num, i; 1.1462 + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; 1.1463 + 1.1464 + png_debug(1, "in png_handle_hIST\n"); 1.1465 + 1.1466 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1467 + png_error(png_ptr, "Missing IHDR before hIST"); 1.1468 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1469 + { 1.1470 + png_warning(png_ptr, "Invalid hIST after IDAT"); 1.1471 + png_crc_finish(png_ptr, length); 1.1472 + return; 1.1473 + } 1.1474 + else if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1.1475 + { 1.1476 + png_warning(png_ptr, "Missing PLTE before hIST"); 1.1477 + png_crc_finish(png_ptr, length); 1.1478 + return; 1.1479 + } 1.1480 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) 1.1481 + { 1.1482 + png_warning(png_ptr, "Duplicate hIST chunk"); 1.1483 + png_crc_finish(png_ptr, length); 1.1484 + return; 1.1485 + } 1.1486 + 1.1487 + num = length / 2 ; 1.1488 + if (num != (unsigned int) png_ptr->num_palette || num > 1.1489 + (unsigned int) PNG_MAX_PALETTE_LENGTH) 1.1490 + { 1.1491 + png_warning(png_ptr, "Incorrect hIST chunk length"); 1.1492 + png_crc_finish(png_ptr, length); 1.1493 + return; 1.1494 + } 1.1495 + 1.1496 + for (i = 0; i < num; i++) 1.1497 + { 1.1498 + png_byte buf[2]; 1.1499 + 1.1500 + png_crc_read(png_ptr, buf, 2); 1.1501 + readbuf[i] = png_get_uint_16(buf); 1.1502 + } 1.1503 + 1.1504 + if (png_crc_finish(png_ptr, 0)) 1.1505 + return; 1.1506 + 1.1507 + png_set_hIST(png_ptr, info_ptr, readbuf); 1.1508 +} 1.1509 +#endif 1.1510 + 1.1511 +#if defined(PNG_READ_pHYs_SUPPORTED) 1.1512 +void /* PRIVATE */ 1.1513 +png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1514 +{ 1.1515 + png_byte buf[9]; 1.1516 + png_uint_32 res_x, res_y; 1.1517 + int unit_type; 1.1518 + 1.1519 + png_debug(1, "in png_handle_pHYs\n"); 1.1520 + 1.1521 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1522 + png_error(png_ptr, "Missing IHDR before pHYs"); 1.1523 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1524 + { 1.1525 + png_warning(png_ptr, "Invalid pHYs after IDAT"); 1.1526 + png_crc_finish(png_ptr, length); 1.1527 + return; 1.1528 + } 1.1529 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) 1.1530 + { 1.1531 + png_warning(png_ptr, "Duplicate pHYs chunk"); 1.1532 + png_crc_finish(png_ptr, length); 1.1533 + return; 1.1534 + } 1.1535 + 1.1536 + if (length != 9) 1.1537 + { 1.1538 + png_warning(png_ptr, "Incorrect pHYs chunk length"); 1.1539 + png_crc_finish(png_ptr, length); 1.1540 + return; 1.1541 + } 1.1542 + 1.1543 + png_crc_read(png_ptr, buf, 9); 1.1544 + if (png_crc_finish(png_ptr, 0)) 1.1545 + return; 1.1546 + 1.1547 + res_x = png_get_uint_32(buf); 1.1548 + res_y = png_get_uint_32(buf + 4); 1.1549 + unit_type = buf[8]; 1.1550 + png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); 1.1551 +} 1.1552 +#endif 1.1553 + 1.1554 +#if defined(PNG_READ_oFFs_SUPPORTED) 1.1555 +void /* PRIVATE */ 1.1556 +png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1557 +{ 1.1558 + png_byte buf[9]; 1.1559 + png_int_32 offset_x, offset_y; 1.1560 + int unit_type; 1.1561 + 1.1562 + png_debug(1, "in png_handle_oFFs\n"); 1.1563 + 1.1564 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1565 + png_error(png_ptr, "Missing IHDR before oFFs"); 1.1566 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1567 + { 1.1568 + png_warning(png_ptr, "Invalid oFFs after IDAT"); 1.1569 + png_crc_finish(png_ptr, length); 1.1570 + return; 1.1571 + } 1.1572 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) 1.1573 + { 1.1574 + png_warning(png_ptr, "Duplicate oFFs chunk"); 1.1575 + png_crc_finish(png_ptr, length); 1.1576 + return; 1.1577 + } 1.1578 + 1.1579 + if (length != 9) 1.1580 + { 1.1581 + png_warning(png_ptr, "Incorrect oFFs chunk length"); 1.1582 + png_crc_finish(png_ptr, length); 1.1583 + return; 1.1584 + } 1.1585 + 1.1586 + png_crc_read(png_ptr, buf, 9); 1.1587 + if (png_crc_finish(png_ptr, 0)) 1.1588 + return; 1.1589 + 1.1590 + offset_x = png_get_int_32(buf); 1.1591 + offset_y = png_get_int_32(buf + 4); 1.1592 + unit_type = buf[8]; 1.1593 + png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); 1.1594 +} 1.1595 +#endif 1.1596 + 1.1597 +#if defined(PNG_READ_pCAL_SUPPORTED) 1.1598 +/* read the pCAL chunk (described in the PNG Extensions document) */ 1.1599 +void /* PRIVATE */ 1.1600 +png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1601 +{ 1.1602 + png_int_32 X0, X1; 1.1603 + png_byte type, nparams; 1.1604 + png_charp buf, units, endptr; 1.1605 + png_charpp params; 1.1606 + png_size_t slength; 1.1607 + int i; 1.1608 + 1.1609 + png_debug(1, "in png_handle_pCAL\n"); 1.1610 + 1.1611 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1612 + png_error(png_ptr, "Missing IHDR before pCAL"); 1.1613 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1614 + { 1.1615 + png_warning(png_ptr, "Invalid pCAL after IDAT"); 1.1616 + png_crc_finish(png_ptr, length); 1.1617 + return; 1.1618 + } 1.1619 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) 1.1620 + { 1.1621 + png_warning(png_ptr, "Duplicate pCAL chunk"); 1.1622 + png_crc_finish(png_ptr, length); 1.1623 + return; 1.1624 + } 1.1625 + 1.1626 + png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n", 1.1627 + length + 1); 1.1628 + png_free(png_ptr, png_ptr->chunkdata); 1.1629 + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1.1630 + if (png_ptr->chunkdata == NULL) 1.1631 + { 1.1632 + png_warning(png_ptr, "No memory for pCAL purpose."); 1.1633 + return; 1.1634 + } 1.1635 + slength = (png_size_t)length; 1.1636 + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1.1637 + 1.1638 + if (png_crc_finish(png_ptr, 0)) 1.1639 + { 1.1640 + png_free(png_ptr, png_ptr->chunkdata); 1.1641 + png_ptr->chunkdata = NULL; 1.1642 + return; 1.1643 + } 1.1644 + 1.1645 + png_ptr->chunkdata[slength] = 0x00; /* null terminate the last string */ 1.1646 + 1.1647 + png_debug(3, "Finding end of pCAL purpose string\n"); 1.1648 + for (buf = png_ptr->chunkdata; *buf; buf++) 1.1649 + /* empty loop */ ; 1.1650 + 1.1651 + endptr = png_ptr->chunkdata + slength; 1.1652 + 1.1653 + /* We need to have at least 12 bytes after the purpose string 1.1654 + in order to get the parameter information. */ 1.1655 + if (endptr <= buf + 12) 1.1656 + { 1.1657 + png_warning(png_ptr, "Invalid pCAL data"); 1.1658 + png_free(png_ptr, png_ptr->chunkdata); 1.1659 + png_ptr->chunkdata = NULL; 1.1660 + return; 1.1661 + } 1.1662 + 1.1663 + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n"); 1.1664 + X0 = png_get_int_32((png_bytep)buf+1); 1.1665 + X1 = png_get_int_32((png_bytep)buf+5); 1.1666 + type = buf[9]; 1.1667 + nparams = buf[10]; 1.1668 + units = buf + 11; 1.1669 + 1.1670 + png_debug(3, "Checking pCAL equation type and number of parameters\n"); 1.1671 + /* Check that we have the right number of parameters for known 1.1672 + equation types. */ 1.1673 + if ((type == PNG_EQUATION_LINEAR && nparams != 2) || 1.1674 + (type == PNG_EQUATION_BASE_E && nparams != 3) || 1.1675 + (type == PNG_EQUATION_ARBITRARY && nparams != 3) || 1.1676 + (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) 1.1677 + { 1.1678 + png_warning(png_ptr, "Invalid pCAL parameters for equation type"); 1.1679 + png_free(png_ptr, png_ptr->chunkdata); 1.1680 + png_ptr->chunkdata = NULL; 1.1681 + return; 1.1682 + } 1.1683 + else if (type >= PNG_EQUATION_LAST) 1.1684 + { 1.1685 + png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 1.1686 + } 1.1687 + 1.1688 + for (buf = units; *buf; buf++) 1.1689 + /* Empty loop to move past the units string. */ ; 1.1690 + 1.1691 + png_debug(3, "Allocating pCAL parameters array\n"); 1.1692 + params = (png_charpp)png_malloc_warn(png_ptr, 1.1693 + (png_uint_32)(nparams * png_sizeof(png_charp))) ; 1.1694 + if (params == NULL) 1.1695 + { 1.1696 + png_free(png_ptr, png_ptr->chunkdata); 1.1697 + png_ptr->chunkdata = NULL; 1.1698 + png_warning(png_ptr, "No memory for pCAL params."); 1.1699 + return; 1.1700 + } 1.1701 + 1.1702 + /* Get pointers to the start of each parameter string. */ 1.1703 + for (i = 0; i < (int)nparams; i++) 1.1704 + { 1.1705 + buf++; /* Skip the null string terminator from previous parameter. */ 1.1706 + 1.1707 + png_debug1(3, "Reading pCAL parameter %d\n", i); 1.1708 + for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) 1.1709 + /* Empty loop to move past each parameter string */ ; 1.1710 + 1.1711 + /* Make sure we haven't run out of data yet */ 1.1712 + if (buf > endptr) 1.1713 + { 1.1714 + png_warning(png_ptr, "Invalid pCAL data"); 1.1715 + png_free(png_ptr, png_ptr->chunkdata); 1.1716 + png_ptr->chunkdata = NULL; 1.1717 + png_free(png_ptr, params); 1.1718 + return; 1.1719 + } 1.1720 + } 1.1721 + 1.1722 + png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, 1.1723 + units, params); 1.1724 + 1.1725 + png_free(png_ptr, png_ptr->chunkdata); 1.1726 + png_ptr->chunkdata = NULL; 1.1727 + png_free(png_ptr, params); 1.1728 +} 1.1729 +#endif 1.1730 + 1.1731 +#if defined(PNG_READ_sCAL_SUPPORTED) 1.1732 +/* read the sCAL chunk */ 1.1733 +void /* PRIVATE */ 1.1734 +png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1735 +{ 1.1736 + png_charp ep; 1.1737 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.1738 + double width, height; 1.1739 + png_charp vp; 1.1740 +#else 1.1741 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.1742 + png_charp swidth, sheight; 1.1743 +#endif 1.1744 +#endif 1.1745 + png_size_t slength; 1.1746 + 1.1747 + png_debug(1, "in png_handle_sCAL\n"); 1.1748 + 1.1749 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1750 + png_error(png_ptr, "Missing IHDR before sCAL"); 1.1751 + else if (png_ptr->mode & PNG_HAVE_IDAT) 1.1752 + { 1.1753 + png_warning(png_ptr, "Invalid sCAL after IDAT"); 1.1754 + png_crc_finish(png_ptr, length); 1.1755 + return; 1.1756 + } 1.1757 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) 1.1758 + { 1.1759 + png_warning(png_ptr, "Duplicate sCAL chunk"); 1.1760 + png_crc_finish(png_ptr, length); 1.1761 + return; 1.1762 + } 1.1763 + 1.1764 + png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n", 1.1765 + length + 1); 1.1766 + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1.1767 + if (png_ptr->chunkdata == NULL) 1.1768 + { 1.1769 + png_warning(png_ptr, "Out of memory while processing sCAL chunk"); 1.1770 + return; 1.1771 + } 1.1772 + slength = (png_size_t)length; 1.1773 + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1.1774 + 1.1775 + if (png_crc_finish(png_ptr, 0)) 1.1776 + { 1.1777 + png_free(png_ptr, png_ptr->chunkdata); 1.1778 + png_ptr->chunkdata = NULL; 1.1779 + return; 1.1780 + } 1.1781 + 1.1782 + png_ptr->chunkdata[slength] = 0x00; /* null terminate the last string */ 1.1783 + 1.1784 + ep = png_ptr->chunkdata + 1; /* skip unit byte */ 1.1785 + 1.1786 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.1787 + width = png_strtod(png_ptr, ep, &vp); 1.1788 + if (*vp) 1.1789 + { 1.1790 + png_warning(png_ptr, "malformed width string in sCAL chunk"); 1.1791 + return; 1.1792 + } 1.1793 +#else 1.1794 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.1795 + swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1.1796 + if (swidth == NULL) 1.1797 + { 1.1798 + png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); 1.1799 + return; 1.1800 + } 1.1801 + png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); 1.1802 +#endif 1.1803 +#endif 1.1804 + 1.1805 + for (ep = png_ptr->chunkdata; *ep; ep++) 1.1806 + /* empty loop */ ; 1.1807 + ep++; 1.1808 + 1.1809 + if (png_ptr->chunkdata + slength < ep) 1.1810 + { 1.1811 + png_warning(png_ptr, "Truncated sCAL chunk"); 1.1812 +#if defined(PNG_FIXED_POINT_SUPPORTED) && \ 1.1813 + !defined(PNG_FLOATING_POINT_SUPPORTED) 1.1814 + png_free(png_ptr, swidth); 1.1815 +#endif 1.1816 + png_free(png_ptr, png_ptr->chunkdata); 1.1817 + png_ptr->chunkdata = NULL; 1.1818 + return; 1.1819 + } 1.1820 + 1.1821 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.1822 + height = png_strtod(png_ptr, ep, &vp); 1.1823 + if (*vp) 1.1824 + { 1.1825 + png_warning(png_ptr, "malformed height string in sCAL chunk"); 1.1826 + return; 1.1827 + } 1.1828 +#else 1.1829 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.1830 + sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1.1831 + if (sheight == NULL) 1.1832 + { 1.1833 + png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); 1.1834 + return; 1.1835 + } 1.1836 + png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); 1.1837 +#endif 1.1838 +#endif 1.1839 + 1.1840 + if (png_ptr->chunkdata + slength < ep 1.1841 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.1842 + || width <= 0. || height <= 0. 1.1843 +#endif 1.1844 + ) 1.1845 + { 1.1846 + png_warning(png_ptr, "Invalid sCAL data"); 1.1847 + png_free(png_ptr, png_ptr->chunkdata); 1.1848 + png_ptr->chunkdata = NULL; 1.1849 +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1.1850 + png_free(png_ptr, swidth); 1.1851 + png_free(png_ptr, sheight); 1.1852 +#endif 1.1853 + return; 1.1854 + } 1.1855 + 1.1856 + 1.1857 +#ifdef PNG_FLOATING_POINT_SUPPORTED 1.1858 + png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height); 1.1859 +#else 1.1860 +#ifdef PNG_FIXED_POINT_SUPPORTED 1.1861 + png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); 1.1862 +#endif 1.1863 +#endif 1.1864 + 1.1865 + png_free(png_ptr, png_ptr->chunkdata); 1.1866 + png_ptr->chunkdata = NULL; 1.1867 +#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1.1868 + png_free(png_ptr, swidth); 1.1869 + png_free(png_ptr, sheight); 1.1870 +#endif 1.1871 +} 1.1872 +#endif 1.1873 + 1.1874 +#if defined(PNG_READ_tIME_SUPPORTED) 1.1875 +void /* PRIVATE */ 1.1876 +png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1877 +{ 1.1878 + png_byte buf[7]; 1.1879 + png_time mod_time; 1.1880 + 1.1881 + png_debug(1, "in png_handle_tIME\n"); 1.1882 + 1.1883 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1884 + png_error(png_ptr, "Out of place tIME chunk"); 1.1885 + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 1.1886 + { 1.1887 + png_warning(png_ptr, "Duplicate tIME chunk"); 1.1888 + png_crc_finish(png_ptr, length); 1.1889 + return; 1.1890 + } 1.1891 + 1.1892 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.1893 + png_ptr->mode |= PNG_AFTER_IDAT; 1.1894 + 1.1895 + if (length != 7) 1.1896 + { 1.1897 + png_warning(png_ptr, "Incorrect tIME chunk length"); 1.1898 + png_crc_finish(png_ptr, length); 1.1899 + return; 1.1900 + } 1.1901 + 1.1902 + png_crc_read(png_ptr, buf, 7); 1.1903 + if (png_crc_finish(png_ptr, 0)) 1.1904 + return; 1.1905 + 1.1906 + mod_time.second = buf[6]; 1.1907 + mod_time.minute = buf[5]; 1.1908 + mod_time.hour = buf[4]; 1.1909 + mod_time.day = buf[3]; 1.1910 + mod_time.month = buf[2]; 1.1911 + mod_time.year = png_get_uint_16(buf); 1.1912 + 1.1913 + png_set_tIME(png_ptr, info_ptr, &mod_time); 1.1914 +} 1.1915 +#endif 1.1916 + 1.1917 +#if defined(PNG_READ_tEXt_SUPPORTED) 1.1918 +/* Note: this does not properly handle chunks that are > 64K under DOS */ 1.1919 +void /* PRIVATE */ 1.1920 +png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.1921 +{ 1.1922 + png_textp text_ptr; 1.1923 + png_charp key; 1.1924 + png_charp text; 1.1925 + png_uint_32 skip = 0; 1.1926 + png_size_t slength; 1.1927 + int ret; 1.1928 + 1.1929 + png_debug(1, "in png_handle_tEXt\n"); 1.1930 + 1.1931 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.1932 + png_error(png_ptr, "Missing IHDR before tEXt"); 1.1933 + 1.1934 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.1935 + png_ptr->mode |= PNG_AFTER_IDAT; 1.1936 + 1.1937 +#ifdef PNG_MAX_MALLOC_64K 1.1938 + if (length > (png_uint_32)65535L) 1.1939 + { 1.1940 + png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 1.1941 + skip = length - (png_uint_32)65535L; 1.1942 + length = (png_uint_32)65535L; 1.1943 + } 1.1944 +#endif 1.1945 + 1.1946 + png_free(png_ptr, png_ptr->chunkdata); 1.1947 + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1.1948 + if (png_ptr->chunkdata == NULL) 1.1949 + { 1.1950 + png_warning(png_ptr, "No memory to process text chunk."); 1.1951 + return; 1.1952 + } 1.1953 + slength = (png_size_t)length; 1.1954 + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1.1955 + 1.1956 + if (png_crc_finish(png_ptr, skip)) 1.1957 + { 1.1958 + png_free(png_ptr, png_ptr->chunkdata); 1.1959 + png_ptr->chunkdata = NULL; 1.1960 + return; 1.1961 + } 1.1962 + 1.1963 + key = png_ptr->chunkdata; 1.1964 + key[slength] = 0x00; 1.1965 + 1.1966 + for (text = key; *text; text++) 1.1967 + /* empty loop to find end of key */ ; 1.1968 + 1.1969 + if (text != key + slength) 1.1970 + text++; 1.1971 + 1.1972 + text_ptr = (png_textp)png_malloc_warn(png_ptr, 1.1973 + (png_uint_32)png_sizeof(png_text)); 1.1974 + if (text_ptr == NULL) 1.1975 + { 1.1976 + png_warning(png_ptr, "Not enough memory to process text chunk."); 1.1977 + png_free(png_ptr, png_ptr->chunkdata); 1.1978 + png_ptr->chunkdata = NULL; 1.1979 + return; 1.1980 + } 1.1981 + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 1.1982 + text_ptr->key = key; 1.1983 +#ifdef PNG_iTXt_SUPPORTED 1.1984 + text_ptr->lang = NULL; 1.1985 + text_ptr->lang_key = NULL; 1.1986 + text_ptr->itxt_length = 0; 1.1987 +#endif 1.1988 + text_ptr->text = text; 1.1989 + text_ptr->text_length = png_strlen(text); 1.1990 + 1.1991 + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 1.1992 + 1.1993 + png_free(png_ptr, png_ptr->chunkdata); 1.1994 + png_ptr->chunkdata = NULL; 1.1995 + png_free(png_ptr, text_ptr); 1.1996 + if (ret) 1.1997 + png_warning(png_ptr, "Insufficient memory to process text chunk."); 1.1998 +} 1.1999 +#endif 1.2000 + 1.2001 +#if defined(PNG_READ_zTXt_SUPPORTED) 1.2002 +/* note: this does not correctly handle chunks that are > 64K under DOS */ 1.2003 +void /* PRIVATE */ 1.2004 +png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.2005 +{ 1.2006 + png_textp text_ptr; 1.2007 + png_charp text; 1.2008 + int comp_type; 1.2009 + int ret; 1.2010 + png_size_t slength, prefix_len, data_len; 1.2011 + 1.2012 + png_debug(1, "in png_handle_zTXt\n"); 1.2013 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2014 + png_error(png_ptr, "Missing IHDR before zTXt"); 1.2015 + 1.2016 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.2017 + png_ptr->mode |= PNG_AFTER_IDAT; 1.2018 + 1.2019 +#ifdef PNG_MAX_MALLOC_64K 1.2020 + /* We will no doubt have problems with chunks even half this size, but 1.2021 + there is no hard and fast rule to tell us where to stop. */ 1.2022 + if (length > (png_uint_32)65535L) 1.2023 + { 1.2024 + png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 1.2025 + png_crc_finish(png_ptr, length); 1.2026 + return; 1.2027 + } 1.2028 +#endif 1.2029 + 1.2030 + png_free(png_ptr, png_ptr->chunkdata); 1.2031 + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1.2032 + if (png_ptr->chunkdata == NULL) 1.2033 + { 1.2034 + png_warning(png_ptr, "Out of memory processing zTXt chunk."); 1.2035 + return; 1.2036 + } 1.2037 + slength = (png_size_t)length; 1.2038 + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1.2039 + if (png_crc_finish(png_ptr, 0)) 1.2040 + { 1.2041 + png_free(png_ptr, png_ptr->chunkdata); 1.2042 + png_ptr->chunkdata = NULL; 1.2043 + return; 1.2044 + } 1.2045 + 1.2046 + png_ptr->chunkdata[slength] = 0x00; 1.2047 + 1.2048 + for (text = png_ptr->chunkdata; *text; text++) 1.2049 + /* empty loop */ ; 1.2050 + 1.2051 + /* zTXt must have some text after the chunkdataword */ 1.2052 + if (text >= png_ptr->chunkdata + slength - 2) 1.2053 + { 1.2054 + png_warning(png_ptr, "Truncated zTXt chunk"); 1.2055 + png_free(png_ptr, png_ptr->chunkdata); 1.2056 + png_ptr->chunkdata = NULL; 1.2057 + return; 1.2058 + } 1.2059 + else 1.2060 + { 1.2061 + comp_type = *(++text); 1.2062 + if (comp_type != PNG_TEXT_COMPRESSION_zTXt) 1.2063 + { 1.2064 + png_warning(png_ptr, "Unknown compression type in zTXt chunk"); 1.2065 + comp_type = PNG_TEXT_COMPRESSION_zTXt; 1.2066 + } 1.2067 + text++; /* skip the compression_method byte */ 1.2068 + } 1.2069 + prefix_len = text - png_ptr->chunkdata; 1.2070 + 1.2071 + png_decompress_chunk(png_ptr, comp_type, 1.2072 + (png_size_t)length, prefix_len, &data_len); 1.2073 + 1.2074 + text_ptr = (png_textp)png_malloc_warn(png_ptr, 1.2075 + (png_uint_32)png_sizeof(png_text)); 1.2076 + if (text_ptr == NULL) 1.2077 + { 1.2078 + png_warning(png_ptr, "Not enough memory to process zTXt chunk."); 1.2079 + png_free(png_ptr, png_ptr->chunkdata); 1.2080 + png_ptr->chunkdata = NULL; 1.2081 + return; 1.2082 + } 1.2083 + text_ptr->compression = comp_type; 1.2084 + text_ptr->key = png_ptr->chunkdata; 1.2085 +#ifdef PNG_iTXt_SUPPORTED 1.2086 + text_ptr->lang = NULL; 1.2087 + text_ptr->lang_key = NULL; 1.2088 + text_ptr->itxt_length = 0; 1.2089 +#endif 1.2090 + text_ptr->text = png_ptr->chunkdata + prefix_len; 1.2091 + text_ptr->text_length = data_len; 1.2092 + 1.2093 + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 1.2094 + 1.2095 + png_free(png_ptr, text_ptr); 1.2096 + png_free(png_ptr, png_ptr->chunkdata); 1.2097 + png_ptr->chunkdata = NULL; 1.2098 + if (ret) 1.2099 + png_error(png_ptr, "Insufficient memory to store zTXt chunk."); 1.2100 +} 1.2101 +#endif 1.2102 + 1.2103 +#if defined(PNG_READ_iTXt_SUPPORTED) 1.2104 +/* note: this does not correctly handle chunks that are > 64K under DOS */ 1.2105 +void /* PRIVATE */ 1.2106 +png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.2107 +{ 1.2108 + png_textp text_ptr; 1.2109 + png_charp key, lang, text, lang_key; 1.2110 + int comp_flag; 1.2111 + int comp_type = 0; 1.2112 + int ret; 1.2113 + png_size_t slength, prefix_len, data_len; 1.2114 + 1.2115 + png_debug(1, "in png_handle_iTXt\n"); 1.2116 + 1.2117 + if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1.2118 + png_error(png_ptr, "Missing IHDR before iTXt"); 1.2119 + 1.2120 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.2121 + png_ptr->mode |= PNG_AFTER_IDAT; 1.2122 + 1.2123 +#ifdef PNG_MAX_MALLOC_64K 1.2124 + /* We will no doubt have problems with chunks even half this size, but 1.2125 + there is no hard and fast rule to tell us where to stop. */ 1.2126 + if (length > (png_uint_32)65535L) 1.2127 + { 1.2128 + png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 1.2129 + png_crc_finish(png_ptr, length); 1.2130 + return; 1.2131 + } 1.2132 +#endif 1.2133 + 1.2134 + png_free(png_ptr, png_ptr->chunkdata); 1.2135 + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1.2136 + if (png_ptr->chunkdata == NULL) 1.2137 + { 1.2138 + png_warning(png_ptr, "No memory to process iTXt chunk."); 1.2139 + return; 1.2140 + } 1.2141 + slength = (png_size_t)length; 1.2142 + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1.2143 + if (png_crc_finish(png_ptr, 0)) 1.2144 + { 1.2145 + png_free(png_ptr, png_ptr->chunkdata); 1.2146 + png_ptr->chunkdata = NULL; 1.2147 + return; 1.2148 + } 1.2149 + 1.2150 + png_ptr->chunkdata[slength] = 0x00; 1.2151 + 1.2152 + for (lang = png_ptr->chunkdata; *lang; lang++) 1.2153 + /* empty loop */ ; 1.2154 + lang++; /* skip NUL separator */ 1.2155 + 1.2156 + /* iTXt must have a language tag (possibly empty), two compression bytes, 1.2157 + translated keyword (possibly empty), and possibly some text after the 1.2158 + keyword */ 1.2159 + 1.2160 + if (lang >= png_ptr->chunkdata + slength - 3) 1.2161 + { 1.2162 + png_warning(png_ptr, "Truncated iTXt chunk"); 1.2163 + png_free(png_ptr, png_ptr->chunkdata); 1.2164 + png_ptr->chunkdata = NULL; 1.2165 + return; 1.2166 + } 1.2167 + else 1.2168 + { 1.2169 + comp_flag = *lang++; 1.2170 + comp_type = *lang++; 1.2171 + } 1.2172 + 1.2173 + for (lang_key = lang; *lang_key; lang_key++) 1.2174 + /* empty loop */ ; 1.2175 + lang_key++; /* skip NUL separator */ 1.2176 + 1.2177 + if (lang_key >= png_ptr->chunkdata + slength) 1.2178 + { 1.2179 + png_warning(png_ptr, "Truncated iTXt chunk"); 1.2180 + png_free(png_ptr, png_ptr->chunkdata); 1.2181 + png_ptr->chunkdata = NULL; 1.2182 + return; 1.2183 + } 1.2184 + 1.2185 + for (text = lang_key; *text; text++) 1.2186 + /* empty loop */ ; 1.2187 + text++; /* skip NUL separator */ 1.2188 + if (text >= png_ptr->chunkdata + slength) 1.2189 + { 1.2190 + png_warning(png_ptr, "Malformed iTXt chunk"); 1.2191 + png_free(png_ptr, png_ptr->chunkdata); 1.2192 + png_ptr->chunkdata = NULL; 1.2193 + return; 1.2194 + } 1.2195 + 1.2196 + prefix_len = text - png_ptr->chunkdata; 1.2197 + 1.2198 + key=png_ptr->chunkdata; 1.2199 + if (comp_flag) 1.2200 + png_decompress_chunk(png_ptr, comp_type, 1.2201 + (size_t)length, prefix_len, &data_len); 1.2202 + else 1.2203 + data_len = png_strlen(png_ptr->chunkdata + prefix_len); 1.2204 + text_ptr = (png_textp)png_malloc_warn(png_ptr, 1.2205 + (png_uint_32)png_sizeof(png_text)); 1.2206 + if (text_ptr == NULL) 1.2207 + { 1.2208 + png_warning(png_ptr, "Not enough memory to process iTXt chunk."); 1.2209 + png_free(png_ptr, png_ptr->chunkdata); 1.2210 + png_ptr->chunkdata = NULL; 1.2211 + return; 1.2212 + } 1.2213 + text_ptr->compression = (int)comp_flag + 1; 1.2214 + text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); 1.2215 + text_ptr->lang = png_ptr->chunkdata + (lang - key); 1.2216 + text_ptr->itxt_length = data_len; 1.2217 + text_ptr->text_length = 0; 1.2218 + text_ptr->key = png_ptr->chunkdata; 1.2219 + text_ptr->text = png_ptr->chunkdata + prefix_len; 1.2220 + 1.2221 + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 1.2222 + 1.2223 + png_free(png_ptr, text_ptr); 1.2224 + png_free(png_ptr, png_ptr->chunkdata); 1.2225 + png_ptr->chunkdata = NULL; 1.2226 + if (ret) 1.2227 + png_error(png_ptr, "Insufficient memory to store iTXt chunk."); 1.2228 +} 1.2229 +#endif 1.2230 + 1.2231 +/* This function is called when we haven't found a handler for a 1.2232 + chunk. If there isn't a problem with the chunk itself (ie bad 1.2233 + chunk name, CRC, or a critical chunk), the chunk is silently ignored 1.2234 + -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which 1.2235 + case it will be saved away to be written out later. */ 1.2236 +void /* PRIVATE */ 1.2237 +png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1.2238 +{ 1.2239 + png_uint_32 skip = 0; 1.2240 + 1.2241 + png_debug(1, "in png_handle_unknown\n"); 1.2242 + 1.2243 + if (png_ptr->mode & PNG_HAVE_IDAT) 1.2244 + { 1.2245 +#ifdef PNG_USE_LOCAL_ARRAYS 1.2246 + PNG_CONST PNG_IDAT; 1.2247 +#endif 1.2248 + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */ 1.2249 + png_ptr->mode |= PNG_AFTER_IDAT; 1.2250 + } 1.2251 + 1.2252 + if (!(png_ptr->chunk_name[0] & 0x20)) 1.2253 + { 1.2254 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 1.2255 + if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 1.2256 + PNG_HANDLE_CHUNK_ALWAYS 1.2257 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 1.2258 + && png_ptr->read_user_chunk_fn == NULL 1.2259 +#endif 1.2260 + ) 1.2261 +#endif 1.2262 + png_chunk_error(png_ptr, "unknown critical chunk"); 1.2263 + } 1.2264 + 1.2265 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 1.2266 + if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) || 1.2267 + (png_ptr->read_user_chunk_fn != NULL)) 1.2268 + { 1.2269 +#ifdef PNG_MAX_MALLOC_64K 1.2270 + if (length > (png_uint_32)65535L) 1.2271 + { 1.2272 + png_warning(png_ptr, "unknown chunk too large to fit in memory"); 1.2273 + skip = length - (png_uint_32)65535L; 1.2274 + length = (png_uint_32)65535L; 1.2275 + } 1.2276 +#endif 1.2277 + png_memcpy((png_charp)png_ptr->unknown_chunk.name, 1.2278 + (png_charp)png_ptr->chunk_name, 1.2279 + png_sizeof(png_ptr->unknown_chunk.name)); 1.2280 + png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] = '\0'; 1.2281 + png_ptr->unknown_chunk.size = (png_size_t)length; 1.2282 + if (length == 0) 1.2283 + png_ptr->unknown_chunk.data = NULL; 1.2284 + else 1.2285 + { 1.2286 + png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); 1.2287 + png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 1.2288 + } 1.2289 +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 1.2290 + if (png_ptr->read_user_chunk_fn != NULL) 1.2291 + { 1.2292 + /* callback to user unknown chunk handler */ 1.2293 + int ret; 1.2294 + ret = (*(png_ptr->read_user_chunk_fn)) 1.2295 + (png_ptr, &png_ptr->unknown_chunk); 1.2296 + if (ret < 0) 1.2297 + png_chunk_error(png_ptr, "error in user chunk"); 1.2298 + if (ret == 0) 1.2299 + { 1.2300 + if (!(png_ptr->chunk_name[0] & 0x20)) 1.2301 + if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 1.2302 + PNG_HANDLE_CHUNK_ALWAYS) 1.2303 + png_chunk_error(png_ptr, "unknown critical chunk"); 1.2304 + png_set_unknown_chunks(png_ptr, info_ptr, 1.2305 + &png_ptr->unknown_chunk, 1); 1.2306 + } 1.2307 + } 1.2308 + else 1.2309 +#endif 1.2310 + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 1.2311 + png_free(png_ptr, png_ptr->unknown_chunk.data); 1.2312 + png_ptr->unknown_chunk.data = NULL; 1.2313 + } 1.2314 + else 1.2315 +#endif 1.2316 + skip = length; 1.2317 + 1.2318 + png_crc_finish(png_ptr, skip); 1.2319 + 1.2320 +#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) 1.2321 + info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */ 1.2322 +#endif 1.2323 +} 1.2324 + 1.2325 +/* This function is called to verify that a chunk name is valid. 1.2326 + This function can't have the "critical chunk check" incorporated 1.2327 + into it, since in the future we will need to be able to call user 1.2328 + functions to handle unknown critical chunks after we check that 1.2329 + the chunk name itself is valid. */ 1.2330 + 1.2331 +#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 1.2332 + 1.2333 +void /* PRIVATE */ 1.2334 +png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) 1.2335 +{ 1.2336 + png_debug(1, "in png_check_chunk_name\n"); 1.2337 + if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || 1.2338 + isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) 1.2339 + { 1.2340 + png_chunk_error(png_ptr, "invalid chunk type"); 1.2341 + } 1.2342 +} 1.2343 + 1.2344 +/* Combines the row recently read in with the existing pixels in the 1.2345 + row. This routine takes care of alpha and transparency if requested. 1.2346 + This routine also handles the two methods of progressive display 1.2347 + of interlaced images, depending on the mask value. 1.2348 + The mask value describes which pixels are to be combined with 1.2349 + the row. The pattern always repeats every 8 pixels, so just 8 1.2350 + bits are needed. A one indicates the pixel is to be combined, 1.2351 + a zero indicates the pixel is to be skipped. This is in addition 1.2352 + to any alpha or transparency value associated with the pixel. If 1.2353 + you want all pixels to be combined, pass 0xff (255) in mask. */ 1.2354 + 1.2355 +void /* PRIVATE */ 1.2356 +png_combine_row(png_structp png_ptr, png_bytep row, int mask) 1.2357 +{ 1.2358 + png_debug(1, "in png_combine_row\n"); 1.2359 + if (mask == 0xff) 1.2360 + { 1.2361 + png_memcpy(row, png_ptr->row_buf + 1, 1.2362 + PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); 1.2363 + } 1.2364 + else 1.2365 + { 1.2366 + switch (png_ptr->row_info.pixel_depth) 1.2367 + { 1.2368 + case 1: 1.2369 + { 1.2370 + png_bytep sp = png_ptr->row_buf + 1; 1.2371 + png_bytep dp = row; 1.2372 + int s_inc, s_start, s_end; 1.2373 + int m = 0x80; 1.2374 + int shift; 1.2375 + png_uint_32 i; 1.2376 + png_uint_32 row_width = png_ptr->width; 1.2377 + 1.2378 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) 1.2379 + if (png_ptr->transformations & PNG_PACKSWAP) 1.2380 + { 1.2381 + s_start = 0; 1.2382 + s_end = 7; 1.2383 + s_inc = 1; 1.2384 + } 1.2385 + else 1.2386 +#endif 1.2387 + { 1.2388 + s_start = 7; 1.2389 + s_end = 0; 1.2390 + s_inc = -1; 1.2391 + } 1.2392 + 1.2393 + shift = s_start; 1.2394 + 1.2395 + for (i = 0; i < row_width; i++) 1.2396 + { 1.2397 + if (m & mask) 1.2398 + { 1.2399 + int value; 1.2400 + 1.2401 + value = (*sp >> shift) & 0x01; 1.2402 + *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 1.2403 + *dp |= (png_byte)(value << shift); 1.2404 + } 1.2405 + 1.2406 + if (shift == s_end) 1.2407 + { 1.2408 + shift = s_start; 1.2409 + sp++; 1.2410 + dp++; 1.2411 + } 1.2412 + else 1.2413 + shift += s_inc; 1.2414 + 1.2415 + if (m == 1) 1.2416 + m = 0x80; 1.2417 + else 1.2418 + m >>= 1; 1.2419 + } 1.2420 + break; 1.2421 + } 1.2422 + case 2: 1.2423 + { 1.2424 + png_bytep sp = png_ptr->row_buf + 1; 1.2425 + png_bytep dp = row; 1.2426 + int s_start, s_end, s_inc; 1.2427 + int m = 0x80; 1.2428 + int shift; 1.2429 + png_uint_32 i; 1.2430 + png_uint_32 row_width = png_ptr->width; 1.2431 + int value; 1.2432 + 1.2433 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) 1.2434 + if (png_ptr->transformations & PNG_PACKSWAP) 1.2435 + { 1.2436 + s_start = 0; 1.2437 + s_end = 6; 1.2438 + s_inc = 2; 1.2439 + } 1.2440 + else 1.2441 +#endif 1.2442 + { 1.2443 + s_start = 6; 1.2444 + s_end = 0; 1.2445 + s_inc = -2; 1.2446 + } 1.2447 + 1.2448 + shift = s_start; 1.2449 + 1.2450 + for (i = 0; i < row_width; i++) 1.2451 + { 1.2452 + if (m & mask) 1.2453 + { 1.2454 + value = (*sp >> shift) & 0x03; 1.2455 + *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 1.2456 + *dp |= (png_byte)(value << shift); 1.2457 + } 1.2458 + 1.2459 + if (shift == s_end) 1.2460 + { 1.2461 + shift = s_start; 1.2462 + sp++; 1.2463 + dp++; 1.2464 + } 1.2465 + else 1.2466 + shift += s_inc; 1.2467 + if (m == 1) 1.2468 + m = 0x80; 1.2469 + else 1.2470 + m >>= 1; 1.2471 + } 1.2472 + break; 1.2473 + } 1.2474 + case 4: 1.2475 + { 1.2476 + png_bytep sp = png_ptr->row_buf + 1; 1.2477 + png_bytep dp = row; 1.2478 + int s_start, s_end, s_inc; 1.2479 + int m = 0x80; 1.2480 + int shift; 1.2481 + png_uint_32 i; 1.2482 + png_uint_32 row_width = png_ptr->width; 1.2483 + int value; 1.2484 + 1.2485 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) 1.2486 + if (png_ptr->transformations & PNG_PACKSWAP) 1.2487 + { 1.2488 + s_start = 0; 1.2489 + s_end = 4; 1.2490 + s_inc = 4; 1.2491 + } 1.2492 + else 1.2493 +#endif 1.2494 + { 1.2495 + s_start = 4; 1.2496 + s_end = 0; 1.2497 + s_inc = -4; 1.2498 + } 1.2499 + shift = s_start; 1.2500 + 1.2501 + for (i = 0; i < row_width; i++) 1.2502 + { 1.2503 + if (m & mask) 1.2504 + { 1.2505 + value = (*sp >> shift) & 0xf; 1.2506 + *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 1.2507 + *dp |= (png_byte)(value << shift); 1.2508 + } 1.2509 + 1.2510 + if (shift == s_end) 1.2511 + { 1.2512 + shift = s_start; 1.2513 + sp++; 1.2514 + dp++; 1.2515 + } 1.2516 + else 1.2517 + shift += s_inc; 1.2518 + if (m == 1) 1.2519 + m = 0x80; 1.2520 + else 1.2521 + m >>= 1; 1.2522 + } 1.2523 + break; 1.2524 + } 1.2525 + default: 1.2526 + { 1.2527 + png_bytep sp = png_ptr->row_buf + 1; 1.2528 + png_bytep dp = row; 1.2529 + png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); 1.2530 + png_uint_32 i; 1.2531 + png_uint_32 row_width = png_ptr->width; 1.2532 + png_byte m = 0x80; 1.2533 + 1.2534 + 1.2535 + for (i = 0; i < row_width; i++) 1.2536 + { 1.2537 + if (m & mask) 1.2538 + { 1.2539 + png_memcpy(dp, sp, pixel_bytes); 1.2540 + } 1.2541 + 1.2542 + sp += pixel_bytes; 1.2543 + dp += pixel_bytes; 1.2544 + 1.2545 + if (m == 1) 1.2546 + m = 0x80; 1.2547 + else 1.2548 + m >>= 1; 1.2549 + } 1.2550 + break; 1.2551 + } 1.2552 + } 1.2553 + } 1.2554 +} 1.2555 + 1.2556 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.2557 +/* OLD pre-1.0.9 interface: 1.2558 +void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 1.2559 + png_uint_32 transformations) 1.2560 + */ 1.2561 +void /* PRIVATE */ 1.2562 +png_do_read_interlace(png_structp png_ptr) 1.2563 +{ 1.2564 + png_row_infop row_info = &(png_ptr->row_info); 1.2565 + png_bytep row = png_ptr->row_buf + 1; 1.2566 + int pass = png_ptr->pass; 1.2567 + png_uint_32 transformations = png_ptr->transformations; 1.2568 +#ifdef PNG_USE_LOCAL_ARRAYS 1.2569 + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1.2570 + /* offset to next interlace block */ 1.2571 + PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 1.2572 +#endif 1.2573 + 1.2574 + png_debug(1, "in png_do_read_interlace\n"); 1.2575 + if (row != NULL && row_info != NULL) 1.2576 + { 1.2577 + png_uint_32 final_width; 1.2578 + 1.2579 + final_width = row_info->width * png_pass_inc[pass]; 1.2580 + 1.2581 + switch (row_info->pixel_depth) 1.2582 + { 1.2583 + case 1: 1.2584 + { 1.2585 + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 1.2586 + png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 1.2587 + int sshift, dshift; 1.2588 + int s_start, s_end, s_inc; 1.2589 + int jstop = png_pass_inc[pass]; 1.2590 + png_byte v; 1.2591 + png_uint_32 i; 1.2592 + int j; 1.2593 + 1.2594 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) 1.2595 + if (transformations & PNG_PACKSWAP) 1.2596 + { 1.2597 + sshift = (int)((row_info->width + 7) & 0x07); 1.2598 + dshift = (int)((final_width + 7) & 0x07); 1.2599 + s_start = 7; 1.2600 + s_end = 0; 1.2601 + s_inc = -1; 1.2602 + } 1.2603 + else 1.2604 +#endif 1.2605 + { 1.2606 + sshift = 7 - (int)((row_info->width + 7) & 0x07); 1.2607 + dshift = 7 - (int)((final_width + 7) & 0x07); 1.2608 + s_start = 0; 1.2609 + s_end = 7; 1.2610 + s_inc = 1; 1.2611 + } 1.2612 + 1.2613 + for (i = 0; i < row_info->width; i++) 1.2614 + { 1.2615 + v = (png_byte)((*sp >> sshift) & 0x01); 1.2616 + for (j = 0; j < jstop; j++) 1.2617 + { 1.2618 + *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 1.2619 + *dp |= (png_byte)(v << dshift); 1.2620 + if (dshift == s_end) 1.2621 + { 1.2622 + dshift = s_start; 1.2623 + dp--; 1.2624 + } 1.2625 + else 1.2626 + dshift += s_inc; 1.2627 + } 1.2628 + if (sshift == s_end) 1.2629 + { 1.2630 + sshift = s_start; 1.2631 + sp--; 1.2632 + } 1.2633 + else 1.2634 + sshift += s_inc; 1.2635 + } 1.2636 + break; 1.2637 + } 1.2638 + case 2: 1.2639 + { 1.2640 + png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 1.2641 + png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 1.2642 + int sshift, dshift; 1.2643 + int s_start, s_end, s_inc; 1.2644 + int jstop = png_pass_inc[pass]; 1.2645 + png_uint_32 i; 1.2646 + 1.2647 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) 1.2648 + if (transformations & PNG_PACKSWAP) 1.2649 + { 1.2650 + sshift = (int)(((row_info->width + 3) & 0x03) << 1); 1.2651 + dshift = (int)(((final_width + 3) & 0x03) << 1); 1.2652 + s_start = 6; 1.2653 + s_end = 0; 1.2654 + s_inc = -2; 1.2655 + } 1.2656 + else 1.2657 +#endif 1.2658 + { 1.2659 + sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 1.2660 + dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 1.2661 + s_start = 0; 1.2662 + s_end = 6; 1.2663 + s_inc = 2; 1.2664 + } 1.2665 + 1.2666 + for (i = 0; i < row_info->width; i++) 1.2667 + { 1.2668 + png_byte v; 1.2669 + int j; 1.2670 + 1.2671 + v = (png_byte)((*sp >> sshift) & 0x03); 1.2672 + for (j = 0; j < jstop; j++) 1.2673 + { 1.2674 + *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 1.2675 + *dp |= (png_byte)(v << dshift); 1.2676 + if (dshift == s_end) 1.2677 + { 1.2678 + dshift = s_start; 1.2679 + dp--; 1.2680 + } 1.2681 + else 1.2682 + dshift += s_inc; 1.2683 + } 1.2684 + if (sshift == s_end) 1.2685 + { 1.2686 + sshift = s_start; 1.2687 + sp--; 1.2688 + } 1.2689 + else 1.2690 + sshift += s_inc; 1.2691 + } 1.2692 + break; 1.2693 + } 1.2694 + case 4: 1.2695 + { 1.2696 + png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 1.2697 + png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 1.2698 + int sshift, dshift; 1.2699 + int s_start, s_end, s_inc; 1.2700 + png_uint_32 i; 1.2701 + int jstop = png_pass_inc[pass]; 1.2702 + 1.2703 +#if defined(PNG_READ_PACKSWAP_SUPPORTED) 1.2704 + if (transformations & PNG_PACKSWAP) 1.2705 + { 1.2706 + sshift = (int)(((row_info->width + 1) & 0x01) << 2); 1.2707 + dshift = (int)(((final_width + 1) & 0x01) << 2); 1.2708 + s_start = 4; 1.2709 + s_end = 0; 1.2710 + s_inc = -4; 1.2711 + } 1.2712 + else 1.2713 +#endif 1.2714 + { 1.2715 + sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 1.2716 + dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 1.2717 + s_start = 0; 1.2718 + s_end = 4; 1.2719 + s_inc = 4; 1.2720 + } 1.2721 + 1.2722 + for (i = 0; i < row_info->width; i++) 1.2723 + { 1.2724 + png_byte v = (png_byte)((*sp >> sshift) & 0xf); 1.2725 + int j; 1.2726 + 1.2727 + for (j = 0; j < jstop; j++) 1.2728 + { 1.2729 + *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 1.2730 + *dp |= (png_byte)(v << dshift); 1.2731 + if (dshift == s_end) 1.2732 + { 1.2733 + dshift = s_start; 1.2734 + dp--; 1.2735 + } 1.2736 + else 1.2737 + dshift += s_inc; 1.2738 + } 1.2739 + if (sshift == s_end) 1.2740 + { 1.2741 + sshift = s_start; 1.2742 + sp--; 1.2743 + } 1.2744 + else 1.2745 + sshift += s_inc; 1.2746 + } 1.2747 + break; 1.2748 + } 1.2749 + default: 1.2750 + { 1.2751 + png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 1.2752 + png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes; 1.2753 + png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 1.2754 + 1.2755 + int jstop = png_pass_inc[pass]; 1.2756 + png_uint_32 i; 1.2757 + 1.2758 + for (i = 0; i < row_info->width; i++) 1.2759 + { 1.2760 + png_byte v[8]; 1.2761 + int j; 1.2762 + 1.2763 + png_memcpy(v, sp, pixel_bytes); 1.2764 + for (j = 0; j < jstop; j++) 1.2765 + { 1.2766 + png_memcpy(dp, v, pixel_bytes); 1.2767 + dp -= pixel_bytes; 1.2768 + } 1.2769 + sp -= pixel_bytes; 1.2770 + } 1.2771 + break; 1.2772 + } 1.2773 + } 1.2774 + row_info->width = final_width; 1.2775 + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); 1.2776 + } 1.2777 +#if !defined(PNG_READ_PACKSWAP_SUPPORTED) 1.2778 + transformations = transformations; /* silence compiler warning */ 1.2779 +#endif 1.2780 +} 1.2781 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.2782 + 1.2783 +void /* PRIVATE */ 1.2784 +png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, 1.2785 + png_bytep prev_row, int filter) 1.2786 +{ 1.2787 + png_debug(1, "in png_read_filter_row\n"); 1.2788 + png_debug2(2, "row = %lu, filter = %d\n", png_ptr->row_number, filter); 1.2789 + switch (filter) 1.2790 + { 1.2791 + case PNG_FILTER_VALUE_NONE: 1.2792 + break; 1.2793 + case PNG_FILTER_VALUE_SUB: 1.2794 + { 1.2795 + png_uint_32 i; 1.2796 + png_uint_32 istop = row_info->rowbytes; 1.2797 + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 1.2798 + png_bytep rp = row + bpp; 1.2799 + png_bytep lp = row; 1.2800 + 1.2801 + for (i = bpp; i < istop; i++) 1.2802 + { 1.2803 + *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); 1.2804 + rp++; 1.2805 + } 1.2806 + break; 1.2807 + } 1.2808 + case PNG_FILTER_VALUE_UP: 1.2809 + { 1.2810 + png_uint_32 i; 1.2811 + png_uint_32 istop = row_info->rowbytes; 1.2812 + png_bytep rp = row; 1.2813 + png_bytep pp = prev_row; 1.2814 + 1.2815 + for (i = 0; i < istop; i++) 1.2816 + { 1.2817 + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 1.2818 + rp++; 1.2819 + } 1.2820 + break; 1.2821 + } 1.2822 + case PNG_FILTER_VALUE_AVG: 1.2823 + { 1.2824 + png_uint_32 i; 1.2825 + png_bytep rp = row; 1.2826 + png_bytep pp = prev_row; 1.2827 + png_bytep lp = row; 1.2828 + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 1.2829 + png_uint_32 istop = row_info->rowbytes - bpp; 1.2830 + 1.2831 + for (i = 0; i < bpp; i++) 1.2832 + { 1.2833 + *rp = (png_byte)(((int)(*rp) + 1.2834 + ((int)(*pp++) / 2 )) & 0xff); 1.2835 + rp++; 1.2836 + } 1.2837 + 1.2838 + for (i = 0; i < istop; i++) 1.2839 + { 1.2840 + *rp = (png_byte)(((int)(*rp) + 1.2841 + (int)(*pp++ + *lp++) / 2 ) & 0xff); 1.2842 + rp++; 1.2843 + } 1.2844 + break; 1.2845 + } 1.2846 + case PNG_FILTER_VALUE_PAETH: 1.2847 + { 1.2848 + png_uint_32 i; 1.2849 + png_bytep rp = row; 1.2850 + png_bytep pp = prev_row; 1.2851 + png_bytep lp = row; 1.2852 + png_bytep cp = prev_row; 1.2853 + png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 1.2854 + png_uint_32 istop=row_info->rowbytes - bpp; 1.2855 + 1.2856 + for (i = 0; i < bpp; i++) 1.2857 + { 1.2858 + *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 1.2859 + rp++; 1.2860 + } 1.2861 + 1.2862 + for (i = 0; i < istop; i++) /* use leftover rp,pp */ 1.2863 + { 1.2864 + int a, b, c, pa, pb, pc, p; 1.2865 + 1.2866 + a = *lp++; 1.2867 + b = *pp++; 1.2868 + c = *cp++; 1.2869 + 1.2870 + p = b - c; 1.2871 + pc = a - c; 1.2872 + 1.2873 +#ifdef PNG_USE_ABS 1.2874 + pa = abs(p); 1.2875 + pb = abs(pc); 1.2876 + pc = abs(p + pc); 1.2877 +#else 1.2878 + pa = p < 0 ? -p : p; 1.2879 + pb = pc < 0 ? -pc : pc; 1.2880 + pc = (p + pc) < 0 ? -(p + pc) : p + pc; 1.2881 +#endif 1.2882 + 1.2883 + /* 1.2884 + if (pa <= pb && pa <= pc) 1.2885 + p = a; 1.2886 + else if (pb <= pc) 1.2887 + p = b; 1.2888 + else 1.2889 + p = c; 1.2890 + */ 1.2891 + 1.2892 + p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; 1.2893 + 1.2894 + *rp = (png_byte)(((int)(*rp) + p) & 0xff); 1.2895 + rp++; 1.2896 + } 1.2897 + break; 1.2898 + } 1.2899 + default: 1.2900 + png_warning(png_ptr, "Ignoring bad adaptive filter type"); 1.2901 + *row = 0; 1.2902 + break; 1.2903 + } 1.2904 +} 1.2905 + 1.2906 +void /* PRIVATE */ 1.2907 +png_read_finish_row(png_structp png_ptr) 1.2908 +{ 1.2909 +#ifdef PNG_USE_LOCAL_ARRAYS 1.2910 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.2911 + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1.2912 + 1.2913 + /* start of interlace block */ 1.2914 + PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 1.2915 + 1.2916 + /* offset to next interlace block */ 1.2917 + PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 1.2918 + 1.2919 + /* start of interlace block in the y direction */ 1.2920 + PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 1.2921 + 1.2922 + /* offset to next interlace block in the y direction */ 1.2923 + PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 1.2924 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.2925 +#endif 1.2926 + 1.2927 + png_debug(1, "in png_read_finish_row\n"); 1.2928 + png_ptr->row_number++; 1.2929 + if (png_ptr->row_number < png_ptr->num_rows) 1.2930 + return; 1.2931 + 1.2932 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.2933 + if (png_ptr->interlaced) 1.2934 + { 1.2935 + png_ptr->row_number = 0; 1.2936 + png_memset_check(png_ptr, png_ptr->prev_row, 0, 1.2937 + png_ptr->rowbytes + 1); 1.2938 + do 1.2939 + { 1.2940 + png_ptr->pass++; 1.2941 + if (png_ptr->pass >= 7) 1.2942 + break; 1.2943 + png_ptr->iwidth = (png_ptr->width + 1.2944 + png_pass_inc[png_ptr->pass] - 1 - 1.2945 + png_pass_start[png_ptr->pass]) / 1.2946 + png_pass_inc[png_ptr->pass]; 1.2947 + 1.2948 + png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, 1.2949 + png_ptr->iwidth) + 1; 1.2950 + 1.2951 + if (!(png_ptr->transformations & PNG_INTERLACE)) 1.2952 + { 1.2953 + png_ptr->num_rows = (png_ptr->height + 1.2954 + png_pass_yinc[png_ptr->pass] - 1 - 1.2955 + png_pass_ystart[png_ptr->pass]) / 1.2956 + png_pass_yinc[png_ptr->pass]; 1.2957 + if (!(png_ptr->num_rows)) 1.2958 + continue; 1.2959 + } 1.2960 + else /* if (png_ptr->transformations & PNG_INTERLACE) */ 1.2961 + break; 1.2962 + } while (png_ptr->iwidth == 0); 1.2963 + 1.2964 + if (png_ptr->pass < 7) 1.2965 + return; 1.2966 + } 1.2967 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.2968 + 1.2969 + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 1.2970 + { 1.2971 +#ifdef PNG_USE_LOCAL_ARRAYS 1.2972 + PNG_CONST PNG_IDAT; 1.2973 +#endif 1.2974 + char extra; 1.2975 + int ret; 1.2976 + 1.2977 + png_ptr->zstream.next_out = (Byte *)&extra; 1.2978 + png_ptr->zstream.avail_out = (uInt)1; 1.2979 + for (;;) 1.2980 + { 1.2981 + if (!(png_ptr->zstream.avail_in)) 1.2982 + { 1.2983 + while (!png_ptr->idat_size) 1.2984 + { 1.2985 + png_byte chunk_length[4]; 1.2986 + 1.2987 + png_crc_finish(png_ptr, 0); 1.2988 + 1.2989 + png_read_data(png_ptr, chunk_length, 4); 1.2990 + png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); 1.2991 + png_reset_crc(png_ptr); 1.2992 + png_crc_read(png_ptr, png_ptr->chunk_name, 4); 1.2993 + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 1.2994 + png_error(png_ptr, "Not enough image data"); 1.2995 + 1.2996 + } 1.2997 + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 1.2998 + png_ptr->zstream.next_in = png_ptr->zbuf; 1.2999 + if (png_ptr->zbuf_size > png_ptr->idat_size) 1.3000 + png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 1.3001 + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); 1.3002 + png_ptr->idat_size -= png_ptr->zstream.avail_in; 1.3003 + } 1.3004 + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 1.3005 + if (ret == Z_STREAM_END) 1.3006 + { 1.3007 + if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || 1.3008 + png_ptr->idat_size) 1.3009 + png_warning(png_ptr, "Extra compressed data"); 1.3010 + png_ptr->mode |= PNG_AFTER_IDAT; 1.3011 + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 1.3012 + break; 1.3013 + } 1.3014 + if (ret != Z_OK) 1.3015 + png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 1.3016 + "Decompression Error"); 1.3017 + 1.3018 + if (!(png_ptr->zstream.avail_out)) 1.3019 + { 1.3020 + png_warning(png_ptr, "Extra compressed data."); 1.3021 + png_ptr->mode |= PNG_AFTER_IDAT; 1.3022 + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 1.3023 + break; 1.3024 + } 1.3025 + 1.3026 + } 1.3027 + png_ptr->zstream.avail_out = 0; 1.3028 + } 1.3029 + 1.3030 + if (png_ptr->idat_size || png_ptr->zstream.avail_in) 1.3031 + png_warning(png_ptr, "Extra compression data"); 1.3032 + 1.3033 + inflateReset(&png_ptr->zstream); 1.3034 + 1.3035 + png_ptr->mode |= PNG_AFTER_IDAT; 1.3036 +} 1.3037 + 1.3038 +void /* PRIVATE */ 1.3039 +png_read_start_row(png_structp png_ptr) 1.3040 +{ 1.3041 +#ifdef PNG_USE_LOCAL_ARRAYS 1.3042 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.3043 + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1.3044 + 1.3045 + /* start of interlace block */ 1.3046 + PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 1.3047 + 1.3048 + /* offset to next interlace block */ 1.3049 + PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 1.3050 + 1.3051 + /* start of interlace block in the y direction */ 1.3052 + PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 1.3053 + 1.3054 + /* offset to next interlace block in the y direction */ 1.3055 + PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 1.3056 +#endif 1.3057 +#endif 1.3058 + 1.3059 + int max_pixel_depth; 1.3060 + png_size_t row_bytes; 1.3061 + 1.3062 + png_debug(1, "in png_read_start_row\n"); 1.3063 + png_ptr->zstream.avail_in = 0; 1.3064 + png_init_read_transformations(png_ptr); 1.3065 +#ifdef PNG_READ_INTERLACING_SUPPORTED 1.3066 + if (png_ptr->interlaced) 1.3067 + { 1.3068 + if (!(png_ptr->transformations & PNG_INTERLACE)) 1.3069 + png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 1.3070 + png_pass_ystart[0]) / png_pass_yinc[0]; 1.3071 + else 1.3072 + png_ptr->num_rows = png_ptr->height; 1.3073 + 1.3074 + png_ptr->iwidth = (png_ptr->width + 1.3075 + png_pass_inc[png_ptr->pass] - 1 - 1.3076 + png_pass_start[png_ptr->pass]) / 1.3077 + png_pass_inc[png_ptr->pass]; 1.3078 + 1.3079 + png_ptr->irowbytes = 1.3080 + PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1; 1.3081 + } 1.3082 + else 1.3083 +#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1.3084 + { 1.3085 + png_ptr->num_rows = png_ptr->height; 1.3086 + png_ptr->iwidth = png_ptr->width; 1.3087 + png_ptr->irowbytes = png_ptr->rowbytes + 1; 1.3088 + } 1.3089 + max_pixel_depth = png_ptr->pixel_depth; 1.3090 + 1.3091 +#if defined(PNG_READ_PACK_SUPPORTED) 1.3092 + if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 1.3093 + max_pixel_depth = 8; 1.3094 +#endif 1.3095 + 1.3096 +#if defined(PNG_READ_EXPAND_SUPPORTED) 1.3097 + if (png_ptr->transformations & PNG_EXPAND) 1.3098 + { 1.3099 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.3100 + { 1.3101 + if (png_ptr->num_trans) 1.3102 + max_pixel_depth = 32; 1.3103 + else 1.3104 + max_pixel_depth = 24; 1.3105 + } 1.3106 + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1.3107 + { 1.3108 + if (max_pixel_depth < 8) 1.3109 + max_pixel_depth = 8; 1.3110 + if (png_ptr->num_trans) 1.3111 + max_pixel_depth *= 2; 1.3112 + } 1.3113 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1.3114 + { 1.3115 + if (png_ptr->num_trans) 1.3116 + { 1.3117 + max_pixel_depth *= 4; 1.3118 + max_pixel_depth /= 3; 1.3119 + } 1.3120 + } 1.3121 + } 1.3122 +#endif 1.3123 + 1.3124 +#if defined(PNG_READ_FILLER_SUPPORTED) 1.3125 + if (png_ptr->transformations & (PNG_FILLER)) 1.3126 + { 1.3127 + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1.3128 + max_pixel_depth = 32; 1.3129 + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1.3130 + { 1.3131 + if (max_pixel_depth <= 8) 1.3132 + max_pixel_depth = 16; 1.3133 + else 1.3134 + max_pixel_depth = 32; 1.3135 + } 1.3136 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1.3137 + { 1.3138 + if (max_pixel_depth <= 32) 1.3139 + max_pixel_depth = 32; 1.3140 + else 1.3141 + max_pixel_depth = 64; 1.3142 + } 1.3143 + } 1.3144 +#endif 1.3145 + 1.3146 +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) 1.3147 + if (png_ptr->transformations & PNG_GRAY_TO_RGB) 1.3148 + { 1.3149 + if ( 1.3150 +#if defined(PNG_READ_EXPAND_SUPPORTED) 1.3151 + (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 1.3152 +#endif 1.3153 +#if defined(PNG_READ_FILLER_SUPPORTED) 1.3154 + (png_ptr->transformations & (PNG_FILLER)) || 1.3155 +#endif 1.3156 + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 1.3157 + { 1.3158 + if (max_pixel_depth <= 16) 1.3159 + max_pixel_depth = 32; 1.3160 + else 1.3161 + max_pixel_depth = 64; 1.3162 + } 1.3163 + else 1.3164 + { 1.3165 + if (max_pixel_depth <= 8) 1.3166 + { 1.3167 + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 1.3168 + max_pixel_depth = 32; 1.3169 + else 1.3170 + max_pixel_depth = 24; 1.3171 + } 1.3172 + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 1.3173 + max_pixel_depth = 64; 1.3174 + else 1.3175 + max_pixel_depth = 48; 1.3176 + } 1.3177 + } 1.3178 +#endif 1.3179 + 1.3180 +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 1.3181 +defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 1.3182 + if (png_ptr->transformations & PNG_USER_TRANSFORM) 1.3183 + { 1.3184 + int user_pixel_depth = png_ptr->user_transform_depth* 1.3185 + png_ptr->user_transform_channels; 1.3186 + if (user_pixel_depth > max_pixel_depth) 1.3187 + max_pixel_depth=user_pixel_depth; 1.3188 + } 1.3189 +#endif 1.3190 + 1.3191 + /* align the width on the next larger 8 pixels. Mainly used 1.3192 + for interlacing */ 1.3193 + row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 1.3194 + /* calculate the maximum bytes needed, adding a byte and a pixel 1.3195 + for safety's sake */ 1.3196 + row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 1.3197 + 1 + ((max_pixel_depth + 7) >> 3); 1.3198 +#ifdef PNG_MAX_MALLOC_64K 1.3199 + if (row_bytes > (png_uint_32)65536L) 1.3200 + png_error(png_ptr, "This image requires a row greater than 64KB"); 1.3201 +#endif 1.3202 + 1.3203 + if (row_bytes + 64 > png_ptr->old_big_row_buf_size) 1.3204 + { 1.3205 + png_free(png_ptr, png_ptr->big_row_buf); 1.3206 + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); 1.3207 + png_ptr->row_buf = png_ptr->big_row_buf+32; 1.3208 + png_ptr->old_big_row_buf_size = row_bytes+64; 1.3209 + } 1.3210 + 1.3211 +#ifdef PNG_MAX_MALLOC_64K 1.3212 + if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) 1.3213 + png_error(png_ptr, "This image requires a row greater than 64KB"); 1.3214 +#endif 1.3215 + if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1)) 1.3216 + png_error(png_ptr, "Row has too many bytes to allocate in memory."); 1.3217 + 1.3218 + if (png_ptr->rowbytes+1 > png_ptr->old_prev_row_size) 1.3219 + { 1.3220 + png_free(png_ptr, png_ptr->prev_row); 1.3221 + png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( 1.3222 + png_ptr->rowbytes + 1)); 1.3223 + png_ptr->old_prev_row_size = png_ptr->rowbytes+1; 1.3224 + } 1.3225 + 1.3226 + png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 1.3227 + 1.3228 + png_debug1(3, "width = %lu,\n", png_ptr->width); 1.3229 + png_debug1(3, "height = %lu,\n", png_ptr->height); 1.3230 + png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth); 1.3231 + png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows); 1.3232 + png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes); 1.3233 + png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes); 1.3234 + 1.3235 + png_ptr->flags |= PNG_FLAG_ROW_INIT; 1.3236 +} 1.3237 +#endif /* PNG_READ_SUPPORTED */