Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpngrutil.c
Go to the documentation of this file.
00001 00002 /* pngrutil.c - utilities to read a PNG file 00003 * 00004 * Last changed in libpng 1.5.9 [February 18, 2012] 00005 * Copyright (c) 1998-2012 Glenn Randers-Pehrson 00006 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 00007 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 00008 * 00009 * This code is released under the libpng license. 00010 * For conditions of distribution and use, see the disclaimer 00011 * and license in png.h 00012 * 00013 * This file contains routines that are only called from within 00014 * libpng itself during the course of reading an image. 00015 */ 00016 00017 #include "pngpriv.h" 00018 00019 #ifdef PNG_READ_SUPPORTED 00020 00021 #define png_strtod(p,a,b) strtod(a,b) 00022 00023 png_uint_32 PNGAPI 00024 png_get_uint_31(png_structp png_ptr, png_const_bytep buf) 00025 { 00026 png_uint_32 uval = png_get_uint_32(buf); 00027 00028 if (uval > PNG_UINT_31_MAX) 00029 png_error(png_ptr, "PNG unsigned integer out of range"); 00030 00031 return (uval); 00032 } 00033 00034 #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) 00035 /* The following is a variation on the above for use with the fixed 00036 * point values used for gAMA and cHRM. Instead of png_error it 00037 * issues a warning and returns (-1) - an invalid value because both 00038 * gAMA and cHRM use *unsigned* integers for fixed point values. 00039 */ 00040 #define PNG_FIXED_ERROR (-1) 00041 00042 static png_fixed_point /* PRIVATE */ 00043 png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) 00044 { 00045 png_uint_32 uval = png_get_uint_32(buf); 00046 00047 if (uval <= PNG_UINT_31_MAX) 00048 return (png_fixed_point)uval; /* known to be in range */ 00049 00050 /* The caller can turn off the warning by passing NULL. */ 00051 if (png_ptr != NULL) 00052 png_warning(png_ptr, "PNG fixed point integer out of range"); 00053 00054 return PNG_FIXED_ERROR; 00055 } 00056 #endif 00057 00058 #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED 00059 /* NOTE: the read macros will obscure these definitions, so that if 00060 * PNG_USE_READ_MACROS is set the library will not use them internally, 00061 * but the APIs will still be available externally. 00062 * 00063 * The parentheses around "PNGAPI function_name" in the following three 00064 * functions are necessary because they allow the macros to co-exist with 00065 * these (unused but exported) functions. 00066 */ 00067 00068 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ 00069 png_uint_32 (PNGAPI 00070 png_get_uint_32)(png_const_bytep buf) 00071 { 00072 png_uint_32 uval = 00073 ((png_uint_32)(*(buf )) << 24) + 00074 ((png_uint_32)(*(buf + 1)) << 16) + 00075 ((png_uint_32)(*(buf + 2)) << 8) + 00076 ((png_uint_32)(*(buf + 3)) ) ; 00077 00078 return uval; 00079 } 00080 00081 /* Grab a signed 32-bit integer from a buffer in big-endian format. The 00082 * data is stored in the PNG file in two's complement format and there 00083 * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore 00084 * the following code does a two's complement to native conversion. 00085 */ 00086 png_int_32 (PNGAPI 00087 png_get_int_32)(png_const_bytep buf) 00088 { 00089 png_uint_32 uval = png_get_uint_32(buf); 00090 if ((uval & 0x80000000) == 0) /* non-negative */ 00091 return uval; 00092 00093 uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ 00094 return -(png_int_32)uval; 00095 } 00096 00097 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ 00098 png_uint_16 (PNGAPI 00099 png_get_uint_16)(png_const_bytep buf) 00100 { 00101 /* ANSI-C requires an int value to accomodate at least 16 bits so this 00102 * works and allows the compiler not to worry about possible narrowing 00103 * on 32 bit systems. (Pre-ANSI systems did not make integers smaller 00104 * than 16 bits either.) 00105 */ 00106 unsigned int val = 00107 ((unsigned int)(*buf) << 8) + 00108 ((unsigned int)(*(buf + 1))); 00109 00110 return (png_uint_16)val; 00111 } 00112 00113 #endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ 00114 00115 /* Read and check the PNG file signature */ 00116 void /* PRIVATE */ 00117 png_read_sig(png_structp png_ptr, png_infop info_ptr) 00118 { 00119 png_size_t num_checked, num_to_check; 00120 00121 /* Exit if the user application does not expect a signature. */ 00122 if (png_ptr->sig_bytes >= 8) 00123 return; 00124 00125 num_checked = png_ptr->sig_bytes; 00126 num_to_check = 8 - num_checked; 00127 00128 #ifdef PNG_IO_STATE_SUPPORTED 00129 png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; 00130 #endif 00131 00132 /* The signature must be serialized in a single I/O call. */ 00133 png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); 00134 png_ptr->sig_bytes = 8; 00135 00136 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) 00137 { 00138 if (num_checked < 4 && 00139 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) 00140 png_error(png_ptr, "Not a PNG file"); 00141 else 00142 png_error(png_ptr, "PNG file corrupted by ASCII conversion"); 00143 } 00144 if (num_checked < 3) 00145 png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; 00146 } 00147 00148 /* Read the chunk header (length + type name). 00149 * Put the type name into png_ptr->chunk_name, and return the length. 00150 */ 00151 png_uint_32 /* PRIVATE */ 00152 png_read_chunk_header(png_structp png_ptr) 00153 { 00154 png_byte buf[8]; 00155 png_uint_32 length; 00156 00157 #ifdef PNG_IO_STATE_SUPPORTED 00158 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; 00159 #endif 00160 00161 /* Read the length and the chunk name. 00162 * This must be performed in a single I/O call. 00163 */ 00164 png_read_data(png_ptr, buf, 8); 00165 length = png_get_uint_31(png_ptr, buf); 00166 00167 /* Put the chunk name into png_ptr->chunk_name. */ 00168 png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); 00169 00170 png_debug2(0, "Reading %lx chunk, length = %lu", 00171 (unsigned long)png_ptr->chunk_name, (unsigned long)length); 00172 00173 /* Reset the crc and run it over the chunk name. */ 00174 png_reset_crc(png_ptr); 00175 png_calculate_crc(png_ptr, buf + 4, 4); 00176 00177 /* Check to see if chunk name is valid. */ 00178 png_check_chunk_name(png_ptr, png_ptr->chunk_name); 00179 00180 #ifdef PNG_IO_STATE_SUPPORTED 00181 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; 00182 #endif 00183 00184 return length; 00185 } 00186 00187 /* Read data, and (optionally) run it through the CRC. */ 00188 void /* PRIVATE */ 00189 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) 00190 { 00191 if (png_ptr == NULL) 00192 return; 00193 00194 png_read_data(png_ptr, buf, length); 00195 png_calculate_crc(png_ptr, buf, length); 00196 } 00197 00198 /* Optionally skip data and then check the CRC. Depending on whether we 00199 * are reading a ancillary or critical chunk, and how the program has set 00200 * things up, we may calculate the CRC on the data and print a message. 00201 * Returns '1' if there was a CRC error, '0' otherwise. 00202 */ 00203 int /* PRIVATE */ 00204 png_crc_finish(png_structp png_ptr, png_uint_32 skip) 00205 { 00206 png_size_t i; 00207 png_size_t istop = png_ptr->zbuf_size; 00208 00209 for (i = (png_size_t)skip; i > istop; i -= istop) 00210 { 00211 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 00212 } 00213 00214 if (i) 00215 { 00216 png_crc_read(png_ptr, png_ptr->zbuf, i); 00217 } 00218 00219 if (png_crc_error(png_ptr)) 00220 { 00221 if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ? 00222 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) : 00223 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)) 00224 { 00225 png_chunk_warning(png_ptr, "CRC error"); 00226 } 00227 00228 else 00229 { 00230 png_chunk_benign_error(png_ptr, "CRC error"); 00231 return (0); 00232 } 00233 00234 return (1); 00235 } 00236 00237 return (0); 00238 } 00239 00240 /* Compare the CRC stored in the PNG file with that calculated by libpng from 00241 * the data it has read thus far. 00242 */ 00243 int /* PRIVATE */ 00244 png_crc_error(png_structp png_ptr) 00245 { 00246 png_byte crc_bytes[4]; 00247 png_uint_32 crc; 00248 int need_crc = 1; 00249 00250 if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name)) 00251 { 00252 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 00253 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 00254 need_crc = 0; 00255 } 00256 00257 else /* critical */ 00258 { 00259 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 00260 need_crc = 0; 00261 } 00262 00263 #ifdef PNG_IO_STATE_SUPPORTED 00264 png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; 00265 #endif 00266 00267 /* The chunk CRC must be serialized in a single I/O call. */ 00268 png_read_data(png_ptr, crc_bytes, 4); 00269 00270 if (need_crc) 00271 { 00272 crc = png_get_uint_32(crc_bytes); 00273 return ((int)(crc != png_ptr->crc)); 00274 } 00275 00276 else 00277 return (0); 00278 } 00279 00280 #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED 00281 static png_size_t 00282 png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, 00283 png_bytep output, png_size_t output_size) 00284 { 00285 png_size_t count = 0; 00286 00287 /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't 00288 * even necessarily handle 65536 bytes) because the type uInt is "16 bits or 00289 * more". Consequently it is necessary to chunk the input to zlib. This 00290 * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value 00291 * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a 00292 * lower value in pngpriv.h and this may sometimes have a performance 00293 * advantage, because it forces access of the input data to be separated from 00294 * at least some of the use by some period of time. 00295 */ 00296 png_ptr->zstream.next_in = data; 00297 /* avail_in is set below from 'size' */ 00298 png_ptr->zstream.avail_in = 0; 00299 00300 while (1) 00301 { 00302 int ret, avail; 00303 00304 /* The setting of 'avail_in' used to be outside the loop; by setting it 00305 * inside it is possible to chunk the input to zlib and simply rely on 00306 * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o 00307 * data to be passed through zlib at the unavoidable cost of requiring a 00308 * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX 00309 * input bytes. 00310 */ 00311 if (png_ptr->zstream.avail_in == 0 && size > 0) 00312 { 00313 if (size <= ZLIB_IO_MAX) 00314 { 00315 /* The value is less than ZLIB_IO_MAX so the cast is safe: */ 00316 png_ptr->zstream.avail_in = (uInt)size; 00317 size = 0; 00318 } 00319 00320 else 00321 { 00322 png_ptr->zstream.avail_in = ZLIB_IO_MAX; 00323 size -= ZLIB_IO_MAX; 00324 } 00325 } 00326 00327 /* Reset the output buffer each time round - we empty it 00328 * after every inflate call. 00329 */ 00330 png_ptr->zstream.next_out = png_ptr->zbuf; 00331 png_ptr->zstream.avail_out = png_ptr->zbuf_size; 00332 00333 ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); 00334 avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; 00335 00336 /* First copy/count any new output - but only if we didn't 00337 * get an error code. 00338 */ 00339 if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) 00340 { 00341 png_size_t space = avail; /* > 0, see above */ 00342 00343 if (output != 0 && output_size > count) 00344 { 00345 png_size_t copy = output_size - count; 00346 00347 if (space < copy) 00348 copy = space; 00349 00350 png_memcpy(output + count, png_ptr->zbuf, copy); 00351 } 00352 count += space; 00353 } 00354 00355 if (ret == Z_OK) 00356 continue; 00357 00358 /* Termination conditions - always reset the zstream, it 00359 * must be left in inflateInit state. 00360 */ 00361 png_ptr->zstream.avail_in = 0; 00362 inflateReset(&png_ptr->zstream); 00363 00364 if (ret == Z_STREAM_END) 00365 return count; /* NOTE: may be zero. */ 00366 00367 /* Now handle the error codes - the API always returns 0 00368 * and the error message is dumped into the uncompressed 00369 * buffer if available. 00370 */ 00371 # ifdef PNG_WARNINGS_SUPPORTED 00372 { 00373 png_const_charp msg; 00374 00375 if (png_ptr->zstream.msg != 0) 00376 msg = png_ptr->zstream.msg; 00377 00378 else switch (ret) 00379 { 00380 case Z_BUF_ERROR: 00381 msg = "Buffer error in compressed datastream"; 00382 break; 00383 00384 case Z_DATA_ERROR: 00385 msg = "Data error in compressed datastream"; 00386 break; 00387 00388 default: 00389 msg = "Incomplete compressed datastream"; 00390 break; 00391 } 00392 00393 png_chunk_warning(png_ptr, msg); 00394 } 00395 # endif 00396 00397 /* 0 means an error - notice that this code simply ignores 00398 * zero length compressed chunks as a result. 00399 */ 00400 return 0; 00401 } 00402 } 00403 00404 /* 00405 * Decompress trailing data in a chunk. The assumption is that chunkdata 00406 * points at an allocated area holding the contents of a chunk with a 00407 * trailing compressed part. What we get back is an allocated area 00408 * holding the original prefix part and an uncompressed version of the 00409 * trailing part (the malloc area passed in is freed). 00410 */ 00411 void /* PRIVATE */ 00412 png_decompress_chunk(png_structp png_ptr, int comp_type, 00413 png_size_t chunklength, 00414 png_size_t prefix_size, png_size_t *newlength) 00415 { 00416 /* The caller should guarantee this */ 00417 if (prefix_size > chunklength) 00418 { 00419 /* The recovery is to delete the chunk. */ 00420 png_warning(png_ptr, "invalid chunklength"); 00421 prefix_size = 0; /* To delete everything */ 00422 } 00423 00424 else if (comp_type == PNG_COMPRESSION_TYPE_BASE) 00425 { 00426 png_size_t expanded_size = png_inflate(png_ptr, 00427 (png_bytep)(png_ptr->chunkdata + prefix_size), 00428 chunklength - prefix_size, 00429 0, /* output */ 00430 0); /* output size */ 00431 00432 /* Now check the limits on this chunk - if the limit fails the 00433 * compressed data will be removed, the prefix will remain. 00434 */ 00435 if (prefix_size >= (~(png_size_t)0) - 1 || 00436 expanded_size >= (~(png_size_t)0) - 1 - prefix_size 00437 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED 00438 || (png_ptr->user_chunk_malloc_max && 00439 (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) 00440 #else 00441 # ifdef PNG_USER_CHUNK_MALLOC_MAX 00442 || ((PNG_USER_CHUNK_MALLOC_MAX > 0) && 00443 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) 00444 # endif 00445 #endif 00446 ) 00447 png_warning(png_ptr, "Exceeded size limit while expanding chunk"); 00448 00449 /* If the size is zero either there was an error and a message 00450 * has already been output (warning) or the size really is zero 00451 * and we have nothing to do - the code will exit through the 00452 * error case below. 00453 */ 00454 else if (expanded_size > 0) 00455 { 00456 /* Success (maybe) - really uncompress the chunk. */ 00457 png_size_t new_size = 0; 00458 png_charp text = (png_charp)png_malloc_warn(png_ptr, 00459 prefix_size + expanded_size + 1); 00460 00461 if (text != NULL) 00462 { 00463 png_memcpy(text, png_ptr->chunkdata, prefix_size); 00464 new_size = png_inflate(png_ptr, 00465 (png_bytep)(png_ptr->chunkdata + prefix_size), 00466 chunklength - prefix_size, 00467 (png_bytep)(text + prefix_size), expanded_size); 00468 text[prefix_size + expanded_size] = 0; /* just in case */ 00469 00470 if (new_size == expanded_size) 00471 { 00472 png_free(png_ptr, png_ptr->chunkdata); 00473 png_ptr->chunkdata = text; 00474 *newlength = prefix_size + expanded_size; 00475 return; /* The success return! */ 00476 } 00477 00478 png_warning(png_ptr, "png_inflate logic error"); 00479 png_free(png_ptr, text); 00480 } 00481 00482 else 00483 png_warning(png_ptr, "Not enough memory to decompress chunk"); 00484 } 00485 } 00486 00487 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ 00488 { 00489 PNG_WARNING_PARAMETERS(p) 00490 png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type); 00491 png_formatted_warning(png_ptr, p, "Unknown compression type @1"); 00492 00493 /* The recovery is to simply drop the data. */ 00494 } 00495 00496 /* Generic error return - leave the prefix, delete the compressed 00497 * data, reallocate the chunkdata to remove the potentially large 00498 * amount of compressed data. 00499 */ 00500 { 00501 png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1); 00502 00503 if (text != NULL) 00504 { 00505 if (prefix_size > 0) 00506 png_memcpy(text, png_ptr->chunkdata, prefix_size); 00507 00508 png_free(png_ptr, png_ptr->chunkdata); 00509 png_ptr->chunkdata = text; 00510 00511 /* This is an extra zero in the 'uncompressed' part. */ 00512 *(png_ptr->chunkdata + prefix_size) = 0x00; 00513 } 00514 /* Ignore a malloc error here - it is safe. */ 00515 } 00516 00517 *newlength = prefix_size; 00518 } 00519 #endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */ 00520 00521 /* Read and check the IDHR chunk */ 00522 void /* PRIVATE */ 00523 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 00524 { 00525 png_byte buf[13]; 00526 png_uint_32 width, height; 00527 int bit_depth, color_type, compression_type, filter_type; 00528 int interlace_type; 00529 00530 png_debug(1, "in png_handle_IHDR"); 00531 00532 if (png_ptr->mode & PNG_HAVE_IHDR) 00533 png_error(png_ptr, "Out of place IHDR"); 00534 00535 /* Check the length */ 00536 if (length != 13) 00537 png_error(png_ptr, "Invalid IHDR chunk"); 00538 00539 png_ptr->mode |= PNG_HAVE_IHDR; 00540 00541 png_crc_read(png_ptr, buf, 13); 00542 png_crc_finish(png_ptr, 0); 00543 00544 width = png_get_uint_31(png_ptr, buf); 00545 height = png_get_uint_31(png_ptr, buf + 4); 00546 bit_depth = buf[8]; 00547 color_type = buf[9]; 00548 compression_type = buf[10]; 00549 filter_type = buf[11]; 00550 interlace_type = buf[12]; 00551 00552 /* Set internal variables */ 00553 png_ptr->width = width; 00554 png_ptr->height = height; 00555 png_ptr->bit_depth = (png_byte)bit_depth; 00556 png_ptr->interlaced = (png_byte)interlace_type; 00557 png_ptr->color_type = (png_byte)color_type; 00558 #ifdef PNG_MNG_FEATURES_SUPPORTED 00559 png_ptr->filter_type = (png_byte)filter_type; 00560 #endif 00561 png_ptr->compression_type = (png_byte)compression_type; 00562 00563 /* Find number of channels */ 00564 switch (png_ptr->color_type) 00565 { 00566 default: /* invalid, png_set_IHDR calls png_error */ 00567 case PNG_COLOR_TYPE_GRAY: 00568 case PNG_COLOR_TYPE_PALETTE: 00569 png_ptr->channels = 1; 00570 break; 00571 00572 case PNG_COLOR_TYPE_RGB: 00573 png_ptr->channels = 3; 00574 break; 00575 00576 case PNG_COLOR_TYPE_GRAY_ALPHA: 00577 png_ptr->channels = 2; 00578 break; 00579 00580 case PNG_COLOR_TYPE_RGB_ALPHA: 00581 png_ptr->channels = 4; 00582 break; 00583 } 00584 00585 /* Set up other useful info */ 00586 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 00587 png_ptr->channels); 00588 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); 00589 png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); 00590 png_debug1(3, "channels = %d", png_ptr->channels); 00591 png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); 00592 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 00593 color_type, interlace_type, compression_type, filter_type); 00594 } 00595 00596 /* Read and check the palette */ 00597 void /* PRIVATE */ 00598 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 00599 { 00600 png_color palette[PNG_MAX_PALETTE_LENGTH]; 00601 int num, i; 00602 #ifdef PNG_POINTER_INDEXING_SUPPORTED 00603 png_colorp pal_ptr; 00604 #endif 00605 00606 png_debug(1, "in png_handle_PLTE"); 00607 00608 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 00609 png_error(png_ptr, "Missing IHDR before PLTE"); 00610 00611 else if (png_ptr->mode & PNG_HAVE_IDAT) 00612 { 00613 png_warning(png_ptr, "Invalid PLTE after IDAT"); 00614 png_crc_finish(png_ptr, length); 00615 return; 00616 } 00617 00618 else if (png_ptr->mode & PNG_HAVE_PLTE) 00619 png_error(png_ptr, "Duplicate PLTE chunk"); 00620 00621 png_ptr->mode |= PNG_HAVE_PLTE; 00622 00623 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 00624 { 00625 png_warning(png_ptr, 00626 "Ignoring PLTE chunk in grayscale PNG"); 00627 png_crc_finish(png_ptr, length); 00628 return; 00629 } 00630 00631 #ifndef PNG_READ_OPT_PLTE_SUPPORTED 00632 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 00633 { 00634 png_crc_finish(png_ptr, length); 00635 return; 00636 } 00637 #endif 00638 00639 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) 00640 { 00641 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 00642 { 00643 png_warning(png_ptr, "Invalid palette chunk"); 00644 png_crc_finish(png_ptr, length); 00645 return; 00646 } 00647 00648 else 00649 { 00650 png_error(png_ptr, "Invalid palette chunk"); 00651 } 00652 } 00653 00654 num = (int)length / 3; 00655 00656 #ifdef PNG_POINTER_INDEXING_SUPPORTED 00657 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) 00658 { 00659 png_byte buf[3]; 00660 00661 png_crc_read(png_ptr, buf, 3); 00662 pal_ptr->red = buf[0]; 00663 pal_ptr->green = buf[1]; 00664 pal_ptr->blue = buf[2]; 00665 } 00666 #else 00667 for (i = 0; i < num; i++) 00668 { 00669 png_byte buf[3]; 00670 00671 png_crc_read(png_ptr, buf, 3); 00672 /* Don't depend upon png_color being any order */ 00673 palette[i].red = buf[0]; 00674 palette[i].green = buf[1]; 00675 palette[i].blue = buf[2]; 00676 } 00677 #endif 00678 00679 /* If we actually need the PLTE chunk (ie for a paletted image), we do 00680 * whatever the normal CRC configuration tells us. However, if we 00681 * have an RGB image, the PLTE can be considered ancillary, so 00682 * we will act as though it is. 00683 */ 00684 #ifndef PNG_READ_OPT_PLTE_SUPPORTED 00685 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 00686 #endif 00687 { 00688 png_crc_finish(png_ptr, 0); 00689 } 00690 00691 #ifndef PNG_READ_OPT_PLTE_SUPPORTED 00692 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ 00693 { 00694 /* If we don't want to use the data from an ancillary chunk, 00695 * we have two options: an error abort, or a warning and we 00696 * ignore the data in this chunk (which should be OK, since 00697 * it's considered ancillary for a RGB or RGBA image). 00698 */ 00699 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) 00700 { 00701 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) 00702 { 00703 png_chunk_benign_error(png_ptr, "CRC error"); 00704 } 00705 00706 else 00707 { 00708 png_chunk_warning(png_ptr, "CRC error"); 00709 return; 00710 } 00711 } 00712 00713 /* Otherwise, we (optionally) emit a warning and use the chunk. */ 00714 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) 00715 { 00716 png_chunk_warning(png_ptr, "CRC error"); 00717 } 00718 } 00719 #endif 00720 00721 png_set_PLTE(png_ptr, info_ptr, palette, num); 00722 00723 #ifdef PNG_READ_tRNS_SUPPORTED 00724 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 00725 { 00726 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 00727 { 00728 if (png_ptr->num_trans > (png_uint_16)num) 00729 { 00730 png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); 00731 png_ptr->num_trans = (png_uint_16)num; 00732 } 00733 00734 if (info_ptr->num_trans > (png_uint_16)num) 00735 { 00736 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); 00737 info_ptr->num_trans = (png_uint_16)num; 00738 } 00739 } 00740 } 00741 #endif 00742 00743 } 00744 00745 void /* PRIVATE */ 00746 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 00747 { 00748 png_debug(1, "in png_handle_IEND"); 00749 00750 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) 00751 { 00752 png_error(png_ptr, "No image in file"); 00753 } 00754 00755 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); 00756 00757 if (length != 0) 00758 { 00759 png_warning(png_ptr, "Incorrect IEND chunk length"); 00760 } 00761 00762 png_crc_finish(png_ptr, length); 00763 00764 PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ 00765 } 00766 00767 #ifdef PNG_READ_gAMA_SUPPORTED 00768 void /* PRIVATE */ 00769 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 00770 { 00771 png_fixed_point igamma; 00772 png_byte buf[4]; 00773 00774 png_debug(1, "in png_handle_gAMA"); 00775 00776 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 00777 png_error(png_ptr, "Missing IHDR before gAMA"); 00778 00779 else if (png_ptr->mode & PNG_HAVE_IDAT) 00780 { 00781 png_warning(png_ptr, "Invalid gAMA after IDAT"); 00782 png_crc_finish(png_ptr, length); 00783 return; 00784 } 00785 00786 else if (png_ptr->mode & PNG_HAVE_PLTE) 00787 /* Should be an error, but we can cope with it */ 00788 png_warning(png_ptr, "Out of place gAMA chunk"); 00789 00790 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) 00791 #ifdef PNG_READ_sRGB_SUPPORTED 00792 && !(info_ptr->valid & PNG_INFO_sRGB) 00793 #endif 00794 ) 00795 { 00796 png_warning(png_ptr, "Duplicate gAMA chunk"); 00797 png_crc_finish(png_ptr, length); 00798 return; 00799 } 00800 00801 if (length != 4) 00802 { 00803 png_warning(png_ptr, "Incorrect gAMA chunk length"); 00804 png_crc_finish(png_ptr, length); 00805 return; 00806 } 00807 00808 png_crc_read(png_ptr, buf, 4); 00809 00810 if (png_crc_finish(png_ptr, 0)) 00811 return; 00812 00813 igamma = png_get_fixed_point(NULL, buf); 00814 00815 /* Check for zero gamma or an error. */ 00816 if (igamma <= 0) 00817 { 00818 png_warning(png_ptr, 00819 "Ignoring gAMA chunk with out of range gamma"); 00820 00821 return; 00822 } 00823 00824 # ifdef PNG_READ_sRGB_SUPPORTED 00825 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 00826 { 00827 if (PNG_OUT_OF_RANGE(igamma, 45500, 500)) 00828 { 00829 PNG_WARNING_PARAMETERS(p) 00830 png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); 00831 png_formatted_warning(png_ptr, p, 00832 "Ignoring incorrect gAMA value @1 when sRGB is also present"); 00833 return; 00834 } 00835 } 00836 # endif /* PNG_READ_sRGB_SUPPORTED */ 00837 00838 # ifdef PNG_READ_GAMMA_SUPPORTED 00839 /* Gamma correction on read is supported. */ 00840 png_ptr->gamma = igamma; 00841 # endif 00842 /* And set the 'info' structure members. */ 00843 png_set_gAMA_fixed(png_ptr, info_ptr, igamma); 00844 } 00845 #endif 00846 00847 #ifdef PNG_READ_sBIT_SUPPORTED 00848 void /* PRIVATE */ 00849 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 00850 { 00851 png_size_t truelen; 00852 png_byte buf[4]; 00853 00854 png_debug(1, "in png_handle_sBIT"); 00855 00856 buf[0] = buf[1] = buf[2] = buf[3] = 0; 00857 00858 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 00859 png_error(png_ptr, "Missing IHDR before sBIT"); 00860 00861 else if (png_ptr->mode & PNG_HAVE_IDAT) 00862 { 00863 png_warning(png_ptr, "Invalid sBIT after IDAT"); 00864 png_crc_finish(png_ptr, length); 00865 return; 00866 } 00867 00868 else if (png_ptr->mode & PNG_HAVE_PLTE) 00869 { 00870 /* Should be an error, but we can cope with it */ 00871 png_warning(png_ptr, "Out of place sBIT chunk"); 00872 } 00873 00874 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) 00875 { 00876 png_warning(png_ptr, "Duplicate sBIT chunk"); 00877 png_crc_finish(png_ptr, length); 00878 return; 00879 } 00880 00881 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 00882 truelen = 3; 00883 00884 else 00885 truelen = (png_size_t)png_ptr->channels; 00886 00887 if (length != truelen || length > 4) 00888 { 00889 png_warning(png_ptr, "Incorrect sBIT chunk length"); 00890 png_crc_finish(png_ptr, length); 00891 return; 00892 } 00893 00894 png_crc_read(png_ptr, buf, truelen); 00895 00896 if (png_crc_finish(png_ptr, 0)) 00897 return; 00898 00899 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 00900 { 00901 png_ptr->sig_bit.red = buf[0]; 00902 png_ptr->sig_bit.green = buf[1]; 00903 png_ptr->sig_bit.blue = buf[2]; 00904 png_ptr->sig_bit.alpha = buf[3]; 00905 } 00906 00907 else 00908 { 00909 png_ptr->sig_bit.gray = buf[0]; 00910 png_ptr->sig_bit.red = buf[0]; 00911 png_ptr->sig_bit.green = buf[0]; 00912 png_ptr->sig_bit.blue = buf[0]; 00913 png_ptr->sig_bit.alpha = buf[1]; 00914 } 00915 00916 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); 00917 } 00918 #endif 00919 00920 #ifdef PNG_READ_cHRM_SUPPORTED 00921 void /* PRIVATE */ 00922 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 00923 { 00924 png_byte buf[32]; 00925 png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, 00926 y_blue; 00927 00928 png_debug(1, "in png_handle_cHRM"); 00929 00930 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 00931 png_error(png_ptr, "Missing IHDR before cHRM"); 00932 00933 else if (png_ptr->mode & PNG_HAVE_IDAT) 00934 { 00935 png_warning(png_ptr, "Invalid cHRM after IDAT"); 00936 png_crc_finish(png_ptr, length); 00937 return; 00938 } 00939 00940 else if (png_ptr->mode & PNG_HAVE_PLTE) 00941 /* Should be an error, but we can cope with it */ 00942 png_warning(png_ptr, "Out of place cHRM chunk"); 00943 00944 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) 00945 # ifdef PNG_READ_sRGB_SUPPORTED 00946 && !(info_ptr->valid & PNG_INFO_sRGB) 00947 # endif 00948 ) 00949 { 00950 png_warning(png_ptr, "Duplicate cHRM chunk"); 00951 png_crc_finish(png_ptr, length); 00952 return; 00953 } 00954 00955 if (length != 32) 00956 { 00957 png_warning(png_ptr, "Incorrect cHRM chunk length"); 00958 png_crc_finish(png_ptr, length); 00959 return; 00960 } 00961 00962 png_crc_read(png_ptr, buf, 32); 00963 00964 if (png_crc_finish(png_ptr, 0)) 00965 return; 00966 00967 x_white = png_get_fixed_point(NULL, buf); 00968 y_white = png_get_fixed_point(NULL, buf + 4); 00969 x_red = png_get_fixed_point(NULL, buf + 8); 00970 y_red = png_get_fixed_point(NULL, buf + 12); 00971 x_green = png_get_fixed_point(NULL, buf + 16); 00972 y_green = png_get_fixed_point(NULL, buf + 20); 00973 x_blue = png_get_fixed_point(NULL, buf + 24); 00974 y_blue = png_get_fixed_point(NULL, buf + 28); 00975 00976 if (x_white == PNG_FIXED_ERROR || 00977 y_white == PNG_FIXED_ERROR || 00978 x_red == PNG_FIXED_ERROR || 00979 y_red == PNG_FIXED_ERROR || 00980 x_green == PNG_FIXED_ERROR || 00981 y_green == PNG_FIXED_ERROR || 00982 x_blue == PNG_FIXED_ERROR || 00983 y_blue == PNG_FIXED_ERROR) 00984 { 00985 png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); 00986 return; 00987 } 00988 00989 #ifdef PNG_READ_sRGB_SUPPORTED 00990 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) 00991 { 00992 if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || 00993 PNG_OUT_OF_RANGE(y_white, 32900, 1000) || 00994 PNG_OUT_OF_RANGE(x_red, 64000, 1000) || 00995 PNG_OUT_OF_RANGE(y_red, 33000, 1000) || 00996 PNG_OUT_OF_RANGE(x_green, 30000, 1000) || 00997 PNG_OUT_OF_RANGE(y_green, 60000, 1000) || 00998 PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || 00999 PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) 01000 { 01001 PNG_WARNING_PARAMETERS(p) 01002 01003 png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white); 01004 png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white); 01005 png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red); 01006 png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red); 01007 png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green); 01008 png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green); 01009 png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue); 01010 png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue); 01011 01012 png_formatted_warning(png_ptr, p, 01013 "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) " 01014 "when sRGB is also present"); 01015 } 01016 return; 01017 } 01018 #endif /* PNG_READ_sRGB_SUPPORTED */ 01019 01020 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 01021 /* Store the _white values as default coefficients for the rgb to gray 01022 * operation if it is supported. Check if the transform is already set to 01023 * avoid destroying the transform values. 01024 */ 01025 if (!png_ptr->rgb_to_gray_coefficients_set) 01026 { 01027 /* png_set_background has not been called and we haven't seen an sRGB 01028 * chunk yet. Find the XYZ of the three end points. 01029 */ 01030 png_XYZ XYZ; 01031 png_xy xy; 01032 01033 xy.redx = x_red; 01034 xy.redy = y_red; 01035 xy.greenx = x_green; 01036 xy.greeny = y_green; 01037 xy.bluex = x_blue; 01038 xy.bluey = y_blue; 01039 xy.whitex = x_white; 01040 xy.whitey = y_white; 01041 01042 if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy)) 01043 { 01044 /* The success case, because XYZ_from_xy normalises to a reference 01045 * white Y of 1.0 we just need to scale the numbers. This should 01046 * always work just fine. It is an internal error if this overflows. 01047 */ 01048 { 01049 png_fixed_point r, g, b; 01050 if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) && 01051 r >= 0 && r <= 32768 && 01052 png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) && 01053 g >= 0 && g <= 32768 && 01054 png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) && 01055 b >= 0 && b <= 32768 && 01056 r+g+b <= 32769) 01057 { 01058 /* We allow 0 coefficients here. r+g+b may be 32769 if two or 01059 * all of the coefficients were rounded up. Handle this by 01060 * reducing the *largest* coefficient by 1; this matches the 01061 * approach used for the default coefficients in pngrtran.c 01062 */ 01063 int add = 0; 01064 01065 if (r+g+b > 32768) 01066 add = -1; 01067 else if (r+g+b < 32768) 01068 add = 1; 01069 01070 if (add != 0) 01071 { 01072 if (g >= r && g >= b) 01073 g += add; 01074 else if (r >= g && r >= b) 01075 r += add; 01076 else 01077 b += add; 01078 } 01079 01080 /* Check for an internal error. */ 01081 if (r+g+b != 32768) 01082 png_error(png_ptr, 01083 "internal error handling cHRM coefficients"); 01084 01085 png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; 01086 png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; 01087 } 01088 01089 /* This is a png_error at present even though it could be ignored - 01090 * it should never happen, but it is important that if it does, the 01091 * bug is fixed. 01092 */ 01093 else 01094 png_error(png_ptr, "internal error handling cHRM->XYZ"); 01095 } 01096 } 01097 } 01098 #endif 01099 01100 png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, 01101 x_green, y_green, x_blue, y_blue); 01102 } 01103 #endif 01104 01105 #ifdef PNG_READ_sRGB_SUPPORTED 01106 void /* PRIVATE */ 01107 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01108 { 01109 int intent; 01110 png_byte buf[1]; 01111 01112 png_debug(1, "in png_handle_sRGB"); 01113 01114 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01115 png_error(png_ptr, "Missing IHDR before sRGB"); 01116 01117 else if (png_ptr->mode & PNG_HAVE_IDAT) 01118 { 01119 png_warning(png_ptr, "Invalid sRGB after IDAT"); 01120 png_crc_finish(png_ptr, length); 01121 return; 01122 } 01123 01124 else if (png_ptr->mode & PNG_HAVE_PLTE) 01125 /* Should be an error, but we can cope with it */ 01126 png_warning(png_ptr, "Out of place sRGB chunk"); 01127 01128 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 01129 { 01130 png_warning(png_ptr, "Duplicate sRGB chunk"); 01131 png_crc_finish(png_ptr, length); 01132 return; 01133 } 01134 01135 if (length != 1) 01136 { 01137 png_warning(png_ptr, "Incorrect sRGB chunk length"); 01138 png_crc_finish(png_ptr, length); 01139 return; 01140 } 01141 01142 png_crc_read(png_ptr, buf, 1); 01143 01144 if (png_crc_finish(png_ptr, 0)) 01145 return; 01146 01147 intent = buf[0]; 01148 01149 /* Check for bad intent */ 01150 if (intent >= PNG_sRGB_INTENT_LAST) 01151 { 01152 png_warning(png_ptr, "Unknown sRGB intent"); 01153 return; 01154 } 01155 01156 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) 01157 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) 01158 { 01159 if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500)) 01160 { 01161 PNG_WARNING_PARAMETERS(p) 01162 01163 png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, 01164 info_ptr->gamma); 01165 01166 png_formatted_warning(png_ptr, p, 01167 "Ignoring incorrect gAMA value @1 when sRGB is also present"); 01168 } 01169 } 01170 #endif /* PNG_READ_gAMA_SUPPORTED */ 01171 01172 #ifdef PNG_READ_cHRM_SUPPORTED 01173 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) 01174 if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || 01175 PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || 01176 PNG_OUT_OF_RANGE(info_ptr->x_red, 64000, 1000) || 01177 PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || 01178 PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || 01179 PNG_OUT_OF_RANGE(info_ptr->y_green, 60000, 1000) || 01180 PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || 01181 PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) 01182 { 01183 png_warning(png_ptr, 01184 "Ignoring incorrect cHRM value when sRGB is also present"); 01185 } 01186 #endif /* PNG_READ_cHRM_SUPPORTED */ 01187 01188 /* This is recorded for use when handling the cHRM chunk above. An sRGB 01189 * chunk unconditionally overwrites the coefficients for grayscale conversion 01190 * too. 01191 */ 01192 png_ptr->is_sRGB = 1; 01193 01194 # ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 01195 /* Don't overwrite user supplied values: */ 01196 if (!png_ptr->rgb_to_gray_coefficients_set) 01197 { 01198 /* These numbers come from the sRGB specification (or, since one has to 01199 * pay much money to get a copy, the wikipedia sRGB page) the 01200 * chromaticity values quoted have been inverted to get the reverse 01201 * transformation from RGB to XYZ and the 'Y' coefficients scaled by 01202 * 32768 (then rounded). 01203 * 01204 * sRGB and ITU Rec-709 both truncate the values for the D65 white 01205 * point to four digits and, even though it actually stores five 01206 * digits, the PNG spec gives the truncated value. 01207 * 01208 * This means that when the chromaticities are converted back to XYZ 01209 * end points we end up with (6968,23435,2366), which, as described in 01210 * pngrtran.c, would overflow. If the five digit precision and up is 01211 * used we get, instead: 01212 * 01213 * 6968*R + 23435*G + 2365*B 01214 * 01215 * (Notice that this rounds the blue coefficient down, rather than the 01216 * choice used in pngrtran.c which is to round the green one down.) 01217 */ 01218 png_ptr->rgb_to_gray_red_coeff = 6968; /* 0.212639005871510 */ 01219 png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */ 01220 /* png_ptr->rgb_to_gray_blue_coeff = 2366; 0.072192315360734 */ 01221 01222 /* The following keeps the cHRM chunk from destroying the 01223 * coefficients again in the event that it follows the sRGB chunk. 01224 */ 01225 png_ptr->rgb_to_gray_coefficients_set = 1; 01226 } 01227 # endif 01228 01229 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); 01230 } 01231 #endif /* PNG_READ_sRGB_SUPPORTED */ 01232 01233 #ifdef PNG_READ_iCCP_SUPPORTED 01234 void /* PRIVATE */ 01235 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01236 /* Note: this does not properly handle chunks that are > 64K under DOS */ 01237 { 01238 png_byte compression_type; 01239 png_bytep pC; 01240 png_charp profile; 01241 png_uint_32 skip = 0; 01242 png_uint_32 profile_size; 01243 png_alloc_size_t profile_length; 01244 png_size_t slength, prefix_length, data_length; 01245 01246 png_debug(1, "in png_handle_iCCP"); 01247 01248 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01249 png_error(png_ptr, "Missing IHDR before iCCP"); 01250 01251 else if (png_ptr->mode & PNG_HAVE_IDAT) 01252 { 01253 png_warning(png_ptr, "Invalid iCCP after IDAT"); 01254 png_crc_finish(png_ptr, length); 01255 return; 01256 } 01257 01258 else if (png_ptr->mode & PNG_HAVE_PLTE) 01259 /* Should be an error, but we can cope with it */ 01260 png_warning(png_ptr, "Out of place iCCP chunk"); 01261 01262 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) 01263 { 01264 png_warning(png_ptr, "Duplicate iCCP chunk"); 01265 png_crc_finish(png_ptr, length); 01266 return; 01267 } 01268 01269 #ifdef PNG_MAX_MALLOC_64K 01270 if (length > (png_uint_32)65535L) 01271 { 01272 png_warning(png_ptr, "iCCP chunk too large to fit in memory"); 01273 skip = length - (png_uint_32)65535L; 01274 length = (png_uint_32)65535L; 01275 } 01276 #endif 01277 01278 png_free(png_ptr, png_ptr->chunkdata); 01279 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 01280 slength = length; 01281 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 01282 01283 if (png_crc_finish(png_ptr, skip)) 01284 { 01285 png_free(png_ptr, png_ptr->chunkdata); 01286 png_ptr->chunkdata = NULL; 01287 return; 01288 } 01289 01290 png_ptr->chunkdata[slength] = 0x00; 01291 01292 for (profile = png_ptr->chunkdata; *profile; profile++) 01293 /* Empty loop to find end of name */ ; 01294 01295 ++profile; 01296 01297 /* There should be at least one zero (the compression type byte) 01298 * following the separator, and we should be on it 01299 */ 01300 if (profile >= png_ptr->chunkdata + slength - 1) 01301 { 01302 png_free(png_ptr, png_ptr->chunkdata); 01303 png_ptr->chunkdata = NULL; 01304 png_warning(png_ptr, "Malformed iCCP chunk"); 01305 return; 01306 } 01307 01308 /* Compression_type should always be zero */ 01309 compression_type = *profile++; 01310 01311 if (compression_type) 01312 { 01313 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); 01314 compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 01315 wrote nonzero) */ 01316 } 01317 01318 prefix_length = profile - png_ptr->chunkdata; 01319 png_decompress_chunk(png_ptr, compression_type, 01320 slength, prefix_length, &data_length); 01321 01322 profile_length = data_length - prefix_length; 01323 01324 if (prefix_length > data_length || profile_length < 4) 01325 { 01326 png_free(png_ptr, png_ptr->chunkdata); 01327 png_ptr->chunkdata = NULL; 01328 png_warning(png_ptr, "Profile size field missing from iCCP chunk"); 01329 return; 01330 } 01331 01332 /* Check the profile_size recorded in the first 32 bits of the ICC profile */ 01333 pC = (png_bytep)(png_ptr->chunkdata + prefix_length); 01334 profile_size = ((*(pC )) << 24) | 01335 ((*(pC + 1)) << 16) | 01336 ((*(pC + 2)) << 8) | 01337 ((*(pC + 3)) ); 01338 01339 /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, 01340 * because profile_size is a 32 bit value. 01341 */ 01342 if (profile_size < profile_length) 01343 profile_length = profile_size; 01344 01345 /* And the following guarantees that profile_size == profile_length. */ 01346 if (profile_size > profile_length) 01347 { 01348 PNG_WARNING_PARAMETERS(p) 01349 01350 png_free(png_ptr, png_ptr->chunkdata); 01351 png_ptr->chunkdata = NULL; 01352 01353 png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size); 01354 png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length); 01355 png_formatted_warning(png_ptr, p, 01356 "Ignoring iCCP chunk with declared size = @1 and actual length = @2"); 01357 return; 01358 } 01359 01360 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, 01361 compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, 01362 profile_size); 01363 png_free(png_ptr, png_ptr->chunkdata); 01364 png_ptr->chunkdata = NULL; 01365 } 01366 #endif /* PNG_READ_iCCP_SUPPORTED */ 01367 01368 #ifdef PNG_READ_sPLT_SUPPORTED 01369 void /* PRIVATE */ 01370 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01371 /* Note: this does not properly handle chunks that are > 64K under DOS */ 01372 { 01373 png_bytep entry_start; 01374 png_sPLT_t new_palette; 01375 png_sPLT_entryp pp; 01376 png_uint_32 data_length; 01377 int entry_size, i; 01378 png_uint_32 skip = 0; 01379 png_size_t slength; 01380 png_uint_32 dl; 01381 png_size_t max_dl; 01382 01383 png_debug(1, "in png_handle_sPLT"); 01384 01385 #ifdef PNG_USER_LIMITS_SUPPORTED 01386 01387 if (png_ptr->user_chunk_cache_max != 0) 01388 { 01389 if (png_ptr->user_chunk_cache_max == 1) 01390 { 01391 png_crc_finish(png_ptr, length); 01392 return; 01393 } 01394 01395 if (--png_ptr->user_chunk_cache_max == 1) 01396 { 01397 png_warning(png_ptr, "No space in chunk cache for sPLT"); 01398 png_crc_finish(png_ptr, length); 01399 return; 01400 } 01401 } 01402 #endif 01403 01404 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01405 png_error(png_ptr, "Missing IHDR before sPLT"); 01406 01407 else if (png_ptr->mode & PNG_HAVE_IDAT) 01408 { 01409 png_warning(png_ptr, "Invalid sPLT after IDAT"); 01410 png_crc_finish(png_ptr, length); 01411 return; 01412 } 01413 01414 #ifdef PNG_MAX_MALLOC_64K 01415 if (length > (png_uint_32)65535L) 01416 { 01417 png_warning(png_ptr, "sPLT chunk too large to fit in memory"); 01418 skip = length - (png_uint_32)65535L; 01419 length = (png_uint_32)65535L; 01420 } 01421 #endif 01422 01423 png_free(png_ptr, png_ptr->chunkdata); 01424 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 01425 01426 /* WARNING: this may break if size_t is less than 32 bits; it is assumed 01427 * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a 01428 * potential breakage point if the types in pngconf.h aren't exactly right. 01429 */ 01430 slength = length; 01431 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 01432 01433 if (png_crc_finish(png_ptr, skip)) 01434 { 01435 png_free(png_ptr, png_ptr->chunkdata); 01436 png_ptr->chunkdata = NULL; 01437 return; 01438 } 01439 01440 png_ptr->chunkdata[slength] = 0x00; 01441 01442 for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; 01443 entry_start++) 01444 /* Empty loop to find end of name */ ; 01445 01446 ++entry_start; 01447 01448 /* A sample depth should follow the separator, and we should be on it */ 01449 if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) 01450 { 01451 png_free(png_ptr, png_ptr->chunkdata); 01452 png_ptr->chunkdata = NULL; 01453 png_warning(png_ptr, "malformed sPLT chunk"); 01454 return; 01455 } 01456 01457 new_palette.depth = *entry_start++; 01458 entry_size = (new_palette.depth == 8 ? 6 : 10); 01459 /* This must fit in a png_uint_32 because it is derived from the original 01460 * chunk data length (and use 'length', not 'slength' here for clarity - 01461 * they are guaranteed to be the same, see the tests above.) 01462 */ 01463 data_length = length - (png_uint_32)(entry_start - 01464 (png_bytep)png_ptr->chunkdata); 01465 01466 /* Integrity-check the data length */ 01467 if (data_length % entry_size) 01468 { 01469 png_free(png_ptr, png_ptr->chunkdata); 01470 png_ptr->chunkdata = NULL; 01471 png_warning(png_ptr, "sPLT chunk has bad length"); 01472 return; 01473 } 01474 01475 dl = (png_int_32)(data_length / entry_size); 01476 max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); 01477 01478 if (dl > max_dl) 01479 { 01480 png_warning(png_ptr, "sPLT chunk too long"); 01481 return; 01482 } 01483 01484 new_palette.nentries = (png_int_32)(data_length / entry_size); 01485 01486 new_palette.entries = (png_sPLT_entryp)png_malloc_warn( 01487 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); 01488 01489 if (new_palette.entries == NULL) 01490 { 01491 png_warning(png_ptr, "sPLT chunk requires too much memory"); 01492 return; 01493 } 01494 01495 #ifdef PNG_POINTER_INDEXING_SUPPORTED 01496 for (i = 0; i < new_palette.nentries; i++) 01497 { 01498 pp = new_palette.entries + i; 01499 01500 if (new_palette.depth == 8) 01501 { 01502 pp->red = *entry_start++; 01503 pp->green = *entry_start++; 01504 pp->blue = *entry_start++; 01505 pp->alpha = *entry_start++; 01506 } 01507 01508 else 01509 { 01510 pp->red = png_get_uint_16(entry_start); entry_start += 2; 01511 pp->green = png_get_uint_16(entry_start); entry_start += 2; 01512 pp->blue = png_get_uint_16(entry_start); entry_start += 2; 01513 pp->alpha = png_get_uint_16(entry_start); entry_start += 2; 01514 } 01515 01516 pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 01517 } 01518 #else 01519 pp = new_palette.entries; 01520 01521 for (i = 0; i < new_palette.nentries; i++) 01522 { 01523 01524 if (new_palette.depth == 8) 01525 { 01526 pp[i].red = *entry_start++; 01527 pp[i].green = *entry_start++; 01528 pp[i].blue = *entry_start++; 01529 pp[i].alpha = *entry_start++; 01530 } 01531 01532 else 01533 { 01534 pp[i].red = png_get_uint_16(entry_start); entry_start += 2; 01535 pp[i].green = png_get_uint_16(entry_start); entry_start += 2; 01536 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; 01537 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; 01538 } 01539 01540 pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2; 01541 } 01542 #endif 01543 01544 /* Discard all chunk data except the name and stash that */ 01545 new_palette.name = png_ptr->chunkdata; 01546 01547 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); 01548 01549 png_free(png_ptr, png_ptr->chunkdata); 01550 png_ptr->chunkdata = NULL; 01551 png_free(png_ptr, new_palette.entries); 01552 } 01553 #endif /* PNG_READ_sPLT_SUPPORTED */ 01554 01555 #ifdef PNG_READ_tRNS_SUPPORTED 01556 void /* PRIVATE */ 01557 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01558 { 01559 png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; 01560 01561 png_debug(1, "in png_handle_tRNS"); 01562 01563 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01564 png_error(png_ptr, "Missing IHDR before tRNS"); 01565 01566 else if (png_ptr->mode & PNG_HAVE_IDAT) 01567 { 01568 png_warning(png_ptr, "Invalid tRNS after IDAT"); 01569 png_crc_finish(png_ptr, length); 01570 return; 01571 } 01572 01573 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 01574 { 01575 png_warning(png_ptr, "Duplicate tRNS chunk"); 01576 png_crc_finish(png_ptr, length); 01577 return; 01578 } 01579 01580 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 01581 { 01582 png_byte buf[2]; 01583 01584 if (length != 2) 01585 { 01586 png_warning(png_ptr, "Incorrect tRNS chunk length"); 01587 png_crc_finish(png_ptr, length); 01588 return; 01589 } 01590 01591 png_crc_read(png_ptr, buf, 2); 01592 png_ptr->num_trans = 1; 01593 png_ptr->trans_color.gray = png_get_uint_16(buf); 01594 } 01595 01596 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 01597 { 01598 png_byte buf[6]; 01599 01600 if (length != 6) 01601 { 01602 png_warning(png_ptr, "Incorrect tRNS chunk length"); 01603 png_crc_finish(png_ptr, length); 01604 return; 01605 } 01606 01607 png_crc_read(png_ptr, buf, (png_size_t)length); 01608 png_ptr->num_trans = 1; 01609 png_ptr->trans_color.red = png_get_uint_16(buf); 01610 png_ptr->trans_color.green = png_get_uint_16(buf + 2); 01611 png_ptr->trans_color.blue = png_get_uint_16(buf + 4); 01612 } 01613 01614 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 01615 { 01616 if (!(png_ptr->mode & PNG_HAVE_PLTE)) 01617 { 01618 /* Should be an error, but we can cope with it. */ 01619 png_warning(png_ptr, "Missing PLTE before tRNS"); 01620 } 01621 01622 if (length > (png_uint_32)png_ptr->num_palette || 01623 length > PNG_MAX_PALETTE_LENGTH) 01624 { 01625 png_warning(png_ptr, "Incorrect tRNS chunk length"); 01626 png_crc_finish(png_ptr, length); 01627 return; 01628 } 01629 01630 if (length == 0) 01631 { 01632 png_warning(png_ptr, "Zero length tRNS chunk"); 01633 png_crc_finish(png_ptr, length); 01634 return; 01635 } 01636 01637 png_crc_read(png_ptr, readbuf, (png_size_t)length); 01638 png_ptr->num_trans = (png_uint_16)length; 01639 } 01640 01641 else 01642 { 01643 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); 01644 png_crc_finish(png_ptr, length); 01645 return; 01646 } 01647 01648 if (png_crc_finish(png_ptr, 0)) 01649 { 01650 png_ptr->num_trans = 0; 01651 return; 01652 } 01653 01654 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, 01655 &(png_ptr->trans_color)); 01656 } 01657 #endif 01658 01659 #ifdef PNG_READ_bKGD_SUPPORTED 01660 void /* PRIVATE */ 01661 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01662 { 01663 png_size_t truelen; 01664 png_byte buf[6]; 01665 png_color_16 background; 01666 01667 png_debug(1, "in png_handle_bKGD"); 01668 01669 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01670 png_error(png_ptr, "Missing IHDR before bKGD"); 01671 01672 else if (png_ptr->mode & PNG_HAVE_IDAT) 01673 { 01674 png_warning(png_ptr, "Invalid bKGD after IDAT"); 01675 png_crc_finish(png_ptr, length); 01676 return; 01677 } 01678 01679 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 01680 !(png_ptr->mode & PNG_HAVE_PLTE)) 01681 { 01682 png_warning(png_ptr, "Missing PLTE before bKGD"); 01683 png_crc_finish(png_ptr, length); 01684 return; 01685 } 01686 01687 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) 01688 { 01689 png_warning(png_ptr, "Duplicate bKGD chunk"); 01690 png_crc_finish(png_ptr, length); 01691 return; 01692 } 01693 01694 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 01695 truelen = 1; 01696 01697 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 01698 truelen = 6; 01699 01700 else 01701 truelen = 2; 01702 01703 if (length != truelen) 01704 { 01705 png_warning(png_ptr, "Incorrect bKGD chunk length"); 01706 png_crc_finish(png_ptr, length); 01707 return; 01708 } 01709 01710 png_crc_read(png_ptr, buf, truelen); 01711 01712 if (png_crc_finish(png_ptr, 0)) 01713 return; 01714 01715 /* We convert the index value into RGB components so that we can allow 01716 * arbitrary RGB values for background when we have transparency, and 01717 * so it is easy to determine the RGB values of the background color 01718 * from the info_ptr struct. 01719 */ 01720 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 01721 { 01722 background.index = buf[0]; 01723 01724 if (info_ptr && info_ptr->num_palette) 01725 { 01726 if (buf[0] >= info_ptr->num_palette) 01727 { 01728 png_warning(png_ptr, "Incorrect bKGD chunk index value"); 01729 return; 01730 } 01731 01732 background.red = (png_uint_16)png_ptr->palette[buf[0]].red; 01733 background.green = (png_uint_16)png_ptr->palette[buf[0]].green; 01734 background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; 01735 } 01736 01737 else 01738 background.red = background.green = background.blue = 0; 01739 01740 background.gray = 0; 01741 } 01742 01743 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ 01744 { 01745 background.index = 0; 01746 background.red = 01747 background.green = 01748 background.blue = 01749 background.gray = png_get_uint_16(buf); 01750 } 01751 01752 else 01753 { 01754 background.index = 0; 01755 background.red = png_get_uint_16(buf); 01756 background.green = png_get_uint_16(buf + 2); 01757 background.blue = png_get_uint_16(buf + 4); 01758 background.gray = 0; 01759 } 01760 01761 png_set_bKGD(png_ptr, info_ptr, &background); 01762 } 01763 #endif 01764 01765 #ifdef PNG_READ_hIST_SUPPORTED 01766 void /* PRIVATE */ 01767 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01768 { 01769 unsigned int num, i; 01770 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; 01771 01772 png_debug(1, "in png_handle_hIST"); 01773 01774 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01775 png_error(png_ptr, "Missing IHDR before hIST"); 01776 01777 else if (png_ptr->mode & PNG_HAVE_IDAT) 01778 { 01779 png_warning(png_ptr, "Invalid hIST after IDAT"); 01780 png_crc_finish(png_ptr, length); 01781 return; 01782 } 01783 01784 else if (!(png_ptr->mode & PNG_HAVE_PLTE)) 01785 { 01786 png_warning(png_ptr, "Missing PLTE before hIST"); 01787 png_crc_finish(png_ptr, length); 01788 return; 01789 } 01790 01791 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) 01792 { 01793 png_warning(png_ptr, "Duplicate hIST chunk"); 01794 png_crc_finish(png_ptr, length); 01795 return; 01796 } 01797 01798 num = length / 2 ; 01799 01800 if (num != (unsigned int)png_ptr->num_palette || num > 01801 (unsigned int)PNG_MAX_PALETTE_LENGTH) 01802 { 01803 png_warning(png_ptr, "Incorrect hIST chunk length"); 01804 png_crc_finish(png_ptr, length); 01805 return; 01806 } 01807 01808 for (i = 0; i < num; i++) 01809 { 01810 png_byte buf[2]; 01811 01812 png_crc_read(png_ptr, buf, 2); 01813 readbuf[i] = png_get_uint_16(buf); 01814 } 01815 01816 if (png_crc_finish(png_ptr, 0)) 01817 return; 01818 01819 png_set_hIST(png_ptr, info_ptr, readbuf); 01820 } 01821 #endif 01822 01823 #ifdef PNG_READ_pHYs_SUPPORTED 01824 void /* PRIVATE */ 01825 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01826 { 01827 png_byte buf[9]; 01828 png_uint_32 res_x, res_y; 01829 int unit_type; 01830 01831 png_debug(1, "in png_handle_pHYs"); 01832 01833 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01834 png_error(png_ptr, "Missing IHDR before pHYs"); 01835 01836 else if (png_ptr->mode & PNG_HAVE_IDAT) 01837 { 01838 png_warning(png_ptr, "Invalid pHYs after IDAT"); 01839 png_crc_finish(png_ptr, length); 01840 return; 01841 } 01842 01843 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) 01844 { 01845 png_warning(png_ptr, "Duplicate pHYs chunk"); 01846 png_crc_finish(png_ptr, length); 01847 return; 01848 } 01849 01850 if (length != 9) 01851 { 01852 png_warning(png_ptr, "Incorrect pHYs chunk length"); 01853 png_crc_finish(png_ptr, length); 01854 return; 01855 } 01856 01857 png_crc_read(png_ptr, buf, 9); 01858 01859 if (png_crc_finish(png_ptr, 0)) 01860 return; 01861 01862 res_x = png_get_uint_32(buf); 01863 res_y = png_get_uint_32(buf + 4); 01864 unit_type = buf[8]; 01865 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); 01866 } 01867 #endif 01868 01869 #ifdef PNG_READ_oFFs_SUPPORTED 01870 void /* PRIVATE */ 01871 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01872 { 01873 png_byte buf[9]; 01874 png_int_32 offset_x, offset_y; 01875 int unit_type; 01876 01877 png_debug(1, "in png_handle_oFFs"); 01878 01879 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01880 png_error(png_ptr, "Missing IHDR before oFFs"); 01881 01882 else if (png_ptr->mode & PNG_HAVE_IDAT) 01883 { 01884 png_warning(png_ptr, "Invalid oFFs after IDAT"); 01885 png_crc_finish(png_ptr, length); 01886 return; 01887 } 01888 01889 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) 01890 { 01891 png_warning(png_ptr, "Duplicate oFFs chunk"); 01892 png_crc_finish(png_ptr, length); 01893 return; 01894 } 01895 01896 if (length != 9) 01897 { 01898 png_warning(png_ptr, "Incorrect oFFs chunk length"); 01899 png_crc_finish(png_ptr, length); 01900 return; 01901 } 01902 01903 png_crc_read(png_ptr, buf, 9); 01904 01905 if (png_crc_finish(png_ptr, 0)) 01906 return; 01907 01908 offset_x = png_get_int_32(buf); 01909 offset_y = png_get_int_32(buf + 4); 01910 unit_type = buf[8]; 01911 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); 01912 } 01913 #endif 01914 01915 #ifdef PNG_READ_pCAL_SUPPORTED 01916 /* Read the pCAL chunk (described in the PNG Extensions document) */ 01917 void /* PRIVATE */ 01918 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 01919 { 01920 png_int_32 X0, X1; 01921 png_byte type, nparams; 01922 png_charp buf, units, endptr; 01923 png_charpp params; 01924 png_size_t slength; 01925 int i; 01926 01927 png_debug(1, "in png_handle_pCAL"); 01928 01929 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 01930 png_error(png_ptr, "Missing IHDR before pCAL"); 01931 01932 else if (png_ptr->mode & PNG_HAVE_IDAT) 01933 { 01934 png_warning(png_ptr, "Invalid pCAL after IDAT"); 01935 png_crc_finish(png_ptr, length); 01936 return; 01937 } 01938 01939 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) 01940 { 01941 png_warning(png_ptr, "Duplicate pCAL chunk"); 01942 png_crc_finish(png_ptr, length); 01943 return; 01944 } 01945 01946 png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", 01947 length + 1); 01948 png_free(png_ptr, png_ptr->chunkdata); 01949 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 01950 01951 if (png_ptr->chunkdata == NULL) 01952 { 01953 png_warning(png_ptr, "No memory for pCAL purpose"); 01954 return; 01955 } 01956 01957 slength = length; 01958 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 01959 01960 if (png_crc_finish(png_ptr, 0)) 01961 { 01962 png_free(png_ptr, png_ptr->chunkdata); 01963 png_ptr->chunkdata = NULL; 01964 return; 01965 } 01966 01967 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 01968 01969 png_debug(3, "Finding end of pCAL purpose string"); 01970 for (buf = png_ptr->chunkdata; *buf; buf++) 01971 /* Empty loop */ ; 01972 01973 endptr = png_ptr->chunkdata + slength; 01974 01975 /* We need to have at least 12 bytes after the purpose string 01976 * in order to get the parameter information. 01977 */ 01978 if (endptr <= buf + 12) 01979 { 01980 png_warning(png_ptr, "Invalid pCAL data"); 01981 png_free(png_ptr, png_ptr->chunkdata); 01982 png_ptr->chunkdata = NULL; 01983 return; 01984 } 01985 01986 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); 01987 X0 = png_get_int_32((png_bytep)buf+1); 01988 X1 = png_get_int_32((png_bytep)buf+5); 01989 type = buf[9]; 01990 nparams = buf[10]; 01991 units = buf + 11; 01992 01993 png_debug(3, "Checking pCAL equation type and number of parameters"); 01994 /* Check that we have the right number of parameters for known 01995 * equation types. 01996 */ 01997 if ((type == PNG_EQUATION_LINEAR && nparams != 2) || 01998 (type == PNG_EQUATION_BASE_E && nparams != 3) || 01999 (type == PNG_EQUATION_ARBITRARY && nparams != 3) || 02000 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) 02001 { 02002 png_warning(png_ptr, "Invalid pCAL parameters for equation type"); 02003 png_free(png_ptr, png_ptr->chunkdata); 02004 png_ptr->chunkdata = NULL; 02005 return; 02006 } 02007 02008 else if (type >= PNG_EQUATION_LAST) 02009 { 02010 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 02011 } 02012 02013 for (buf = units; *buf; buf++) 02014 /* Empty loop to move past the units string. */ ; 02015 02016 png_debug(3, "Allocating pCAL parameters array"); 02017 02018 params = (png_charpp)png_malloc_warn(png_ptr, 02019 (png_size_t)(nparams * png_sizeof(png_charp))); 02020 02021 if (params == NULL) 02022 { 02023 png_free(png_ptr, png_ptr->chunkdata); 02024 png_ptr->chunkdata = NULL; 02025 png_warning(png_ptr, "No memory for pCAL params"); 02026 return; 02027 } 02028 02029 /* Get pointers to the start of each parameter string. */ 02030 for (i = 0; i < (int)nparams; i++) 02031 { 02032 buf++; /* Skip the null string terminator from previous parameter. */ 02033 02034 png_debug1(3, "Reading pCAL parameter %d", i); 02035 02036 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) 02037 /* Empty loop to move past each parameter string */ ; 02038 02039 /* Make sure we haven't run out of data yet */ 02040 if (buf > endptr) 02041 { 02042 png_warning(png_ptr, "Invalid pCAL data"); 02043 png_free(png_ptr, png_ptr->chunkdata); 02044 png_ptr->chunkdata = NULL; 02045 png_free(png_ptr, params); 02046 return; 02047 } 02048 } 02049 02050 png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, 02051 units, params); 02052 02053 png_free(png_ptr, png_ptr->chunkdata); 02054 png_ptr->chunkdata = NULL; 02055 png_free(png_ptr, params); 02056 } 02057 #endif 02058 02059 #ifdef PNG_READ_sCAL_SUPPORTED 02060 /* Read the sCAL chunk */ 02061 void /* PRIVATE */ 02062 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 02063 { 02064 png_size_t slength, i; 02065 int state; 02066 02067 png_debug(1, "in png_handle_sCAL"); 02068 02069 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 02070 png_error(png_ptr, "Missing IHDR before sCAL"); 02071 02072 else if (png_ptr->mode & PNG_HAVE_IDAT) 02073 { 02074 png_warning(png_ptr, "Invalid sCAL after IDAT"); 02075 png_crc_finish(png_ptr, length); 02076 return; 02077 } 02078 02079 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) 02080 { 02081 png_warning(png_ptr, "Duplicate sCAL chunk"); 02082 png_crc_finish(png_ptr, length); 02083 return; 02084 } 02085 02086 /* Need unit type, width, \0, height: minimum 4 bytes */ 02087 else if (length < 4) 02088 { 02089 png_warning(png_ptr, "sCAL chunk too short"); 02090 png_crc_finish(png_ptr, length); 02091 return; 02092 } 02093 02094 png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", 02095 length + 1); 02096 02097 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 02098 02099 if (png_ptr->chunkdata == NULL) 02100 { 02101 png_warning(png_ptr, "Out of memory while processing sCAL chunk"); 02102 png_crc_finish(png_ptr, length); 02103 return; 02104 } 02105 02106 slength = length; 02107 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 02108 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 02109 02110 if (png_crc_finish(png_ptr, 0)) 02111 { 02112 png_free(png_ptr, png_ptr->chunkdata); 02113 png_ptr->chunkdata = NULL; 02114 return; 02115 } 02116 02117 /* Validate the unit. */ 02118 if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) 02119 { 02120 png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); 02121 png_free(png_ptr, png_ptr->chunkdata); 02122 png_ptr->chunkdata = NULL; 02123 return; 02124 } 02125 02126 /* Validate the ASCII numbers, need two ASCII numbers separated by 02127 * a '\0' and they need to fit exactly in the chunk data. 02128 */ 02129 i = 1; 02130 state = 0; 02131 02132 if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || 02133 i >= slength || png_ptr->chunkdata[i++] != 0) 02134 png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); 02135 02136 else if (!PNG_FP_IS_POSITIVE(state)) 02137 png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width"); 02138 02139 else 02140 { 02141 png_size_t heighti = i; 02142 02143 state = 0; 02144 if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) || 02145 i != slength) 02146 png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); 02147 02148 else if (!PNG_FP_IS_POSITIVE(state)) 02149 png_warning(png_ptr, 02150 "Invalid sCAL chunk ignored: non-positive height"); 02151 02152 else 02153 /* This is the (only) success case. */ 02154 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], 02155 png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); 02156 } 02157 02158 /* Clean up - just free the temporarily allocated buffer. */ 02159 png_free(png_ptr, png_ptr->chunkdata); 02160 png_ptr->chunkdata = NULL; 02161 } 02162 #endif 02163 02164 #ifdef PNG_READ_tIME_SUPPORTED 02165 void /* PRIVATE */ 02166 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 02167 { 02168 png_byte buf[7]; 02169 png_time mod_time; 02170 02171 png_debug(1, "in png_handle_tIME"); 02172 02173 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 02174 png_error(png_ptr, "Out of place tIME chunk"); 02175 02176 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 02177 { 02178 png_warning(png_ptr, "Duplicate tIME chunk"); 02179 png_crc_finish(png_ptr, length); 02180 return; 02181 } 02182 02183 if (png_ptr->mode & PNG_HAVE_IDAT) 02184 png_ptr->mode |= PNG_AFTER_IDAT; 02185 02186 if (length != 7) 02187 { 02188 png_warning(png_ptr, "Incorrect tIME chunk length"); 02189 png_crc_finish(png_ptr, length); 02190 return; 02191 } 02192 02193 png_crc_read(png_ptr, buf, 7); 02194 02195 if (png_crc_finish(png_ptr, 0)) 02196 return; 02197 02198 mod_time.second = buf[6]; 02199 mod_time.minute = buf[5]; 02200 mod_time.hour = buf[4]; 02201 mod_time.day = buf[3]; 02202 mod_time.month = buf[2]; 02203 mod_time.year = png_get_uint_16(buf); 02204 02205 png_set_tIME(png_ptr, info_ptr, &mod_time); 02206 } 02207 #endif 02208 02209 #ifdef PNG_READ_tEXt_SUPPORTED 02210 /* Note: this does not properly handle chunks that are > 64K under DOS */ 02211 void /* PRIVATE */ 02212 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 02213 { 02214 png_textp text_ptr; 02215 png_charp key; 02216 png_charp text; 02217 png_uint_32 skip = 0; 02218 png_size_t slength; 02219 int ret; 02220 02221 png_debug(1, "in png_handle_tEXt"); 02222 02223 #ifdef PNG_USER_LIMITS_SUPPORTED 02224 if (png_ptr->user_chunk_cache_max != 0) 02225 { 02226 if (png_ptr->user_chunk_cache_max == 1) 02227 { 02228 png_crc_finish(png_ptr, length); 02229 return; 02230 } 02231 02232 if (--png_ptr->user_chunk_cache_max == 1) 02233 { 02234 png_warning(png_ptr, "No space in chunk cache for tEXt"); 02235 png_crc_finish(png_ptr, length); 02236 return; 02237 } 02238 } 02239 #endif 02240 02241 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 02242 png_error(png_ptr, "Missing IHDR before tEXt"); 02243 02244 if (png_ptr->mode & PNG_HAVE_IDAT) 02245 png_ptr->mode |= PNG_AFTER_IDAT; 02246 02247 #ifdef PNG_MAX_MALLOC_64K 02248 if (length > (png_uint_32)65535L) 02249 { 02250 png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 02251 skip = length - (png_uint_32)65535L; 02252 length = (png_uint_32)65535L; 02253 } 02254 #endif 02255 02256 png_free(png_ptr, png_ptr->chunkdata); 02257 02258 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 02259 02260 if (png_ptr->chunkdata == NULL) 02261 { 02262 png_warning(png_ptr, "No memory to process text chunk"); 02263 return; 02264 } 02265 02266 slength = length; 02267 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 02268 02269 if (png_crc_finish(png_ptr, skip)) 02270 { 02271 png_free(png_ptr, png_ptr->chunkdata); 02272 png_ptr->chunkdata = NULL; 02273 return; 02274 } 02275 02276 key = png_ptr->chunkdata; 02277 02278 key[slength] = 0x00; 02279 02280 for (text = key; *text; text++) 02281 /* Empty loop to find end of key */ ; 02282 02283 if (text != key + slength) 02284 text++; 02285 02286 text_ptr = (png_textp)png_malloc_warn(png_ptr, 02287 png_sizeof(png_text)); 02288 02289 if (text_ptr == NULL) 02290 { 02291 png_warning(png_ptr, "Not enough memory to process text chunk"); 02292 png_free(png_ptr, png_ptr->chunkdata); 02293 png_ptr->chunkdata = NULL; 02294 return; 02295 } 02296 02297 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 02298 text_ptr->key = key; 02299 text_ptr->lang = NULL; 02300 text_ptr->lang_key = NULL; 02301 text_ptr->itxt_length = 0; 02302 text_ptr->text = text; 02303 text_ptr->text_length = png_strlen(text); 02304 02305 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 02306 02307 png_free(png_ptr, png_ptr->chunkdata); 02308 png_ptr->chunkdata = NULL; 02309 png_free(png_ptr, text_ptr); 02310 02311 if (ret) 02312 png_warning(png_ptr, "Insufficient memory to process text chunk"); 02313 } 02314 #endif 02315 02316 #ifdef PNG_READ_zTXt_SUPPORTED 02317 /* Note: this does not correctly handle chunks that are > 64K under DOS */ 02318 void /* PRIVATE */ 02319 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 02320 { 02321 png_textp text_ptr; 02322 png_charp text; 02323 int comp_type; 02324 int ret; 02325 png_size_t slength, prefix_len, data_len; 02326 02327 png_debug(1, "in png_handle_zTXt"); 02328 02329 #ifdef PNG_USER_LIMITS_SUPPORTED 02330 if (png_ptr->user_chunk_cache_max != 0) 02331 { 02332 if (png_ptr->user_chunk_cache_max == 1) 02333 { 02334 png_crc_finish(png_ptr, length); 02335 return; 02336 } 02337 02338 if (--png_ptr->user_chunk_cache_max == 1) 02339 { 02340 png_warning(png_ptr, "No space in chunk cache for zTXt"); 02341 png_crc_finish(png_ptr, length); 02342 return; 02343 } 02344 } 02345 #endif 02346 02347 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 02348 png_error(png_ptr, "Missing IHDR before zTXt"); 02349 02350 if (png_ptr->mode & PNG_HAVE_IDAT) 02351 png_ptr->mode |= PNG_AFTER_IDAT; 02352 02353 #ifdef PNG_MAX_MALLOC_64K 02354 /* We will no doubt have problems with chunks even half this size, but 02355 * there is no hard and fast rule to tell us where to stop. 02356 */ 02357 if (length > (png_uint_32)65535L) 02358 { 02359 png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 02360 png_crc_finish(png_ptr, length); 02361 return; 02362 } 02363 #endif 02364 02365 png_free(png_ptr, png_ptr->chunkdata); 02366 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 02367 02368 if (png_ptr->chunkdata == NULL) 02369 { 02370 png_warning(png_ptr, "Out of memory processing zTXt chunk"); 02371 return; 02372 } 02373 02374 slength = length; 02375 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 02376 02377 if (png_crc_finish(png_ptr, 0)) 02378 { 02379 png_free(png_ptr, png_ptr->chunkdata); 02380 png_ptr->chunkdata = NULL; 02381 return; 02382 } 02383 02384 png_ptr->chunkdata[slength] = 0x00; 02385 02386 for (text = png_ptr->chunkdata; *text; text++) 02387 /* Empty loop */ ; 02388 02389 /* zTXt must have some text after the chunkdataword */ 02390 if (text >= png_ptr->chunkdata + slength - 2) 02391 { 02392 png_warning(png_ptr, "Truncated zTXt chunk"); 02393 png_free(png_ptr, png_ptr->chunkdata); 02394 png_ptr->chunkdata = NULL; 02395 return; 02396 } 02397 02398 else 02399 { 02400 comp_type = *(++text); 02401 02402 if (comp_type != PNG_TEXT_COMPRESSION_zTXt) 02403 { 02404 png_warning(png_ptr, "Unknown compression type in zTXt chunk"); 02405 comp_type = PNG_TEXT_COMPRESSION_zTXt; 02406 } 02407 02408 text++; /* Skip the compression_method byte */ 02409 } 02410 02411 prefix_len = text - png_ptr->chunkdata; 02412 02413 png_decompress_chunk(png_ptr, comp_type, 02414 (png_size_t)length, prefix_len, &data_len); 02415 02416 text_ptr = (png_textp)png_malloc_warn(png_ptr, 02417 png_sizeof(png_text)); 02418 02419 if (text_ptr == NULL) 02420 { 02421 png_warning(png_ptr, "Not enough memory to process zTXt chunk"); 02422 png_free(png_ptr, png_ptr->chunkdata); 02423 png_ptr->chunkdata = NULL; 02424 return; 02425 } 02426 02427 text_ptr->compression = comp_type; 02428 text_ptr->key = png_ptr->chunkdata; 02429 text_ptr->lang = NULL; 02430 text_ptr->lang_key = NULL; 02431 text_ptr->itxt_length = 0; 02432 text_ptr->text = png_ptr->chunkdata + prefix_len; 02433 text_ptr->text_length = data_len; 02434 02435 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 02436 02437 png_free(png_ptr, text_ptr); 02438 png_free(png_ptr, png_ptr->chunkdata); 02439 png_ptr->chunkdata = NULL; 02440 02441 if (ret) 02442 png_error(png_ptr, "Insufficient memory to store zTXt chunk"); 02443 } 02444 #endif 02445 02446 #ifdef PNG_READ_iTXt_SUPPORTED 02447 /* Note: this does not correctly handle chunks that are > 64K under DOS */ 02448 void /* PRIVATE */ 02449 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 02450 { 02451 png_textp text_ptr; 02452 png_charp key, lang, text, lang_key; 02453 int comp_flag; 02454 int comp_type = 0; 02455 int ret; 02456 png_size_t slength, prefix_len, data_len; 02457 02458 png_debug(1, "in png_handle_iTXt"); 02459 02460 #ifdef PNG_USER_LIMITS_SUPPORTED 02461 if (png_ptr->user_chunk_cache_max != 0) 02462 { 02463 if (png_ptr->user_chunk_cache_max == 1) 02464 { 02465 png_crc_finish(png_ptr, length); 02466 return; 02467 } 02468 02469 if (--png_ptr->user_chunk_cache_max == 1) 02470 { 02471 png_warning(png_ptr, "No space in chunk cache for iTXt"); 02472 png_crc_finish(png_ptr, length); 02473 return; 02474 } 02475 } 02476 #endif 02477 02478 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 02479 png_error(png_ptr, "Missing IHDR before iTXt"); 02480 02481 if (png_ptr->mode & PNG_HAVE_IDAT) 02482 png_ptr->mode |= PNG_AFTER_IDAT; 02483 02484 #ifdef PNG_MAX_MALLOC_64K 02485 /* We will no doubt have problems with chunks even half this size, but 02486 * there is no hard and fast rule to tell us where to stop. 02487 */ 02488 if (length > (png_uint_32)65535L) 02489 { 02490 png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 02491 png_crc_finish(png_ptr, length); 02492 return; 02493 } 02494 #endif 02495 02496 png_free(png_ptr, png_ptr->chunkdata); 02497 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 02498 02499 if (png_ptr->chunkdata == NULL) 02500 { 02501 png_warning(png_ptr, "No memory to process iTXt chunk"); 02502 return; 02503 } 02504 02505 slength = length; 02506 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 02507 02508 if (png_crc_finish(png_ptr, 0)) 02509 { 02510 png_free(png_ptr, png_ptr->chunkdata); 02511 png_ptr->chunkdata = NULL; 02512 return; 02513 } 02514 02515 png_ptr->chunkdata[slength] = 0x00; 02516 02517 for (lang = png_ptr->chunkdata; *lang; lang++) 02518 /* Empty loop */ ; 02519 02520 lang++; /* Skip NUL separator */ 02521 02522 /* iTXt must have a language tag (possibly empty), two compression bytes, 02523 * translated keyword (possibly empty), and possibly some text after the 02524 * keyword 02525 */ 02526 02527 if (lang >= png_ptr->chunkdata + slength - 3) 02528 { 02529 png_warning(png_ptr, "Truncated iTXt chunk"); 02530 png_free(png_ptr, png_ptr->chunkdata); 02531 png_ptr->chunkdata = NULL; 02532 return; 02533 } 02534 02535 else 02536 { 02537 comp_flag = *lang++; 02538 comp_type = *lang++; 02539 } 02540 02541 if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt)) 02542 { 02543 png_warning(png_ptr, "Unknown iTXt compression type or method"); 02544 png_free(png_ptr, png_ptr->chunkdata); 02545 png_ptr->chunkdata = NULL; 02546 return; 02547 } 02548 02549 for (lang_key = lang; *lang_key; lang_key++) 02550 /* Empty loop */ ; 02551 02552 lang_key++; /* Skip NUL separator */ 02553 02554 if (lang_key >= png_ptr->chunkdata + slength) 02555 { 02556 png_warning(png_ptr, "Truncated iTXt chunk"); 02557 png_free(png_ptr, png_ptr->chunkdata); 02558 png_ptr->chunkdata = NULL; 02559 return; 02560 } 02561 02562 for (text = lang_key; *text; text++) 02563 /* Empty loop */ ; 02564 02565 text++; /* Skip NUL separator */ 02566 02567 if (text >= png_ptr->chunkdata + slength) 02568 { 02569 png_warning(png_ptr, "Malformed iTXt chunk"); 02570 png_free(png_ptr, png_ptr->chunkdata); 02571 png_ptr->chunkdata = NULL; 02572 return; 02573 } 02574 02575 prefix_len = text - png_ptr->chunkdata; 02576 02577 key=png_ptr->chunkdata; 02578 02579 if (comp_flag) 02580 png_decompress_chunk(png_ptr, comp_type, 02581 (size_t)length, prefix_len, &data_len); 02582 02583 else 02584 data_len = png_strlen(png_ptr->chunkdata + prefix_len); 02585 02586 text_ptr = (png_textp)png_malloc_warn(png_ptr, 02587 png_sizeof(png_text)); 02588 02589 if (text_ptr == NULL) 02590 { 02591 png_warning(png_ptr, "Not enough memory to process iTXt chunk"); 02592 png_free(png_ptr, png_ptr->chunkdata); 02593 png_ptr->chunkdata = NULL; 02594 return; 02595 } 02596 02597 text_ptr->compression = (int)comp_flag + 1; 02598 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); 02599 text_ptr->lang = png_ptr->chunkdata + (lang - key); 02600 text_ptr->itxt_length = data_len; 02601 text_ptr->text_length = 0; 02602 text_ptr->key = png_ptr->chunkdata; 02603 text_ptr->text = png_ptr->chunkdata + prefix_len; 02604 02605 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 02606 02607 png_free(png_ptr, text_ptr); 02608 png_free(png_ptr, png_ptr->chunkdata); 02609 png_ptr->chunkdata = NULL; 02610 02611 if (ret) 02612 png_error(png_ptr, "Insufficient memory to store iTXt chunk"); 02613 } 02614 #endif 02615 02616 /* This function is called when we haven't found a handler for a 02617 * chunk. If there isn't a problem with the chunk itself (ie bad 02618 * chunk name, CRC, or a critical chunk), the chunk is silently ignored 02619 * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which 02620 * case it will be saved away to be written out later. 02621 */ 02622 void /* PRIVATE */ 02623 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 02624 { 02625 png_uint_32 skip = 0; 02626 02627 png_debug(1, "in png_handle_unknown"); 02628 02629 #ifdef PNG_USER_LIMITS_SUPPORTED 02630 if (png_ptr->user_chunk_cache_max != 0) 02631 { 02632 if (png_ptr->user_chunk_cache_max == 1) 02633 { 02634 png_crc_finish(png_ptr, length); 02635 return; 02636 } 02637 02638 if (--png_ptr->user_chunk_cache_max == 1) 02639 { 02640 png_warning(png_ptr, "No space in chunk cache for unknown chunk"); 02641 png_crc_finish(png_ptr, length); 02642 return; 02643 } 02644 } 02645 #endif 02646 02647 if (png_ptr->mode & PNG_HAVE_IDAT) 02648 { 02649 if (png_ptr->chunk_name != png_IDAT) 02650 png_ptr->mode |= PNG_AFTER_IDAT; 02651 } 02652 02653 if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) 02654 { 02655 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 02656 if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != 02657 PNG_HANDLE_CHUNK_ALWAYS 02658 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 02659 && png_ptr->read_user_chunk_fn == NULL 02660 #endif 02661 ) 02662 #endif 02663 png_chunk_error(png_ptr, "unknown critical chunk"); 02664 } 02665 02666 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 02667 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) 02668 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 02669 || (png_ptr->read_user_chunk_fn != NULL) 02670 #endif 02671 ) 02672 { 02673 #ifdef PNG_MAX_MALLOC_64K 02674 if (length > 65535) 02675 { 02676 png_warning(png_ptr, "unknown chunk too large to fit in memory"); 02677 skip = length - 65535; 02678 length = 65535; 02679 } 02680 #endif 02681 02682 /* TODO: this code is very close to the unknown handling in pngpread.c, 02683 * maybe it can be put into a common utility routine? 02684 * png_struct::unknown_chunk is just used as a temporary variable, along 02685 * with the data into which the chunk is read. These can be eliminated. 02686 */ 02687 PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); 02688 png_ptr->unknown_chunk.size = (png_size_t)length; 02689 02690 if (length == 0) 02691 png_ptr->unknown_chunk.data = NULL; 02692 02693 else 02694 { 02695 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); 02696 png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); 02697 } 02698 02699 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 02700 if (png_ptr->read_user_chunk_fn != NULL) 02701 { 02702 /* Callback to user unknown chunk handler */ 02703 int ret; 02704 02705 ret = (*(png_ptr->read_user_chunk_fn)) 02706 (png_ptr, &png_ptr->unknown_chunk); 02707 02708 if (ret < 0) 02709 png_chunk_error(png_ptr, "error in user chunk"); 02710 02711 if (ret == 0) 02712 { 02713 if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) 02714 { 02715 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 02716 if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) != 02717 PNG_HANDLE_CHUNK_ALWAYS) 02718 #endif 02719 png_chunk_error(png_ptr, "unknown critical chunk"); 02720 } 02721 02722 png_set_unknown_chunks(png_ptr, info_ptr, 02723 &png_ptr->unknown_chunk, 1); 02724 } 02725 } 02726 02727 else 02728 #endif 02729 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 02730 02731 png_free(png_ptr, png_ptr->unknown_chunk.data); 02732 png_ptr->unknown_chunk.data = NULL; 02733 } 02734 02735 else 02736 #endif 02737 skip = length; 02738 02739 png_crc_finish(png_ptr, skip); 02740 02741 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED 02742 PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ 02743 #endif 02744 } 02745 02746 /* This function is called to verify that a chunk name is valid. 02747 * This function can't have the "critical chunk check" incorporated 02748 * into it, since in the future we will need to be able to call user 02749 * functions to handle unknown critical chunks after we check that 02750 * the chunk name itself is valid. 02751 */ 02752 02753 /* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: 02754 * 02755 * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 02756 */ 02757 02758 void /* PRIVATE */ 02759 png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name) 02760 { 02761 int i; 02762 02763 png_debug(1, "in png_check_chunk_name"); 02764 02765 for (i=1; i<=4; ++i) 02766 { 02767 int c = chunk_name & 0xff; 02768 02769 if (c < 65 || c > 122 || (c > 90 && c < 97)) 02770 png_chunk_error(png_ptr, "invalid chunk type"); 02771 02772 chunk_name >>= 8; 02773 } 02774 } 02775 02776 /* Combines the row recently read in with the existing pixels in the row. This 02777 * routine takes care of alpha and transparency if requested. This routine also 02778 * handles the two methods of progressive display of interlaced images, 02779 * depending on the 'display' value; if 'display' is true then the whole row 02780 * (dp) is filled from the start by replicating the available pixels. If 02781 * 'display' is false only those pixels present in the pass are filled in. 02782 */ 02783 void /* PRIVATE */ 02784 png_combine_row(png_structp png_ptr, png_bytep dp, int display) 02785 { 02786 unsigned int pixel_depth = png_ptr->transformed_pixel_depth; 02787 png_const_bytep sp = png_ptr->row_buf + 1; 02788 png_uint_32 row_width = png_ptr->width; 02789 unsigned int pass = png_ptr->pass; 02790 png_bytep end_ptr = 0; 02791 png_byte end_byte = 0; 02792 unsigned int end_mask; 02793 02794 png_debug(1, "in png_combine_row"); 02795 02796 /* Added in 1.5.6: it should not be possible to enter this routine until at 02797 * least one row has been read from the PNG data and transformed. 02798 */ 02799 if (pixel_depth == 0) 02800 png_error(png_ptr, "internal row logic error"); 02801 02802 /* Added in 1.5.4: the pixel depth should match the information returned by 02803 * any call to png_read_update_info at this point. Do not continue if we got 02804 * this wrong. 02805 */ 02806 if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != 02807 PNG_ROWBYTES(pixel_depth, row_width)) 02808 png_error(png_ptr, "internal row size calculation error"); 02809 02810 /* Don't expect this to ever happen: */ 02811 if (row_width == 0) 02812 png_error(png_ptr, "internal row width error"); 02813 02814 /* Preserve the last byte in cases where only part of it will be overwritten, 02815 * the multiply below may overflow, we don't care because ANSI-C guarantees 02816 * we get the low bits. 02817 */ 02818 end_mask = (pixel_depth * row_width) & 7; 02819 if (end_mask != 0) 02820 { 02821 /* end_ptr == NULL is a flag to say do nothing */ 02822 end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; 02823 end_byte = *end_ptr; 02824 # ifdef PNG_READ_PACKSWAP_SUPPORTED 02825 if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */ 02826 end_mask = 0xff << end_mask; 02827 02828 else /* big-endian byte */ 02829 # endif 02830 end_mask = 0xff >> end_mask; 02831 /* end_mask is now the bits to *keep* from the destination row */ 02832 } 02833 02834 /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy() 02835 * will also happen if interlacing isn't supported or if the application 02836 * does not call png_set_interlace_handling(). In the latter cases the 02837 * caller just gets a sequence of the unexpanded rows from each interlace 02838 * pass. 02839 */ 02840 #ifdef PNG_READ_INTERLACING_SUPPORTED 02841 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) && 02842 pass < 6 && (display == 0 || 02843 /* The following copies everything for 'display' on passes 0, 2 and 4. */ 02844 (display == 1 && (pass & 1) != 0))) 02845 { 02846 /* Narrow images may have no bits in a pass; the caller should handle 02847 * this, but this test is cheap: 02848 */ 02849 if (row_width <= PNG_PASS_START_COL(pass)) 02850 return; 02851 02852 if (pixel_depth < 8) 02853 { 02854 /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit 02855 * into 32 bits, then a single loop over the bytes using the four byte 02856 * values in the 32-bit mask can be used. For the 'display' option the 02857 * expanded mask may also not require any masking within a byte. To 02858 * make this work the PACKSWAP option must be taken into account - it 02859 * simply requires the pixels to be reversed in each byte. 02860 * 02861 * The 'regular' case requires a mask for each of the first 6 passes, 02862 * the 'display' case does a copy for the even passes in the range 02863 * 0..6. This has already been handled in the test above. 02864 * 02865 * The masks are arranged as four bytes with the first byte to use in 02866 * the lowest bits (little-endian) regardless of the order (PACKSWAP or 02867 * not) of the pixels in each byte. 02868 * 02869 * NOTE: the whole of this logic depends on the caller of this function 02870 * only calling it on rows appropriate to the pass. This function only 02871 * understands the 'x' logic; the 'y' logic is handled by the caller. 02872 * 02873 * The following defines allow generation of compile time constant bit 02874 * masks for each pixel depth and each possibility of swapped or not 02875 * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, 02876 * is in the range 0..7; and the result is 1 if the pixel is to be 02877 * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' 02878 * for the block method. 02879 * 02880 * With some compilers a compile time expression of the general form: 02881 * 02882 * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) 02883 * 02884 * Produces warnings with values of 'shift' in the range 33 to 63 02885 * because the right hand side of the ?: expression is evaluated by 02886 * the compiler even though it isn't used. Microsoft Visual C (various 02887 * versions) and the Intel C compiler are known to do this. To avoid 02888 * this the following macros are used in 1.5.6. This is a temporary 02889 * solution to avoid destabilizing the code during the release process. 02890 */ 02891 # if PNG_USE_COMPILE_TIME_MASKS 02892 # define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) 02893 # define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) 02894 # else 02895 # define PNG_LSR(x,s) ((x)>>(s)) 02896 # define PNG_LSL(x,s) ((x)<<(s)) 02897 # endif 02898 # define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ 02899 PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) 02900 # define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ 02901 PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) 02902 02903 /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is 02904 * little endian - the first pixel is at bit 0 - however the extra 02905 * parameter 's' can be set to cause the mask position to be swapped 02906 * within each byte, to match the PNG format. This is done by XOR of 02907 * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. 02908 */ 02909 # define PIXEL_MASK(p,x,d,s) \ 02910 (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) 02911 02912 /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. 02913 */ 02914 # define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) 02915 # define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) 02916 02917 /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp 02918 * cases the result needs replicating, for the 4-bpp case the above 02919 * generates a full 32 bits. 02920 */ 02921 # define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) 02922 02923 # define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ 02924 S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ 02925 S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) 02926 02927 # define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ 02928 B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ 02929 B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) 02930 02931 #if PNG_USE_COMPILE_TIME_MASKS 02932 /* Utility macros to construct all the masks for a depth/swap 02933 * combination. The 's' parameter says whether the format is PNG 02934 * (big endian bytes) or not. Only the three odd-numbered passes are 02935 * required for the display/block algorithm. 02936 */ 02937 # define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ 02938 S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } 02939 02940 # define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) } 02941 02942 # define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) 02943 02944 /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and 02945 * then pass: 02946 */ 02947 static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = 02948 { 02949 /* Little-endian byte masks for PACKSWAP */ 02950 { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, 02951 /* Normal (big-endian byte) masks - PNG format */ 02952 { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } 02953 }; 02954 02955 /* display_mask has only three entries for the odd passes, so index by 02956 * pass>>1. 02957 */ 02958 static PNG_CONST png_uint_32 display_mask[2][3][3] = 02959 { 02960 /* Little-endian byte masks for PACKSWAP */ 02961 { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, 02962 /* Normal (big-endian byte) masks - PNG format */ 02963 { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } 02964 }; 02965 02966 # define MASK(pass,depth,display,png)\ 02967 ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ 02968 row_mask[png][DEPTH_INDEX(depth)][pass]) 02969 02970 #else /* !PNG_USE_COMPILE_TIME_MASKS */ 02971 /* This is the runtime alternative: it seems unlikely that this will 02972 * ever be either smaller or faster than the compile time approach. 02973 */ 02974 # define MASK(pass,depth,display,png)\ 02975 ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) 02976 #endif /* !PNG_USE_COMPILE_TIME_MASKS */ 02977 02978 /* Use the appropriate mask to copy the required bits. In some cases 02979 * the byte mask will be 0 or 0xff, optimize these cases. row_width is 02980 * the number of pixels, but the code copies bytes, so it is necessary 02981 * to special case the end. 02982 */ 02983 png_uint_32 pixels_per_byte = 8 / pixel_depth; 02984 png_uint_32 mask; 02985 02986 # ifdef PNG_READ_PACKSWAP_SUPPORTED 02987 if (png_ptr->transformations & PNG_PACKSWAP) 02988 mask = MASK(pass, pixel_depth, display, 0); 02989 02990 else 02991 # endif 02992 mask = MASK(pass, pixel_depth, display, 1); 02993 02994 for (;;) 02995 { 02996 png_uint_32 m; 02997 02998 /* It doesn't matter in the following if png_uint_32 has more than 02999 * 32 bits because the high bits always match those in m<<24; it is, 03000 * however, essential to use OR here, not +, because of this. 03001 */ 03002 m = mask; 03003 mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ 03004 m &= 0xff; 03005 03006 if (m != 0) /* something to copy */ 03007 { 03008 if (m != 0xff) 03009 *dp = (png_byte)((*dp & ~m) | (*sp & m)); 03010 else 03011 *dp = *sp; 03012 } 03013 03014 /* NOTE: this may overwrite the last byte with garbage if the image 03015 * is not an exact number of bytes wide; libpng has always done 03016 * this. 03017 */ 03018 if (row_width <= pixels_per_byte) 03019 break; /* May need to restore part of the last byte */ 03020 03021 row_width -= pixels_per_byte; 03022 ++dp; 03023 ++sp; 03024 } 03025 } 03026 03027 else /* pixel_depth >= 8 */ 03028 { 03029 unsigned int bytes_to_copy, bytes_to_jump; 03030 03031 /* Validate the depth - it must be a multiple of 8 */ 03032 if (pixel_depth & 7) 03033 png_error(png_ptr, "invalid user transform pixel depth"); 03034 03035 pixel_depth >>= 3; /* now in bytes */ 03036 row_width *= pixel_depth; 03037 03038 /* Regardless of pass number the Adam 7 interlace always results in a 03039 * fixed number of pixels to copy then to skip. There may be a 03040 * different number of pixels to skip at the start though. 03041 */ 03042 { 03043 unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; 03044 03045 row_width -= offset; 03046 dp += offset; 03047 sp += offset; 03048 } 03049 03050 /* Work out the bytes to copy. */ 03051 if (display) 03052 { 03053 /* When doing the 'block' algorithm the pixel in the pass gets 03054 * replicated to adjacent pixels. This is why the even (0,2,4,6) 03055 * passes are skipped above - the entire expanded row is copied. 03056 */ 03057 bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; 03058 03059 /* But don't allow this number to exceed the actual row width. */ 03060 if (bytes_to_copy > row_width) 03061 bytes_to_copy = row_width; 03062 } 03063 03064 else /* normal row; Adam7 only ever gives us one pixel to copy. */ 03065 bytes_to_copy = pixel_depth; 03066 03067 /* In Adam7 there is a constant offset between where the pixels go. */ 03068 bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; 03069 03070 /* And simply copy these bytes. Some optimization is possible here, 03071 * depending on the value of 'bytes_to_copy'. Special case the low 03072 * byte counts, which we know to be frequent. 03073 * 03074 * Notice that these cases all 'return' rather than 'break' - this 03075 * avoids an unnecessary test on whether to restore the last byte 03076 * below. 03077 */ 03078 switch (bytes_to_copy) 03079 { 03080 case 1: 03081 for (;;) 03082 { 03083 *dp = *sp; 03084 03085 if (row_width <= bytes_to_jump) 03086 return; 03087 03088 dp += bytes_to_jump; 03089 sp += bytes_to_jump; 03090 row_width -= bytes_to_jump; 03091 } 03092 03093 case 2: 03094 /* There is a possibility of a partial copy at the end here; this 03095 * slows the code down somewhat. 03096 */ 03097 do 03098 { 03099 dp[0] = sp[0], dp[1] = sp[1]; 03100 03101 if (row_width <= bytes_to_jump) 03102 return; 03103 03104 sp += bytes_to_jump; 03105 dp += bytes_to_jump; 03106 row_width -= bytes_to_jump; 03107 } 03108 while (row_width > 1); 03109 03110 /* And there can only be one byte left at this point: */ 03111 *dp = *sp; 03112 return; 03113 03114 case 3: 03115 /* This can only be the RGB case, so each copy is exactly one 03116 * pixel and it is not necessary to check for a partial copy. 03117 */ 03118 for(;;) 03119 { 03120 dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2]; 03121 03122 if (row_width <= bytes_to_jump) 03123 return; 03124 03125 sp += bytes_to_jump; 03126 dp += bytes_to_jump; 03127 row_width -= bytes_to_jump; 03128 } 03129 03130 default: 03131 #if PNG_ALIGN_TYPE != PNG_ALIGN_NONE 03132 /* Check for double byte alignment and, if possible, use a 03133 * 16-bit copy. Don't attempt this for narrow images - ones that 03134 * are less than an interlace panel wide. Don't attempt it for 03135 * wide bytes_to_copy either - use the png_memcpy there. 03136 */ 03137 if (bytes_to_copy < 16 /*else use png_memcpy*/ && 03138 png_isaligned(dp, png_uint_16) && 03139 png_isaligned(sp, png_uint_16) && 03140 bytes_to_copy % sizeof (png_uint_16) == 0 && 03141 bytes_to_jump % sizeof (png_uint_16) == 0) 03142 { 03143 /* Everything is aligned for png_uint_16 copies, but try for 03144 * png_uint_32 first. 03145 */ 03146 if (png_isaligned(dp, png_uint_32) && 03147 png_isaligned(sp, png_uint_32) && 03148 bytes_to_copy % sizeof (png_uint_32) == 0 && 03149 bytes_to_jump % sizeof (png_uint_32) == 0) 03150 { 03151 png_uint_32p dp32 = (png_uint_32p)dp; 03152 png_const_uint_32p sp32 = (png_const_uint_32p)sp; 03153 unsigned int skip = (bytes_to_jump-bytes_to_copy) / 03154 sizeof (png_uint_32); 03155 03156 do 03157 { 03158 size_t c = bytes_to_copy; 03159 do 03160 { 03161 *dp32++ = *sp32++; 03162 c -= sizeof (png_uint_32); 03163 } 03164 while (c > 0); 03165 03166 if (row_width <= bytes_to_jump) 03167 return; 03168 03169 dp32 += skip; 03170 sp32 += skip; 03171 row_width -= bytes_to_jump; 03172 } 03173 while (bytes_to_copy <= row_width); 03174 03175 /* Get to here when the row_width truncates the final copy. 03176 * There will be 1-3 bytes left to copy, so don't try the 03177 * 16-bit loop below. 03178 */ 03179 dp = (png_bytep)dp32; 03180 sp = (png_const_bytep)sp32; 03181 do 03182 *dp++ = *sp++; 03183 while (--row_width > 0); 03184 return; 03185 } 03186 03187 /* Else do it in 16-bit quantities, but only if the size is 03188 * not too large. 03189 */ 03190 else 03191 { 03192 png_uint_16p dp16 = (png_uint_16p)dp; 03193 png_const_uint_16p sp16 = (png_const_uint_16p)sp; 03194 unsigned int skip = (bytes_to_jump-bytes_to_copy) / 03195 sizeof (png_uint_16); 03196 03197 do 03198 { 03199 size_t c = bytes_to_copy; 03200 do 03201 { 03202 *dp16++ = *sp16++; 03203 c -= sizeof (png_uint_16); 03204 } 03205 while (c > 0); 03206 03207 if (row_width <= bytes_to_jump) 03208 return; 03209 03210 dp16 += skip; 03211 sp16 += skip; 03212 row_width -= bytes_to_jump; 03213 } 03214 while (bytes_to_copy <= row_width); 03215 03216 /* End of row - 1 byte left, bytes_to_copy > row_width: */ 03217 dp = (png_bytep)dp16; 03218 sp = (png_const_bytep)sp16; 03219 do 03220 *dp++ = *sp++; 03221 while (--row_width > 0); 03222 return; 03223 } 03224 } 03225 #endif /* PNG_ALIGN_ code */ 03226 03227 /* The true default - use a png_memcpy: */ 03228 for (;;) 03229 { 03230 png_memcpy(dp, sp, bytes_to_copy); 03231 03232 if (row_width <= bytes_to_jump) 03233 return; 03234 03235 sp += bytes_to_jump; 03236 dp += bytes_to_jump; 03237 row_width -= bytes_to_jump; 03238 if (bytes_to_copy > row_width) 03239 bytes_to_copy = row_width; 03240 } 03241 } 03242 03243 /* NOT REACHED*/ 03244 } /* pixel_depth >= 8 */ 03245 03246 /* Here if pixel_depth < 8 to check 'end_ptr' below. */ 03247 } 03248 else 03249 #endif 03250 03251 /* If here then the switch above wasn't used so just png_memcpy the whole row 03252 * from the temporary row buffer (notice that this overwrites the end of the 03253 * destination row if it is a partial byte.) 03254 */ 03255 png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); 03256 03257 /* Restore the overwritten bits from the last byte if necessary. */ 03258 if (end_ptr != NULL) 03259 *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); 03260 } 03261 03262 #ifdef PNG_READ_INTERLACING_SUPPORTED 03263 void /* PRIVATE */ 03264 png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 03265 png_uint_32 transformations /* Because these may affect the byte layout */) 03266 { 03267 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 03268 /* Offset to next interlace block */ 03269 static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 03270 03271 png_debug(1, "in png_do_read_interlace"); 03272 if (row != NULL && row_info != NULL) 03273 { 03274 png_uint_32 final_width; 03275 03276 final_width = row_info->width * png_pass_inc[pass]; 03277 03278 switch (row_info->pixel_depth) 03279 { 03280 case 1: 03281 { 03282 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 03283 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 03284 int sshift, dshift; 03285 int s_start, s_end, s_inc; 03286 int jstop = png_pass_inc[pass]; 03287 png_byte v; 03288 png_uint_32 i; 03289 int j; 03290 03291 #ifdef PNG_READ_PACKSWAP_SUPPORTED 03292 if (transformations & PNG_PACKSWAP) 03293 { 03294 sshift = (int)((row_info->width + 7) & 0x07); 03295 dshift = (int)((final_width + 7) & 0x07); 03296 s_start = 7; 03297 s_end = 0; 03298 s_inc = -1; 03299 } 03300 03301 else 03302 #endif 03303 { 03304 sshift = 7 - (int)((row_info->width + 7) & 0x07); 03305 dshift = 7 - (int)((final_width + 7) & 0x07); 03306 s_start = 0; 03307 s_end = 7; 03308 s_inc = 1; 03309 } 03310 03311 for (i = 0; i < row_info->width; i++) 03312 { 03313 v = (png_byte)((*sp >> sshift) & 0x01); 03314 for (j = 0; j < jstop; j++) 03315 { 03316 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 03317 *dp |= (png_byte)(v << dshift); 03318 03319 if (dshift == s_end) 03320 { 03321 dshift = s_start; 03322 dp--; 03323 } 03324 03325 else 03326 dshift += s_inc; 03327 } 03328 03329 if (sshift == s_end) 03330 { 03331 sshift = s_start; 03332 sp--; 03333 } 03334 03335 else 03336 sshift += s_inc; 03337 } 03338 break; 03339 } 03340 03341 case 2: 03342 { 03343 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 03344 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 03345 int sshift, dshift; 03346 int s_start, s_end, s_inc; 03347 int jstop = png_pass_inc[pass]; 03348 png_uint_32 i; 03349 03350 #ifdef PNG_READ_PACKSWAP_SUPPORTED 03351 if (transformations & PNG_PACKSWAP) 03352 { 03353 sshift = (int)(((row_info->width + 3) & 0x03) << 1); 03354 dshift = (int)(((final_width + 3) & 0x03) << 1); 03355 s_start = 6; 03356 s_end = 0; 03357 s_inc = -2; 03358 } 03359 03360 else 03361 #endif 03362 { 03363 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 03364 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 03365 s_start = 0; 03366 s_end = 6; 03367 s_inc = 2; 03368 } 03369 03370 for (i = 0; i < row_info->width; i++) 03371 { 03372 png_byte v; 03373 int j; 03374 03375 v = (png_byte)((*sp >> sshift) & 0x03); 03376 for (j = 0; j < jstop; j++) 03377 { 03378 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 03379 *dp |= (png_byte)(v << dshift); 03380 03381 if (dshift == s_end) 03382 { 03383 dshift = s_start; 03384 dp--; 03385 } 03386 03387 else 03388 dshift += s_inc; 03389 } 03390 03391 if (sshift == s_end) 03392 { 03393 sshift = s_start; 03394 sp--; 03395 } 03396 03397 else 03398 sshift += s_inc; 03399 } 03400 break; 03401 } 03402 03403 case 4: 03404 { 03405 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 03406 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 03407 int sshift, dshift; 03408 int s_start, s_end, s_inc; 03409 png_uint_32 i; 03410 int jstop = png_pass_inc[pass]; 03411 03412 #ifdef PNG_READ_PACKSWAP_SUPPORTED 03413 if (transformations & PNG_PACKSWAP) 03414 { 03415 sshift = (int)(((row_info->width + 1) & 0x01) << 2); 03416 dshift = (int)(((final_width + 1) & 0x01) << 2); 03417 s_start = 4; 03418 s_end = 0; 03419 s_inc = -4; 03420 } 03421 03422 else 03423 #endif 03424 { 03425 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 03426 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 03427 s_start = 0; 03428 s_end = 4; 03429 s_inc = 4; 03430 } 03431 03432 for (i = 0; i < row_info->width; i++) 03433 { 03434 png_byte v = (png_byte)((*sp >> sshift) & 0x0f); 03435 int j; 03436 03437 for (j = 0; j < jstop; j++) 03438 { 03439 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 03440 *dp |= (png_byte)(v << dshift); 03441 03442 if (dshift == s_end) 03443 { 03444 dshift = s_start; 03445 dp--; 03446 } 03447 03448 else 03449 dshift += s_inc; 03450 } 03451 03452 if (sshift == s_end) 03453 { 03454 sshift = s_start; 03455 sp--; 03456 } 03457 03458 else 03459 sshift += s_inc; 03460 } 03461 break; 03462 } 03463 03464 default: 03465 { 03466 png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 03467 03468 png_bytep sp = row + (png_size_t)(row_info->width - 1) 03469 * pixel_bytes; 03470 03471 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 03472 03473 int jstop = png_pass_inc[pass]; 03474 png_uint_32 i; 03475 03476 for (i = 0; i < row_info->width; i++) 03477 { 03478 png_byte v[8]; 03479 int j; 03480 03481 png_memcpy(v, sp, pixel_bytes); 03482 03483 for (j = 0; j < jstop; j++) 03484 { 03485 png_memcpy(dp, v, pixel_bytes); 03486 dp -= pixel_bytes; 03487 } 03488 03489 sp -= pixel_bytes; 03490 } 03491 break; 03492 } 03493 } 03494 03495 row_info->width = final_width; 03496 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); 03497 } 03498 #ifndef PNG_READ_PACKSWAP_SUPPORTED 03499 PNG_UNUSED(transformations) /* Silence compiler warning */ 03500 #endif 03501 } 03502 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 03503 03504 static void 03505 png_read_filter_row_sub(png_row_infop row_info, png_bytep row, 03506 png_const_bytep prev_row) 03507 { 03508 png_size_t i; 03509 png_size_t istop = row_info->rowbytes; 03510 unsigned int bpp = (row_info->pixel_depth + 7) >> 3; 03511 png_bytep rp = row + bpp; 03512 03513 PNG_UNUSED(prev_row) 03514 03515 for (i = bpp; i < istop; i++) 03516 { 03517 *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); 03518 rp++; 03519 } 03520 } 03521 03522 static void 03523 png_read_filter_row_up(png_row_infop row_info, png_bytep row, 03524 png_const_bytep prev_row) 03525 { 03526 png_size_t i; 03527 png_size_t istop = row_info->rowbytes; 03528 png_bytep rp = row; 03529 png_const_bytep pp = prev_row; 03530 03531 for (i = 0; i < istop; i++) 03532 { 03533 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 03534 rp++; 03535 } 03536 } 03537 03538 static void 03539 png_read_filter_row_avg(png_row_infop row_info, png_bytep row, 03540 png_const_bytep prev_row) 03541 { 03542 png_size_t i; 03543 png_bytep rp = row; 03544 png_const_bytep pp = prev_row; 03545 unsigned int bpp = (row_info->pixel_depth + 7) >> 3; 03546 png_size_t istop = row_info->rowbytes - bpp; 03547 03548 for (i = 0; i < bpp; i++) 03549 { 03550 *rp = (png_byte)(((int)(*rp) + 03551 ((int)(*pp++) / 2 )) & 0xff); 03552 03553 rp++; 03554 } 03555 03556 for (i = 0; i < istop; i++) 03557 { 03558 *rp = (png_byte)(((int)(*rp) + 03559 (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); 03560 03561 rp++; 03562 } 03563 } 03564 03565 static void 03566 png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, 03567 png_const_bytep prev_row) 03568 { 03569 png_bytep rp_end = row + row_info->rowbytes; 03570 int a, c; 03571 03572 /* First pixel/byte */ 03573 c = *prev_row++; 03574 a = *row + c; 03575 *row++ = (png_byte)a; 03576 03577 /* Remainder */ 03578 while (row < rp_end) 03579 { 03580 int b, pa, pb, pc, p; 03581 03582 a &= 0xff; /* From previous iteration or start */ 03583 b = *prev_row++; 03584 03585 p = b - c; 03586 pc = a - c; 03587 03588 # ifdef PNG_USE_ABS 03589 pa = abs(p); 03590 pb = abs(pc); 03591 pc = abs(p + pc); 03592 # else 03593 pa = p < 0 ? -p : p; 03594 pb = pc < 0 ? -pc : pc; 03595 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 03596 # endif 03597 03598 /* Find the best predictor, the least of pa, pb, pc favoring the earlier 03599 * ones in the case of a tie. 03600 */ 03601 if (pb < pa) pa = pb, a = b; 03602 if (pc < pa) a = c; 03603 03604 /* Calculate the current pixel in a, and move the previous row pixel to c 03605 * for the next time round the loop 03606 */ 03607 c = b; 03608 a += *row; 03609 *row++ = (png_byte)a; 03610 } 03611 } 03612 03613 static void 03614 png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, 03615 png_const_bytep prev_row) 03616 { 03617 int bpp = (row_info->pixel_depth + 7) >> 3; 03618 png_bytep rp_end = row + bpp; 03619 03620 /* Process the first pixel in the row completely (this is the same as 'up' 03621 * because there is only one candidate predictor for the first row). 03622 */ 03623 while (row < rp_end) 03624 { 03625 int a = *row + *prev_row++; 03626 *row++ = (png_byte)a; 03627 } 03628 03629 /* Remainder */ 03630 rp_end += row_info->rowbytes - bpp; 03631 03632 while (row < rp_end) 03633 { 03634 int a, b, c, pa, pb, pc, p; 03635 03636 c = *(prev_row - bpp); 03637 a = *(row - bpp); 03638 b = *prev_row++; 03639 03640 p = b - c; 03641 pc = a - c; 03642 03643 # ifdef PNG_USE_ABS 03644 pa = abs(p); 03645 pb = abs(pc); 03646 pc = abs(p + pc); 03647 # else 03648 pa = p < 0 ? -p : p; 03649 pb = pc < 0 ? -pc : pc; 03650 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 03651 # endif 03652 03653 if (pb < pa) pa = pb, a = b; 03654 if (pc < pa) a = c; 03655 03656 c = b; 03657 a += *row; 03658 *row++ = (png_byte)a; 03659 } 03660 } 03661 03662 #ifdef PNG_ARM_NEON 03663 03664 #ifdef __linux__ 03665 #include <stdio.h> 03666 #include <elf.h> 03667 #include <asm/hwcap.h> 03668 03669 static int png_have_hwcap(unsigned cap) 03670 { 03671 FILE *f = fopen("/proc/self/auxv", "r"); 03672 Elf32_auxv_t aux; 03673 int have_cap = 0; 03674 03675 if (!f) 03676 return 0; 03677 03678 while (fread(&aux, sizeof(aux), 1, f) > 0) 03679 { 03680 if (aux.a_type == AT_HWCAP && 03681 aux.a_un.a_val & cap) 03682 { 03683 have_cap = 1; 03684 break; 03685 } 03686 } 03687 03688 fclose(f); 03689 03690 return have_cap; 03691 } 03692 #endif /* __linux__ */ 03693 03694 static void 03695 png_init_filter_functions_neon(png_structp pp, unsigned int bpp) 03696 { 03697 #ifdef __linux__ 03698 if (!png_have_hwcap(HWCAP_NEON)) 03699 return; 03700 #endif 03701 03702 pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; 03703 03704 if (bpp == 3) 03705 { 03706 pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; 03707 pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; 03708 pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 03709 png_read_filter_row_paeth3_neon; 03710 } 03711 03712 else if (bpp == 4) 03713 { 03714 pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; 03715 pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; 03716 pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 03717 png_read_filter_row_paeth4_neon; 03718 } 03719 } 03720 #endif /* PNG_ARM_NEON */ 03721 03722 static void 03723 png_init_filter_functions(png_structp pp) 03724 { 03725 unsigned int bpp = (pp->pixel_depth + 7) >> 3; 03726 03727 pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; 03728 pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; 03729 pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; 03730 if (bpp == 1) 03731 pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 03732 png_read_filter_row_paeth_1byte_pixel; 03733 else 03734 pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 03735 png_read_filter_row_paeth_multibyte_pixel; 03736 03737 #ifdef PNG_ARM_NEON 03738 png_init_filter_functions_neon(pp, bpp); 03739 #endif 03740 } 03741 03742 void /* PRIVATE */ 03743 png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row, 03744 png_const_bytep prev_row, int filter) 03745 { 03746 if (pp->read_filter[0] == NULL) 03747 png_init_filter_functions(pp); 03748 if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) 03749 pp->read_filter[filter-1](row_info, row, prev_row); 03750 } 03751 03752 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 03753 void /* PRIVATE */ 03754 png_read_finish_row(png_structp png_ptr) 03755 { 03756 #ifdef PNG_READ_INTERLACING_SUPPORTED 03757 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 03758 03759 /* Start of interlace block */ 03760 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 03761 03762 /* Offset to next interlace block */ 03763 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 03764 03765 /* Start of interlace block in the y direction */ 03766 static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 03767 03768 /* Offset to next interlace block in the y direction */ 03769 static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 03770 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 03771 03772 png_debug(1, "in png_read_finish_row"); 03773 png_ptr->row_number++; 03774 if (png_ptr->row_number < png_ptr->num_rows) 03775 return; 03776 03777 #ifdef PNG_READ_INTERLACING_SUPPORTED 03778 if (png_ptr->interlaced) 03779 { 03780 png_ptr->row_number = 0; 03781 03782 /* TO DO: don't do this if prev_row isn't needed (requires 03783 * read-ahead of the next row's filter byte. 03784 */ 03785 png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 03786 03787 do 03788 { 03789 png_ptr->pass++; 03790 03791 if (png_ptr->pass >= 7) 03792 break; 03793 03794 png_ptr->iwidth = (png_ptr->width + 03795 png_pass_inc[png_ptr->pass] - 1 - 03796 png_pass_start[png_ptr->pass]) / 03797 png_pass_inc[png_ptr->pass]; 03798 03799 if (!(png_ptr->transformations & PNG_INTERLACE)) 03800 { 03801 png_ptr->num_rows = (png_ptr->height + 03802 png_pass_yinc[png_ptr->pass] - 1 - 03803 png_pass_ystart[png_ptr->pass]) / 03804 png_pass_yinc[png_ptr->pass]; 03805 } 03806 03807 else /* if (png_ptr->transformations & PNG_INTERLACE) */ 03808 break; /* libpng deinterlacing sees every row */ 03809 03810 } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); 03811 03812 if (png_ptr->pass < 7) 03813 return; 03814 } 03815 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 03816 03817 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 03818 { 03819 char extra; 03820 int ret; 03821 03822 png_ptr->zstream.next_out = (Byte *)&extra; 03823 png_ptr->zstream.avail_out = (uInt)1; 03824 03825 for (;;) 03826 { 03827 if (!(png_ptr->zstream.avail_in)) 03828 { 03829 while (!png_ptr->idat_size) 03830 { 03831 png_crc_finish(png_ptr, 0); 03832 png_ptr->idat_size = png_read_chunk_header(png_ptr); 03833 if (png_ptr->chunk_name != png_IDAT) 03834 png_error(png_ptr, "Not enough image data"); 03835 } 03836 03837 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 03838 png_ptr->zstream.next_in = png_ptr->zbuf; 03839 03840 if (png_ptr->zbuf_size > png_ptr->idat_size) 03841 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 03842 03843 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); 03844 png_ptr->idat_size -= png_ptr->zstream.avail_in; 03845 } 03846 03847 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 03848 03849 if (ret == Z_STREAM_END) 03850 { 03851 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || 03852 png_ptr->idat_size) 03853 png_warning(png_ptr, "Extra compressed data"); 03854 03855 png_ptr->mode |= PNG_AFTER_IDAT; 03856 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 03857 break; 03858 } 03859 03860 if (ret != Z_OK) 03861 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 03862 "Decompression Error"); 03863 03864 if (!(png_ptr->zstream.avail_out)) 03865 { 03866 png_warning(png_ptr, "Extra compressed data"); 03867 png_ptr->mode |= PNG_AFTER_IDAT; 03868 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 03869 break; 03870 } 03871 03872 } 03873 png_ptr->zstream.avail_out = 0; 03874 } 03875 03876 if (png_ptr->idat_size || png_ptr->zstream.avail_in) 03877 png_warning(png_ptr, "Extra compression data"); 03878 03879 inflateReset(&png_ptr->zstream); 03880 03881 png_ptr->mode |= PNG_AFTER_IDAT; 03882 } 03883 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 03884 03885 void /* PRIVATE */ 03886 png_read_start_row(png_structp png_ptr) 03887 { 03888 #ifdef PNG_READ_INTERLACING_SUPPORTED 03889 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 03890 03891 /* Start of interlace block */ 03892 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 03893 03894 /* Offset to next interlace block */ 03895 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 03896 03897 /* Start of interlace block in the y direction */ 03898 static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 03899 03900 /* Offset to next interlace block in the y direction */ 03901 static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 03902 #endif 03903 03904 int max_pixel_depth; 03905 png_size_t row_bytes; 03906 03907 png_debug(1, "in png_read_start_row"); 03908 png_ptr->zstream.avail_in = 0; 03909 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 03910 png_init_read_transformations(png_ptr); 03911 #endif 03912 #ifdef PNG_READ_INTERLACING_SUPPORTED 03913 if (png_ptr->interlaced) 03914 { 03915 if (!(png_ptr->transformations & PNG_INTERLACE)) 03916 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 03917 png_pass_ystart[0]) / png_pass_yinc[0]; 03918 03919 else 03920 png_ptr->num_rows = png_ptr->height; 03921 03922 png_ptr->iwidth = (png_ptr->width + 03923 png_pass_inc[png_ptr->pass] - 1 - 03924 png_pass_start[png_ptr->pass]) / 03925 png_pass_inc[png_ptr->pass]; 03926 } 03927 03928 else 03929 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 03930 { 03931 png_ptr->num_rows = png_ptr->height; 03932 png_ptr->iwidth = png_ptr->width; 03933 } 03934 03935 max_pixel_depth = png_ptr->pixel_depth; 03936 03937 /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of 03938 * calculations to calculate the final pixel depth, then 03939 * png_do_read_transforms actually does the transforms. This means that the 03940 * code which effectively calculates this value is actually repeated in three 03941 * separate places. They must all match. Innocent changes to the order of 03942 * transformations can and will break libpng in a way that causes memory 03943 * overwrites. 03944 * 03945 * TODO: fix this. 03946 */ 03947 #ifdef PNG_READ_PACK_SUPPORTED 03948 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 03949 max_pixel_depth = 8; 03950 #endif 03951 03952 #ifdef PNG_READ_EXPAND_SUPPORTED 03953 if (png_ptr->transformations & PNG_EXPAND) 03954 { 03955 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 03956 { 03957 if (png_ptr->num_trans) 03958 max_pixel_depth = 32; 03959 03960 else 03961 max_pixel_depth = 24; 03962 } 03963 03964 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 03965 { 03966 if (max_pixel_depth < 8) 03967 max_pixel_depth = 8; 03968 03969 if (png_ptr->num_trans) 03970 max_pixel_depth *= 2; 03971 } 03972 03973 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 03974 { 03975 if (png_ptr->num_trans) 03976 { 03977 max_pixel_depth *= 4; 03978 max_pixel_depth /= 3; 03979 } 03980 } 03981 } 03982 #endif 03983 03984 #ifdef PNG_READ_EXPAND_16_SUPPORTED 03985 if (png_ptr->transformations & PNG_EXPAND_16) 03986 { 03987 # ifdef PNG_READ_EXPAND_SUPPORTED 03988 /* In fact it is an error if it isn't supported, but checking is 03989 * the safe way. 03990 */ 03991 if (png_ptr->transformations & PNG_EXPAND) 03992 { 03993 if (png_ptr->bit_depth < 16) 03994 max_pixel_depth *= 2; 03995 } 03996 else 03997 # endif 03998 png_ptr->transformations &= ~PNG_EXPAND_16; 03999 } 04000 #endif 04001 04002 #ifdef PNG_READ_FILLER_SUPPORTED 04003 if (png_ptr->transformations & (PNG_FILLER)) 04004 { 04005 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 04006 { 04007 if (max_pixel_depth <= 8) 04008 max_pixel_depth = 16; 04009 04010 else 04011 max_pixel_depth = 32; 04012 } 04013 04014 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || 04015 png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 04016 { 04017 if (max_pixel_depth <= 32) 04018 max_pixel_depth = 32; 04019 04020 else 04021 max_pixel_depth = 64; 04022 } 04023 } 04024 #endif 04025 04026 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 04027 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 04028 { 04029 if ( 04030 #ifdef PNG_READ_EXPAND_SUPPORTED 04031 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 04032 #endif 04033 #ifdef PNG_READ_FILLER_SUPPORTED 04034 (png_ptr->transformations & (PNG_FILLER)) || 04035 #endif 04036 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 04037 { 04038 if (max_pixel_depth <= 16) 04039 max_pixel_depth = 32; 04040 04041 else 04042 max_pixel_depth = 64; 04043 } 04044 04045 else 04046 { 04047 if (max_pixel_depth <= 8) 04048 { 04049 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 04050 max_pixel_depth = 32; 04051 04052 else 04053 max_pixel_depth = 24; 04054 } 04055 04056 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 04057 max_pixel_depth = 64; 04058 04059 else 04060 max_pixel_depth = 48; 04061 } 04062 } 04063 #endif 04064 04065 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 04066 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 04067 if (png_ptr->transformations & PNG_USER_TRANSFORM) 04068 { 04069 int user_pixel_depth = png_ptr->user_transform_depth * 04070 png_ptr->user_transform_channels; 04071 04072 if (user_pixel_depth > max_pixel_depth) 04073 max_pixel_depth = user_pixel_depth; 04074 } 04075 #endif 04076 04077 /* This value is stored in png_struct and double checked in the row read 04078 * code. 04079 */ 04080 png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; 04081 png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ 04082 04083 /* Align the width on the next larger 8 pixels. Mainly used 04084 * for interlacing 04085 */ 04086 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 04087 /* Calculate the maximum bytes needed, adding a byte and a pixel 04088 * for safety's sake 04089 */ 04090 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 04091 1 + ((max_pixel_depth + 7) >> 3); 04092 04093 #ifdef PNG_MAX_MALLOC_64K 04094 if (row_bytes > (png_uint_32)65536L) 04095 png_error(png_ptr, "This image requires a row greater than 64KB"); 04096 #endif 04097 04098 if (row_bytes + 48 > png_ptr->old_big_row_buf_size) 04099 { 04100 png_free(png_ptr, png_ptr->big_row_buf); 04101 png_free(png_ptr, png_ptr->big_prev_row); 04102 04103 if (png_ptr->interlaced) 04104 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, 04105 row_bytes + 48); 04106 04107 else 04108 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); 04109 04110 png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); 04111 04112 #ifdef PNG_ALIGNED_MEMORY_SUPPORTED 04113 /* Use 16-byte aligned memory for row_buf with at least 16 bytes 04114 * of padding before and after row_buf; treat prev_row similarly. 04115 * NOTE: the alignment is to the start of the pixels, one beyond the start 04116 * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this 04117 * was incorrect; the filter byte was aligned, which had the exact 04118 * opposite effect of that intended. 04119 */ 04120 { 04121 png_bytep temp = png_ptr->big_row_buf + 32; 04122 int extra = (int)((temp - (png_bytep)0) & 0x0f); 04123 png_ptr->row_buf = temp - extra - 1/*filter byte*/; 04124 04125 temp = png_ptr->big_prev_row + 32; 04126 extra = (int)((temp - (png_bytep)0) & 0x0f); 04127 png_ptr->prev_row = temp - extra - 1/*filter byte*/; 04128 } 04129 04130 #else 04131 /* Use 31 bytes of padding before and 17 bytes after row_buf. */ 04132 png_ptr->row_buf = png_ptr->big_row_buf + 31; 04133 png_ptr->prev_row = png_ptr->big_prev_row + 31; 04134 #endif 04135 png_ptr->old_big_row_buf_size = row_bytes + 48; 04136 } 04137 04138 #ifdef PNG_MAX_MALLOC_64K 04139 if (png_ptr->rowbytes > 65535) 04140 png_error(png_ptr, "This image requires a row greater than 64KB"); 04141 04142 #endif 04143 if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) 04144 png_error(png_ptr, "Row has too many bytes to allocate in memory"); 04145 04146 png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 04147 04148 png_debug1(3, "width = %u,", png_ptr->width); 04149 png_debug1(3, "height = %u,", png_ptr->height); 04150 png_debug1(3, "iwidth = %u,", png_ptr->iwidth); 04151 png_debug1(3, "num_rows = %u,", png_ptr->num_rows); 04152 png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); 04153 png_debug1(3, "irowbytes = %lu", 04154 (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); 04155 04156 png_ptr->flags |= PNG_FLAG_ROW_INIT; 04157 } 04158 #endif /* PNG_READ_SUPPORTED */ Generated on Sun May 27 2012 04:19:31 for ReactOS by
1.7.6.1
|