pngrutil.c (98297B)
1 2 /* pngrutil.c - utilities to read a PNG file 3 * 4 * Last changed in libpng 1.2.48 [March 8, 2012] 5 * Copyright (c) 1998-2012 Glenn Randers-Pehrson 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 8 * 9 * This code is released under the libpng license. 10 * For conditions of distribution and use, see the disclaimer 11 * and license in png.h 12 * 13 * This file contains routines that are only called from within 14 * libpng itself during the course of reading an image. 15 */ 16 17 #define PNG_INTERNAL 18 #define PNG_NO_PEDANTIC_WARNINGS 19 #include "png.h" 20 #ifdef PNG_READ_SUPPORTED 21 22 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) 23 # define WIN32_WCE_OLD 24 #endif 25 26 #ifdef PNG_FLOATING_POINT_SUPPORTED 27 # ifdef WIN32_WCE_OLD 28 /* The strtod() function is not supported on WindowsCE */ 29 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, 30 char **endptr) 31 { 32 double result = 0; 33 int len; 34 wchar_t *str, *end; 35 36 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); 37 str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t)); 38 if ( NULL != str ) 39 { 40 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); 41 result = wcstod(str, &end); 42 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); 43 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); 44 png_free(png_ptr, str); 45 } 46 return result; 47 } 48 # else 49 # define png_strtod(p,a,b) strtod(a,b) 50 # endif 51 #endif 52 53 png_uint_32 PNGAPI 54 png_get_uint_31(png_structp png_ptr, png_bytep buf) 55 { 56 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED 57 png_uint_32 i = png_get_uint_32(buf); 58 #else 59 /* Avoid an extra function call by inlining the result. */ 60 png_uint_32 i = ((png_uint_32)(*buf) << 24) + 61 ((png_uint_32)(*(buf + 1)) << 16) + 62 ((png_uint_32)(*(buf + 2)) << 8) + 63 (png_uint_32)(*(buf + 3)); 64 #endif 65 if (i > PNG_UINT_31_MAX) 66 png_error(png_ptr, "PNG unsigned integer out of range."); 67 return (i); 68 } 69 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED 70 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ 71 png_uint_32 PNGAPI 72 png_get_uint_32(png_bytep buf) 73 { 74 png_uint_32 i = ((png_uint_32)(*buf) << 24) + 75 ((png_uint_32)(*(buf + 1)) << 16) + 76 ((png_uint_32)(*(buf + 2)) << 8) + 77 (png_uint_32)(*(buf + 3)); 78 79 return (i); 80 } 81 82 /* Grab a signed 32-bit integer from a buffer in big-endian format. The 83 * data is stored in the PNG file in two's complement format, and it is 84 * assumed that the machine format for signed integers is the same. 85 */ 86 png_int_32 PNGAPI 87 png_get_int_32(png_bytep buf) 88 { 89 png_int_32 i = ((png_int_32)(*buf) << 24) + 90 ((png_int_32)(*(buf + 1)) << 16) + 91 ((png_int_32)(*(buf + 2)) << 8) + 92 (png_int_32)(*(buf + 3)); 93 94 return (i); 95 } 96 97 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ 98 png_uint_16 PNGAPI 99 png_get_uint_16(png_bytep buf) 100 { 101 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + 102 (png_uint_16)(*(buf + 1))); 103 104 return (i); 105 } 106 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ 107 108 /* Read the chunk header (length + type name). 109 * Put the type name into png_ptr->chunk_name, and return the length. 110 */ 111 png_uint_32 /* PRIVATE */ 112 png_read_chunk_header(png_structp png_ptr) 113 { 114 png_byte buf[8]; 115 png_uint_32 length; 116 117 /* Read the length and the chunk name */ 118 png_read_data(png_ptr, buf, 8); 119 length = png_get_uint_31(png_ptr, buf); 120 121 /* Put the chunk name into png_ptr->chunk_name */ 122 png_memcpy(png_ptr->chunk_name, buf + 4, 4); 123 124 png_debug2(0, "Reading %s chunk, length = %lu", 125 png_ptr->chunk_name, length); 126 127 /* Reset the crc and run it over the chunk name */ 128 png_reset_crc(png_ptr); 129 png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); 130 131 /* Check to see if chunk name is valid */ 132 png_check_chunk_name(png_ptr, png_ptr->chunk_name); 133 134 return length; 135 } 136 137 /* Read data, and (optionally) run it through the CRC. */ 138 void /* PRIVATE */ 139 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) 140 { 141 if (png_ptr == NULL) 142 return; 143 png_read_data(png_ptr, buf, length); 144 png_calculate_crc(png_ptr, buf, length); 145 } 146 147 /* Optionally skip data and then check the CRC. Depending on whether we 148 * are reading a ancillary or critical chunk, and how the program has set 149 * things up, we may calculate the CRC on the data and print a message. 150 * Returns '1' if there was a CRC error, '0' otherwise. 151 */ 152 int /* PRIVATE */ 153 png_crc_finish(png_structp png_ptr, png_uint_32 skip) 154 { 155 png_size_t i; 156 png_size_t istop = png_ptr->zbuf_size; 157 158 for (i = (png_size_t)skip; i > istop; i -= istop) 159 { 160 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 161 } 162 if (i) 163 { 164 png_crc_read(png_ptr, png_ptr->zbuf, i); 165 } 166 167 if (png_crc_error(png_ptr)) 168 { 169 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ 170 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || 171 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ 172 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) 173 { 174 png_chunk_warning(png_ptr, "CRC error"); 175 } 176 else 177 { 178 png_chunk_error(png_ptr, "CRC error"); 179 } 180 return (1); 181 } 182 183 return (0); 184 } 185 186 /* Compare the CRC stored in the PNG file with that calculated by libpng from 187 * the data it has read thus far. 188 */ 189 int /* PRIVATE */ 190 png_crc_error(png_structp png_ptr) 191 { 192 png_byte crc_bytes[4]; 193 png_uint_32 crc; 194 int need_crc = 1; 195 196 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ 197 { 198 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 199 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 200 need_crc = 0; 201 } 202 else /* critical */ 203 { 204 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 205 need_crc = 0; 206 } 207 208 png_read_data(png_ptr, crc_bytes, 4); 209 210 if (need_crc) 211 { 212 crc = png_get_uint_32(crc_bytes); 213 return ((int)(crc != png_ptr->crc)); 214 } 215 else 216 return (0); 217 } 218 219 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ 220 defined(PNG_READ_iCCP_SUPPORTED) 221 static png_size_t 222 png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size, 223 png_bytep output, png_size_t output_size) 224 { 225 png_size_t count = 0; 226 227 png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */ 228 png_ptr->zstream.avail_in = size; 229 230 while (1) 231 { 232 int ret, avail; 233 234 /* Reset the output buffer each time round - we empty it 235 * after every inflate call. 236 */ 237 png_ptr->zstream.next_out = png_ptr->zbuf; 238 png_ptr->zstream.avail_out = png_ptr->zbuf_size; 239 240 ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); 241 avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; 242 243 /* First copy/count any new output - but only if we didn't 244 * get an error code. 245 */ 246 if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) 247 { 248 if (output != 0 && output_size > count) 249 { 250 png_size_t copy = output_size - count; 251 if ((png_size_t) avail < copy) copy = (png_size_t) avail; 252 png_memcpy(output + count, png_ptr->zbuf, copy); 253 } 254 count += avail; 255 } 256 257 if (ret == Z_OK) 258 continue; 259 260 /* Termination conditions - always reset the zstream, it 261 * must be left in inflateInit state. 262 */ 263 png_ptr->zstream.avail_in = 0; 264 inflateReset(&png_ptr->zstream); 265 266 if (ret == Z_STREAM_END) 267 return count; /* NOTE: may be zero. */ 268 269 /* Now handle the error codes - the API always returns 0 270 * and the error message is dumped into the uncompressed 271 * buffer if available. 272 */ 273 { 274 PNG_CONST char *msg; 275 if (png_ptr->zstream.msg != 0) 276 msg = png_ptr->zstream.msg; 277 else 278 { 279 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 280 char umsg[52]; 281 282 switch (ret) 283 { 284 case Z_BUF_ERROR: 285 msg = "Buffer error in compressed datastream in %s chunk"; 286 break; 287 case Z_DATA_ERROR: 288 msg = "Data error in compressed datastream in %s chunk"; 289 break; 290 default: 291 msg = "Incomplete compressed datastream in %s chunk"; 292 break; 293 } 294 295 png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name); 296 msg = umsg; 297 #else 298 msg = "Damaged compressed datastream in chunk other than IDAT"; 299 #endif 300 } 301 302 png_warning(png_ptr, msg); 303 } 304 305 /* 0 means an error - notice that this code simple ignores 306 * zero length compressed chunks as a result. 307 */ 308 return 0; 309 } 310 } 311 312 /* 313 * Decompress trailing data in a chunk. The assumption is that chunkdata 314 * points at an allocated area holding the contents of a chunk with a 315 * trailing compressed part. What we get back is an allocated area 316 * holding the original prefix part and an uncompressed version of the 317 * trailing part (the malloc area passed in is freed). 318 */ 319 void /* PRIVATE */ 320 png_decompress_chunk(png_structp png_ptr, int comp_type, 321 png_size_t chunklength, 322 png_size_t prefix_size, png_size_t *newlength) 323 { 324 /* The caller should guarantee this */ 325 if (prefix_size > chunklength) 326 { 327 /* The recovery is to delete the chunk. */ 328 png_warning(png_ptr, "invalid chunklength"); 329 prefix_size = 0; /* To delete everything */ 330 } 331 332 else if (comp_type == PNG_COMPRESSION_TYPE_BASE) 333 { 334 png_size_t expanded_size = png_inflate(png_ptr, 335 (png_bytep)(png_ptr->chunkdata + prefix_size), 336 chunklength - prefix_size, 337 0/*output*/, 0/*output size*/); 338 339 /* Now check the limits on this chunk - if the limit fails the 340 * compressed data will be removed, the prefix will remain. 341 */ 342 if (prefix_size >= (~(png_size_t)0) - 1 || 343 expanded_size >= (~(png_size_t)0) - 1 - prefix_size 344 #ifdef PNG_USER_CHUNK_MALLOC_MAX 345 || ((PNG_USER_CHUNK_MALLOC_MAX > 0) && 346 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) 347 #endif 348 ) 349 png_warning(png_ptr, "Exceeded size limit while expanding chunk"); 350 351 /* If the size is zero either there was an error and a message 352 * has already been output (warning) or the size really is zero 353 * and we have nothing to do - the code will exit through the 354 * error case below. 355 */ 356 else if (expanded_size > 0) 357 { 358 /* Success (maybe) - really uncompress the chunk. */ 359 png_size_t new_size = 0; 360 361 png_charp text = png_malloc_warn(png_ptr, 362 prefix_size + expanded_size + 1); 363 364 if (text != NULL) 365 { 366 png_memcpy(text, png_ptr->chunkdata, prefix_size); 367 new_size = png_inflate(png_ptr, 368 (png_bytep)(png_ptr->chunkdata + prefix_size), 369 chunklength - prefix_size, 370 (png_bytep)(text + prefix_size), expanded_size); 371 text[prefix_size + expanded_size] = 0; /* just in case */ 372 373 if (new_size == expanded_size) 374 { 375 png_free(png_ptr, png_ptr->chunkdata); 376 png_ptr->chunkdata = text; 377 *newlength = prefix_size + expanded_size; 378 return; /* The success return! */ 379 } 380 381 png_warning(png_ptr, "png_inflate logic error"); 382 png_free(png_ptr, text); 383 } 384 else 385 png_warning(png_ptr, "Not enough memory to decompress chunk."); 386 } 387 } 388 389 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ 390 { 391 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 392 char umsg[50]; 393 394 png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d", 395 comp_type); 396 png_warning(png_ptr, umsg); 397 #else 398 png_warning(png_ptr, "Unknown zTXt compression type"); 399 #endif 400 401 /* The recovery is to simply drop the data. */ 402 } 403 404 /* Generic error return - leave the prefix, delete the compressed 405 * data, reallocate the chunkdata to remove the potentially large 406 * amount of compressed data. 407 */ 408 { 409 png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); 410 if (text != NULL) 411 { 412 if (prefix_size > 0) 413 png_memcpy(text, png_ptr->chunkdata, prefix_size); 414 png_free(png_ptr, png_ptr->chunkdata); 415 png_ptr->chunkdata = text; 416 417 /* This is an extra zero in the 'uncompressed' part. */ 418 *(png_ptr->chunkdata + prefix_size) = 0x00; 419 } 420 /* Ignore a malloc error here - it is safe. */ 421 } 422 423 *newlength = prefix_size; 424 } 425 #endif 426 427 /* Read and check the IDHR chunk */ 428 void /* PRIVATE */ 429 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 430 { 431 png_byte buf[13]; 432 png_uint_32 width, height; 433 int bit_depth, color_type, compression_type, filter_type; 434 int interlace_type; 435 436 png_debug(1, "in png_handle_IHDR"); 437 438 if (png_ptr->mode & PNG_HAVE_IHDR) 439 png_error(png_ptr, "Out of place IHDR"); 440 441 /* Check the length */ 442 if (length != 13) 443 png_error(png_ptr, "Invalid IHDR chunk"); 444 445 png_ptr->mode |= PNG_HAVE_IHDR; 446 447 png_crc_read(png_ptr, buf, 13); 448 png_crc_finish(png_ptr, 0); 449 450 width = png_get_uint_31(png_ptr, buf); 451 height = png_get_uint_31(png_ptr, buf + 4); 452 bit_depth = buf[8]; 453 color_type = buf[9]; 454 compression_type = buf[10]; 455 filter_type = buf[11]; 456 interlace_type = buf[12]; 457 458 /* Set internal variables */ 459 png_ptr->width = width; 460 png_ptr->height = height; 461 png_ptr->bit_depth = (png_byte)bit_depth; 462 png_ptr->interlaced = (png_byte)interlace_type; 463 png_ptr->color_type = (png_byte)color_type; 464 #ifdef PNG_MNG_FEATURES_SUPPORTED 465 png_ptr->filter_type = (png_byte)filter_type; 466 #endif 467 png_ptr->compression_type = (png_byte)compression_type; 468 469 /* Find number of channels */ 470 switch (png_ptr->color_type) 471 { 472 case PNG_COLOR_TYPE_GRAY: 473 case PNG_COLOR_TYPE_PALETTE: 474 png_ptr->channels = 1; 475 break; 476 477 case PNG_COLOR_TYPE_RGB: 478 png_ptr->channels = 3; 479 break; 480 481 case PNG_COLOR_TYPE_GRAY_ALPHA: 482 png_ptr->channels = 2; 483 break; 484 485 case PNG_COLOR_TYPE_RGB_ALPHA: 486 png_ptr->channels = 4; 487 break; 488 } 489 490 /* Set up other useful info */ 491 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 492 png_ptr->channels); 493 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); 494 png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); 495 png_debug1(3, "channels = %d", png_ptr->channels); 496 png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes); 497 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 498 color_type, interlace_type, compression_type, filter_type); 499 } 500 501 /* Read and check the palette */ 502 void /* PRIVATE */ 503 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 504 { 505 png_color palette[PNG_MAX_PALETTE_LENGTH]; 506 int num, i; 507 #ifdef PNG_POINTER_INDEXING_SUPPORTED 508 png_colorp pal_ptr; 509 #endif 510 511 png_debug(1, "in png_handle_PLTE"); 512 513 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 514 png_error(png_ptr, "Missing IHDR before PLTE"); 515 516 else if (png_ptr->mode & PNG_HAVE_IDAT) 517 { 518 png_warning(png_ptr, "Invalid PLTE after IDAT"); 519 png_crc_finish(png_ptr, length); 520 return; 521 } 522 523 else if (png_ptr->mode & PNG_HAVE_PLTE) 524 png_error(png_ptr, "Duplicate PLTE chunk"); 525 526 png_ptr->mode |= PNG_HAVE_PLTE; 527 528 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 529 { 530 png_warning(png_ptr, 531 "Ignoring PLTE chunk in grayscale PNG"); 532 png_crc_finish(png_ptr, length); 533 return; 534 } 535 #ifndef PNG_READ_OPT_PLTE_SUPPORTED 536 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 537 { 538 png_crc_finish(png_ptr, length); 539 return; 540 } 541 #endif 542 543 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) 544 { 545 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 546 { 547 png_warning(png_ptr, "Invalid palette chunk"); 548 png_crc_finish(png_ptr, length); 549 return; 550 } 551 552 else 553 { 554 png_error(png_ptr, "Invalid palette chunk"); 555 } 556 } 557 558 num = (int)length / 3; 559 560 #ifdef PNG_POINTER_INDEXING_SUPPORTED 561 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) 562 { 563 png_byte buf[3]; 564 565 png_crc_read(png_ptr, buf, 3); 566 pal_ptr->red = buf[0]; 567 pal_ptr->green = buf[1]; 568 pal_ptr->blue = buf[2]; 569 } 570 #else 571 for (i = 0; i < num; i++) 572 { 573 png_byte buf[3]; 574 575 png_crc_read(png_ptr, buf, 3); 576 /* Don't depend upon png_color being any order */ 577 palette[i].red = buf[0]; 578 palette[i].green = buf[1]; 579 palette[i].blue = buf[2]; 580 } 581 #endif 582 583 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do 584 * whatever the normal CRC configuration tells us. However, if we 585 * have an RGB image, the PLTE can be considered ancillary, so 586 * we will act as though it is. 587 */ 588 #ifndef PNG_READ_OPT_PLTE_SUPPORTED 589 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 590 #endif 591 { 592 png_crc_finish(png_ptr, 0); 593 } 594 #ifndef PNG_READ_OPT_PLTE_SUPPORTED 595 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ 596 { 597 /* If we don't want to use the data from an ancillary chunk, 598 we have two options: an error abort, or a warning and we 599 ignore the data in this chunk (which should be OK, since 600 it's considered ancillary for a RGB or RGBA image). */ 601 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) 602 { 603 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) 604 { 605 png_chunk_error(png_ptr, "CRC error"); 606 } 607 else 608 { 609 png_chunk_warning(png_ptr, "CRC error"); 610 return; 611 } 612 } 613 /* Otherwise, we (optionally) emit a warning and use the chunk. */ 614 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) 615 { 616 png_chunk_warning(png_ptr, "CRC error"); 617 } 618 } 619 #endif 620 621 png_set_PLTE(png_ptr, info_ptr, palette, num); 622 623 #ifdef PNG_READ_tRNS_SUPPORTED 624 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 625 { 626 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 627 { 628 if (png_ptr->num_trans > (png_uint_16)num) 629 { 630 png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); 631 png_ptr->num_trans = (png_uint_16)num; 632 } 633 if (info_ptr->num_trans > (png_uint_16)num) 634 { 635 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); 636 info_ptr->num_trans = (png_uint_16)num; 637 } 638 } 639 } 640 #endif 641 642 } 643 644 void /* PRIVATE */ 645 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 646 { 647 png_debug(1, "in png_handle_IEND"); 648 649 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) 650 { 651 png_error(png_ptr, "No image in file"); 652 } 653 654 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); 655 656 if (length != 0) 657 { 658 png_warning(png_ptr, "Incorrect IEND chunk length"); 659 } 660 png_crc_finish(png_ptr, length); 661 662 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ 663 } 664 665 #ifdef PNG_READ_gAMA_SUPPORTED 666 void /* PRIVATE */ 667 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 668 { 669 png_fixed_point igamma; 670 #ifdef PNG_FLOATING_POINT_SUPPORTED 671 float file_gamma; 672 #endif 673 png_byte buf[4]; 674 675 png_debug(1, "in png_handle_gAMA"); 676 677 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 678 png_error(png_ptr, "Missing IHDR before gAMA"); 679 else if (png_ptr->mode & PNG_HAVE_IDAT) 680 { 681 png_warning(png_ptr, "Invalid gAMA after IDAT"); 682 png_crc_finish(png_ptr, length); 683 return; 684 } 685 else if (png_ptr->mode & PNG_HAVE_PLTE) 686 /* Should be an error, but we can cope with it */ 687 png_warning(png_ptr, "Out of place gAMA chunk"); 688 689 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) 690 #ifdef PNG_READ_sRGB_SUPPORTED 691 && !(info_ptr->valid & PNG_INFO_sRGB) 692 #endif 693 ) 694 { 695 png_warning(png_ptr, "Duplicate gAMA chunk"); 696 png_crc_finish(png_ptr, length); 697 return; 698 } 699 700 if (length != 4) 701 { 702 png_warning(png_ptr, "Incorrect gAMA chunk length"); 703 png_crc_finish(png_ptr, length); 704 return; 705 } 706 707 png_crc_read(png_ptr, buf, 4); 708 if (png_crc_finish(png_ptr, 0)) 709 return; 710 711 igamma = (png_fixed_point)png_get_uint_32(buf); 712 /* Check for zero gamma */ 713 if (igamma == 0) 714 { 715 png_warning(png_ptr, 716 "Ignoring gAMA chunk with gamma=0"); 717 return; 718 } 719 720 #ifdef PNG_READ_sRGB_SUPPORTED 721 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 722 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 723 { 724 png_warning(png_ptr, 725 "Ignoring incorrect gAMA value when sRGB is also present"); 726 #ifdef PNG_CONSOLE_IO_SUPPORTED 727 fprintf(stderr, "gamma = (%d/100000)", (int)igamma); 728 #endif 729 return; 730 } 731 #endif /* PNG_READ_sRGB_SUPPORTED */ 732 733 #ifdef PNG_FLOATING_POINT_SUPPORTED 734 file_gamma = (float)igamma / (float)100000.0; 735 # ifdef PNG_READ_GAMMA_SUPPORTED 736 png_ptr->gamma = file_gamma; 737 # endif 738 png_set_gAMA(png_ptr, info_ptr, file_gamma); 739 #endif 740 #ifdef PNG_FIXED_POINT_SUPPORTED 741 png_set_gAMA_fixed(png_ptr, info_ptr, igamma); 742 #endif 743 } 744 #endif 745 746 #ifdef PNG_READ_sBIT_SUPPORTED 747 void /* PRIVATE */ 748 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 749 { 750 png_size_t truelen; 751 png_byte buf[4]; 752 753 png_debug(1, "in png_handle_sBIT"); 754 755 buf[0] = buf[1] = buf[2] = buf[3] = 0; 756 757 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 758 png_error(png_ptr, "Missing IHDR before sBIT"); 759 else if (png_ptr->mode & PNG_HAVE_IDAT) 760 { 761 png_warning(png_ptr, "Invalid sBIT after IDAT"); 762 png_crc_finish(png_ptr, length); 763 return; 764 } 765 else if (png_ptr->mode & PNG_HAVE_PLTE) 766 { 767 /* Should be an error, but we can cope with it */ 768 png_warning(png_ptr, "Out of place sBIT chunk"); 769 } 770 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) 771 { 772 png_warning(png_ptr, "Duplicate sBIT chunk"); 773 png_crc_finish(png_ptr, length); 774 return; 775 } 776 777 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 778 truelen = 3; 779 else 780 truelen = (png_size_t)png_ptr->channels; 781 782 if (length != truelen || length > 4) 783 { 784 png_warning(png_ptr, "Incorrect sBIT chunk length"); 785 png_crc_finish(png_ptr, length); 786 return; 787 } 788 789 png_crc_read(png_ptr, buf, truelen); 790 if (png_crc_finish(png_ptr, 0)) 791 return; 792 793 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 794 { 795 png_ptr->sig_bit.red = buf[0]; 796 png_ptr->sig_bit.green = buf[1]; 797 png_ptr->sig_bit.blue = buf[2]; 798 png_ptr->sig_bit.alpha = buf[3]; 799 } 800 else 801 { 802 png_ptr->sig_bit.gray = buf[0]; 803 png_ptr->sig_bit.red = buf[0]; 804 png_ptr->sig_bit.green = buf[0]; 805 png_ptr->sig_bit.blue = buf[0]; 806 png_ptr->sig_bit.alpha = buf[1]; 807 } 808 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); 809 } 810 #endif 811 812 #ifdef PNG_READ_cHRM_SUPPORTED 813 void /* PRIVATE */ 814 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 815 { 816 png_byte buf[32]; 817 #ifdef PNG_FLOATING_POINT_SUPPORTED 818 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; 819 #endif 820 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 821 int_y_green, int_x_blue, int_y_blue; 822 823 png_uint_32 uint_x, uint_y; 824 825 png_debug(1, "in png_handle_cHRM"); 826 827 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 828 png_error(png_ptr, "Missing IHDR before cHRM"); 829 else if (png_ptr->mode & PNG_HAVE_IDAT) 830 { 831 png_warning(png_ptr, "Invalid cHRM after IDAT"); 832 png_crc_finish(png_ptr, length); 833 return; 834 } 835 else if (png_ptr->mode & PNG_HAVE_PLTE) 836 /* Should be an error, but we can cope with it */ 837 png_warning(png_ptr, "Missing PLTE before cHRM"); 838 839 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) 840 #ifdef PNG_READ_sRGB_SUPPORTED 841 && !(info_ptr->valid & PNG_INFO_sRGB) 842 #endif 843 ) 844 { 845 png_warning(png_ptr, "Duplicate cHRM chunk"); 846 png_crc_finish(png_ptr, length); 847 return; 848 } 849 850 if (length != 32) 851 { 852 png_warning(png_ptr, "Incorrect cHRM chunk length"); 853 png_crc_finish(png_ptr, length); 854 return; 855 } 856 857 png_crc_read(png_ptr, buf, 32); 858 if (png_crc_finish(png_ptr, 0)) 859 return; 860 861 uint_x = png_get_uint_32(buf); 862 uint_y = png_get_uint_32(buf + 4); 863 int_x_white = (png_fixed_point)uint_x; 864 int_y_white = (png_fixed_point)uint_y; 865 866 uint_x = png_get_uint_32(buf + 8); 867 uint_y = png_get_uint_32(buf + 12); 868 int_x_red = (png_fixed_point)uint_x; 869 int_y_red = (png_fixed_point)uint_y; 870 871 uint_x = png_get_uint_32(buf + 16); 872 uint_y = png_get_uint_32(buf + 20); 873 int_x_green = (png_fixed_point)uint_x; 874 int_y_green = (png_fixed_point)uint_y; 875 876 uint_x = png_get_uint_32(buf + 24); 877 uint_y = png_get_uint_32(buf + 28); 878 int_x_blue = (png_fixed_point)uint_x; 879 int_y_blue = (png_fixed_point)uint_y; 880 881 #ifdef PNG_FLOATING_POINT_SUPPORTED 882 white_x = (float)int_x_white / (float)100000.0; 883 white_y = (float)int_y_white / (float)100000.0; 884 red_x = (float)int_x_red / (float)100000.0; 885 red_y = (float)int_y_red / (float)100000.0; 886 green_x = (float)int_x_green / (float)100000.0; 887 green_y = (float)int_y_green / (float)100000.0; 888 blue_x = (float)int_x_blue / (float)100000.0; 889 blue_y = (float)int_y_blue / (float)100000.0; 890 #endif 891 892 #ifdef PNG_READ_sRGB_SUPPORTED 893 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) 894 { 895 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || 896 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || 897 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || 898 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || 899 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || 900 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || 901 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || 902 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) 903 { 904 png_warning(png_ptr, 905 "Ignoring incorrect cHRM value when sRGB is also present"); 906 #ifdef PNG_CONSOLE_IO_SUPPORTED 907 #ifdef PNG_FLOATING_POINT_SUPPORTED 908 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", 909 white_x, white_y, red_x, red_y); 910 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", 911 green_x, green_y, blue_x, blue_y); 912 #else 913 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", 914 (long)int_x_white, (long)int_y_white, 915 (long)int_x_red, (long)int_y_red); 916 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", 917 (long)int_x_green, (long)int_y_green, 918 (long)int_x_blue, (long)int_y_blue); 919 #endif 920 #endif /* PNG_CONSOLE_IO_SUPPORTED */ 921 } 922 return; 923 } 924 #endif /* PNG_READ_sRGB_SUPPORTED */ 925 926 #ifdef PNG_FLOATING_POINT_SUPPORTED 927 png_set_cHRM(png_ptr, info_ptr, 928 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); 929 #endif 930 #ifdef PNG_FIXED_POINT_SUPPORTED 931 png_set_cHRM_fixed(png_ptr, info_ptr, 932 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 933 int_y_green, int_x_blue, int_y_blue); 934 #endif 935 } 936 #endif 937 938 #ifdef PNG_READ_sRGB_SUPPORTED 939 void /* PRIVATE */ 940 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 941 { 942 int intent; 943 png_byte buf[1]; 944 945 png_debug(1, "in png_handle_sRGB"); 946 947 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 948 png_error(png_ptr, "Missing IHDR before sRGB"); 949 else if (png_ptr->mode & PNG_HAVE_IDAT) 950 { 951 png_warning(png_ptr, "Invalid sRGB after IDAT"); 952 png_crc_finish(png_ptr, length); 953 return; 954 } 955 else if (png_ptr->mode & PNG_HAVE_PLTE) 956 /* Should be an error, but we can cope with it */ 957 png_warning(png_ptr, "Out of place sRGB chunk"); 958 959 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 960 { 961 png_warning(png_ptr, "Duplicate sRGB chunk"); 962 png_crc_finish(png_ptr, length); 963 return; 964 } 965 966 if (length != 1) 967 { 968 png_warning(png_ptr, "Incorrect sRGB chunk length"); 969 png_crc_finish(png_ptr, length); 970 return; 971 } 972 973 png_crc_read(png_ptr, buf, 1); 974 if (png_crc_finish(png_ptr, 0)) 975 return; 976 977 intent = buf[0]; 978 /* Check for bad intent */ 979 if (intent >= PNG_sRGB_INTENT_LAST) 980 { 981 png_warning(png_ptr, "Unknown sRGB intent"); 982 return; 983 } 984 985 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) 986 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) 987 { 988 png_fixed_point igamma; 989 #ifdef PNG_FIXED_POINT_SUPPORTED 990 igamma=info_ptr->int_gamma; 991 #else 992 # ifdef PNG_FLOATING_POINT_SUPPORTED 993 igamma=(png_fixed_point)(info_ptr->gamma * 100000.); 994 # endif 995 #endif 996 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 997 { 998 png_warning(png_ptr, 999 "Ignoring incorrect gAMA value when sRGB is also present"); 1000 #ifdef PNG_CONSOLE_IO_SUPPORTED 1001 # ifdef PNG_FIXED_POINT_SUPPORTED 1002 fprintf(stderr, "incorrect gamma=(%d/100000)\n", 1003 (int)png_ptr->int_gamma); 1004 # else 1005 # ifdef PNG_FLOATING_POINT_SUPPORTED 1006 fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma); 1007 # endif 1008 # endif 1009 #endif 1010 } 1011 } 1012 #endif /* PNG_READ_gAMA_SUPPORTED */ 1013 1014 #ifdef PNG_READ_cHRM_SUPPORTED 1015 #ifdef PNG_FIXED_POINT_SUPPORTED 1016 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) 1017 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || 1018 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || 1019 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || 1020 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || 1021 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || 1022 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || 1023 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || 1024 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) 1025 { 1026 png_warning(png_ptr, 1027 "Ignoring incorrect cHRM value when sRGB is also present"); 1028 } 1029 #endif /* PNG_FIXED_POINT_SUPPORTED */ 1030 #endif /* PNG_READ_cHRM_SUPPORTED */ 1031 1032 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); 1033 } 1034 #endif /* PNG_READ_sRGB_SUPPORTED */ 1035 1036 #ifdef PNG_READ_iCCP_SUPPORTED 1037 void /* PRIVATE */ 1038 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1039 /* Note: this does not properly handle chunks that are > 64K under DOS */ 1040 { 1041 png_byte compression_type; 1042 png_bytep pC; 1043 png_charp profile; 1044 png_uint_32 skip = 0; 1045 png_uint_32 profile_size, profile_length; 1046 png_size_t slength, prefix_length, data_length; 1047 1048 png_debug(1, "in png_handle_iCCP"); 1049 1050 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1051 png_error(png_ptr, "Missing IHDR before iCCP"); 1052 else if (png_ptr->mode & PNG_HAVE_IDAT) 1053 { 1054 png_warning(png_ptr, "Invalid iCCP after IDAT"); 1055 png_crc_finish(png_ptr, length); 1056 return; 1057 } 1058 else if (png_ptr->mode & PNG_HAVE_PLTE) 1059 /* Should be an error, but we can cope with it */ 1060 png_warning(png_ptr, "Out of place iCCP chunk"); 1061 1062 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) 1063 { 1064 png_warning(png_ptr, "Duplicate iCCP chunk"); 1065 png_crc_finish(png_ptr, length); 1066 return; 1067 } 1068 1069 #ifdef PNG_MAX_MALLOC_64K 1070 if (length > (png_uint_32)65535L) 1071 { 1072 png_warning(png_ptr, "iCCP chunk too large to fit in memory"); 1073 skip = length - (png_uint_32)65535L; 1074 length = (png_uint_32)65535L; 1075 } 1076 #endif 1077 1078 png_free(png_ptr, png_ptr->chunkdata); 1079 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1080 slength = (png_size_t)length; 1081 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1082 1083 if (png_crc_finish(png_ptr, skip)) 1084 { 1085 png_free(png_ptr, png_ptr->chunkdata); 1086 png_ptr->chunkdata = NULL; 1087 return; 1088 } 1089 1090 png_ptr->chunkdata[slength] = 0x00; 1091 1092 for (profile = png_ptr->chunkdata; *profile; profile++) 1093 /* Empty loop to find end of name */ ; 1094 1095 ++profile; 1096 1097 /* There should be at least one zero (the compression type byte) 1098 * following the separator, and we should be on it 1099 */ 1100 if ( profile >= png_ptr->chunkdata + slength - 1) 1101 { 1102 png_free(png_ptr, png_ptr->chunkdata); 1103 png_ptr->chunkdata = NULL; 1104 png_warning(png_ptr, "Malformed iCCP chunk"); 1105 return; 1106 } 1107 1108 /* Compression_type should always be zero */ 1109 compression_type = *profile++; 1110 if (compression_type) 1111 { 1112 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); 1113 compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 1114 wrote nonzero) */ 1115 } 1116 1117 prefix_length = profile - png_ptr->chunkdata; 1118 png_decompress_chunk(png_ptr, compression_type, 1119 slength, prefix_length, &data_length); 1120 1121 profile_length = data_length - prefix_length; 1122 1123 if ( prefix_length > data_length || profile_length < 4) 1124 { 1125 png_free(png_ptr, png_ptr->chunkdata); 1126 png_ptr->chunkdata = NULL; 1127 png_warning(png_ptr, "Profile size field missing from iCCP chunk"); 1128 return; 1129 } 1130 1131 /* Check the profile_size recorded in the first 32 bits of the ICC profile */ 1132 pC = (png_bytep)(png_ptr->chunkdata + prefix_length); 1133 profile_size = ((*(pC ))<<24) | 1134 ((*(pC + 1))<<16) | 1135 ((*(pC + 2))<< 8) | 1136 ((*(pC + 3)) ); 1137 1138 if (profile_size < profile_length) 1139 profile_length = profile_size; 1140 1141 if (profile_size > profile_length) 1142 { 1143 png_free(png_ptr, png_ptr->chunkdata); 1144 png_ptr->chunkdata = NULL; 1145 png_warning(png_ptr, "Ignoring truncated iCCP profile."); 1146 return; 1147 } 1148 1149 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, 1150 compression_type, png_ptr->chunkdata + prefix_length, profile_length); 1151 png_free(png_ptr, png_ptr->chunkdata); 1152 png_ptr->chunkdata = NULL; 1153 } 1154 #endif /* PNG_READ_iCCP_SUPPORTED */ 1155 1156 #ifdef PNG_READ_sPLT_SUPPORTED 1157 void /* PRIVATE */ 1158 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1159 /* Note: this does not properly handle chunks that are > 64K under DOS */ 1160 { 1161 png_bytep entry_start; 1162 png_sPLT_t new_palette; 1163 #ifdef PNG_POINTER_INDEXING_SUPPORTED 1164 png_sPLT_entryp pp; 1165 #endif 1166 int data_length, entry_size, i; 1167 png_uint_32 skip = 0; 1168 png_size_t slength; 1169 1170 png_debug(1, "in png_handle_sPLT"); 1171 1172 #ifdef PNG_USER_LIMITS_SUPPORTED 1173 1174 if (png_ptr->user_chunk_cache_max != 0) 1175 { 1176 if (png_ptr->user_chunk_cache_max == 1) 1177 { 1178 png_crc_finish(png_ptr, length); 1179 return; 1180 } 1181 if (--png_ptr->user_chunk_cache_max == 1) 1182 { 1183 png_warning(png_ptr, "No space in chunk cache for sPLT"); 1184 png_crc_finish(png_ptr, length); 1185 return; 1186 } 1187 } 1188 #endif 1189 1190 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1191 png_error(png_ptr, "Missing IHDR before sPLT"); 1192 else if (png_ptr->mode & PNG_HAVE_IDAT) 1193 { 1194 png_warning(png_ptr, "Invalid sPLT after IDAT"); 1195 png_crc_finish(png_ptr, length); 1196 return; 1197 } 1198 1199 #ifdef PNG_MAX_MALLOC_64K 1200 if (length > (png_uint_32)65535L) 1201 { 1202 png_warning(png_ptr, "sPLT chunk too large to fit in memory"); 1203 skip = length - (png_uint_32)65535L; 1204 length = (png_uint_32)65535L; 1205 } 1206 #endif 1207 1208 png_free(png_ptr, png_ptr->chunkdata); 1209 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1210 slength = (png_size_t)length; 1211 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1212 1213 if (png_crc_finish(png_ptr, skip)) 1214 { 1215 png_free(png_ptr, png_ptr->chunkdata); 1216 png_ptr->chunkdata = NULL; 1217 return; 1218 } 1219 1220 png_ptr->chunkdata[slength] = 0x00; 1221 1222 for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; 1223 entry_start++) 1224 /* Empty loop to find end of name */ ; 1225 ++entry_start; 1226 1227 /* A sample depth should follow the separator, and we should be on it */ 1228 if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) 1229 { 1230 png_free(png_ptr, png_ptr->chunkdata); 1231 png_ptr->chunkdata = NULL; 1232 png_warning(png_ptr, "malformed sPLT chunk"); 1233 return; 1234 } 1235 1236 new_palette.depth = *entry_start++; 1237 entry_size = (new_palette.depth == 8 ? 6 : 10); 1238 data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata)); 1239 1240 /* Integrity-check the data length */ 1241 if (data_length % entry_size) 1242 { 1243 png_free(png_ptr, png_ptr->chunkdata); 1244 png_ptr->chunkdata = NULL; 1245 png_warning(png_ptr, "sPLT chunk has bad length"); 1246 return; 1247 } 1248 1249 new_palette.nentries = (png_int_32) ( data_length / entry_size); 1250 if ((png_uint_32) new_palette.nentries > 1251 (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry))) 1252 { 1253 png_warning(png_ptr, "sPLT chunk too long"); 1254 return; 1255 } 1256 new_palette.entries = (png_sPLT_entryp)png_malloc_warn( 1257 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); 1258 if (new_palette.entries == NULL) 1259 { 1260 png_warning(png_ptr, "sPLT chunk requires too much memory"); 1261 return; 1262 } 1263 1264 #ifdef PNG_POINTER_INDEXING_SUPPORTED 1265 for (i = 0; i < new_palette.nentries; i++) 1266 { 1267 pp = new_palette.entries + i; 1268 1269 if (new_palette.depth == 8) 1270 { 1271 pp->red = *entry_start++; 1272 pp->green = *entry_start++; 1273 pp->blue = *entry_start++; 1274 pp->alpha = *entry_start++; 1275 } 1276 else 1277 { 1278 pp->red = png_get_uint_16(entry_start); entry_start += 2; 1279 pp->green = png_get_uint_16(entry_start); entry_start += 2; 1280 pp->blue = png_get_uint_16(entry_start); entry_start += 2; 1281 pp->alpha = png_get_uint_16(entry_start); entry_start += 2; 1282 } 1283 pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1284 } 1285 #else 1286 pp = new_palette.entries; 1287 for (i = 0; i < new_palette.nentries; i++) 1288 { 1289 1290 if (new_palette.depth == 8) 1291 { 1292 pp[i].red = *entry_start++; 1293 pp[i].green = *entry_start++; 1294 pp[i].blue = *entry_start++; 1295 pp[i].alpha = *entry_start++; 1296 } 1297 else 1298 { 1299 pp[i].red = png_get_uint_16(entry_start); entry_start += 2; 1300 pp[i].green = png_get_uint_16(entry_start); entry_start += 2; 1301 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; 1302 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; 1303 } 1304 pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1305 } 1306 #endif 1307 1308 /* Discard all chunk data except the name and stash that */ 1309 new_palette.name = png_ptr->chunkdata; 1310 1311 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); 1312 1313 png_free(png_ptr, png_ptr->chunkdata); 1314 png_ptr->chunkdata = NULL; 1315 png_free(png_ptr, new_palette.entries); 1316 } 1317 #endif /* PNG_READ_sPLT_SUPPORTED */ 1318 1319 #ifdef PNG_READ_tRNS_SUPPORTED 1320 void /* PRIVATE */ 1321 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1322 { 1323 png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; 1324 1325 png_debug(1, "in png_handle_tRNS"); 1326 1327 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1328 png_error(png_ptr, "Missing IHDR before tRNS"); 1329 else if (png_ptr->mode & PNG_HAVE_IDAT) 1330 { 1331 png_warning(png_ptr, "Invalid tRNS after IDAT"); 1332 png_crc_finish(png_ptr, length); 1333 return; 1334 } 1335 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 1336 { 1337 png_warning(png_ptr, "Duplicate tRNS chunk"); 1338 png_crc_finish(png_ptr, length); 1339 return; 1340 } 1341 1342 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1343 { 1344 png_byte buf[2]; 1345 1346 if (length != 2) 1347 { 1348 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1349 png_crc_finish(png_ptr, length); 1350 return; 1351 } 1352 1353 png_crc_read(png_ptr, buf, 2); 1354 png_ptr->num_trans = 1; 1355 png_ptr->trans_values.gray = png_get_uint_16(buf); 1356 } 1357 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1358 { 1359 png_byte buf[6]; 1360 1361 if (length != 6) 1362 { 1363 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1364 png_crc_finish(png_ptr, length); 1365 return; 1366 } 1367 png_crc_read(png_ptr, buf, (png_size_t)length); 1368 png_ptr->num_trans = 1; 1369 png_ptr->trans_values.red = png_get_uint_16(buf); 1370 png_ptr->trans_values.green = png_get_uint_16(buf + 2); 1371 png_ptr->trans_values.blue = png_get_uint_16(buf + 4); 1372 } 1373 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1374 { 1375 if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1376 { 1377 /* Should be an error, but we can cope with it. */ 1378 png_warning(png_ptr, "Missing PLTE before tRNS"); 1379 } 1380 if (length > (png_uint_32)png_ptr->num_palette || 1381 length > PNG_MAX_PALETTE_LENGTH) 1382 { 1383 png_warning(png_ptr, "Incorrect tRNS chunk length"); 1384 png_crc_finish(png_ptr, length); 1385 return; 1386 } 1387 if (length == 0) 1388 { 1389 png_warning(png_ptr, "Zero length tRNS chunk"); 1390 png_crc_finish(png_ptr, length); 1391 return; 1392 } 1393 png_crc_read(png_ptr, readbuf, (png_size_t)length); 1394 png_ptr->num_trans = (png_uint_16)length; 1395 } 1396 else 1397 { 1398 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); 1399 png_crc_finish(png_ptr, length); 1400 return; 1401 } 1402 1403 if (png_crc_finish(png_ptr, 0)) 1404 { 1405 png_ptr->num_trans = 0; 1406 return; 1407 } 1408 1409 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, 1410 &(png_ptr->trans_values)); 1411 } 1412 #endif 1413 1414 #ifdef PNG_READ_bKGD_SUPPORTED 1415 void /* PRIVATE */ 1416 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1417 { 1418 png_size_t truelen; 1419 png_byte buf[6]; 1420 1421 png_debug(1, "in png_handle_bKGD"); 1422 1423 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1424 png_error(png_ptr, "Missing IHDR before bKGD"); 1425 else if (png_ptr->mode & PNG_HAVE_IDAT) 1426 { 1427 png_warning(png_ptr, "Invalid bKGD after IDAT"); 1428 png_crc_finish(png_ptr, length); 1429 return; 1430 } 1431 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 1432 !(png_ptr->mode & PNG_HAVE_PLTE)) 1433 { 1434 png_warning(png_ptr, "Missing PLTE before bKGD"); 1435 png_crc_finish(png_ptr, length); 1436 return; 1437 } 1438 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) 1439 { 1440 png_warning(png_ptr, "Duplicate bKGD chunk"); 1441 png_crc_finish(png_ptr, length); 1442 return; 1443 } 1444 1445 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1446 truelen = 1; 1447 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1448 truelen = 6; 1449 else 1450 truelen = 2; 1451 1452 if (length != truelen) 1453 { 1454 png_warning(png_ptr, "Incorrect bKGD chunk length"); 1455 png_crc_finish(png_ptr, length); 1456 return; 1457 } 1458 1459 png_crc_read(png_ptr, buf, truelen); 1460 if (png_crc_finish(png_ptr, 0)) 1461 return; 1462 1463 /* We convert the index value into RGB components so that we can allow 1464 * arbitrary RGB values for background when we have transparency, and 1465 * so it is easy to determine the RGB values of the background color 1466 * from the info_ptr struct. */ 1467 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1468 { 1469 png_ptr->background.index = buf[0]; 1470 if (info_ptr && info_ptr->num_palette) 1471 { 1472 if (buf[0] >= info_ptr->num_palette) 1473 { 1474 png_warning(png_ptr, "Incorrect bKGD chunk index value"); 1475 return; 1476 } 1477 png_ptr->background.red = 1478 (png_uint_16)png_ptr->palette[buf[0]].red; 1479 png_ptr->background.green = 1480 (png_uint_16)png_ptr->palette[buf[0]].green; 1481 png_ptr->background.blue = 1482 (png_uint_16)png_ptr->palette[buf[0]].blue; 1483 } 1484 } 1485 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ 1486 { 1487 png_ptr->background.red = 1488 png_ptr->background.green = 1489 png_ptr->background.blue = 1490 png_ptr->background.gray = png_get_uint_16(buf); 1491 } 1492 else 1493 { 1494 png_ptr->background.red = png_get_uint_16(buf); 1495 png_ptr->background.green = png_get_uint_16(buf + 2); 1496 png_ptr->background.blue = png_get_uint_16(buf + 4); 1497 } 1498 1499 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); 1500 } 1501 #endif 1502 1503 #ifdef PNG_READ_hIST_SUPPORTED 1504 void /* PRIVATE */ 1505 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1506 { 1507 unsigned int num, i; 1508 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; 1509 1510 png_debug(1, "in png_handle_hIST"); 1511 1512 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1513 png_error(png_ptr, "Missing IHDR before hIST"); 1514 else if (png_ptr->mode & PNG_HAVE_IDAT) 1515 { 1516 png_warning(png_ptr, "Invalid hIST after IDAT"); 1517 png_crc_finish(png_ptr, length); 1518 return; 1519 } 1520 else if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1521 { 1522 png_warning(png_ptr, "Missing PLTE before hIST"); 1523 png_crc_finish(png_ptr, length); 1524 return; 1525 } 1526 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) 1527 { 1528 png_warning(png_ptr, "Duplicate hIST chunk"); 1529 png_crc_finish(png_ptr, length); 1530 return; 1531 } 1532 1533 if (length > 2*PNG_MAX_PALETTE_LENGTH || 1534 length != (unsigned int) (2*png_ptr->num_palette)) 1535 { 1536 png_warning(png_ptr, "Incorrect hIST chunk length"); 1537 png_crc_finish(png_ptr, length); 1538 return; 1539 } 1540 1541 num = length / 2 ; 1542 1543 for (i = 0; i < num; i++) 1544 { 1545 png_byte buf[2]; 1546 1547 png_crc_read(png_ptr, buf, 2); 1548 readbuf[i] = png_get_uint_16(buf); 1549 } 1550 1551 if (png_crc_finish(png_ptr, 0)) 1552 return; 1553 1554 png_set_hIST(png_ptr, info_ptr, readbuf); 1555 } 1556 #endif 1557 1558 #ifdef PNG_READ_pHYs_SUPPORTED 1559 void /* PRIVATE */ 1560 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1561 { 1562 png_byte buf[9]; 1563 png_uint_32 res_x, res_y; 1564 int unit_type; 1565 1566 png_debug(1, "in png_handle_pHYs"); 1567 1568 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1569 png_error(png_ptr, "Missing IHDR before pHYs"); 1570 else if (png_ptr->mode & PNG_HAVE_IDAT) 1571 { 1572 png_warning(png_ptr, "Invalid pHYs after IDAT"); 1573 png_crc_finish(png_ptr, length); 1574 return; 1575 } 1576 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) 1577 { 1578 png_warning(png_ptr, "Duplicate pHYs chunk"); 1579 png_crc_finish(png_ptr, length); 1580 return; 1581 } 1582 1583 if (length != 9) 1584 { 1585 png_warning(png_ptr, "Incorrect pHYs chunk length"); 1586 png_crc_finish(png_ptr, length); 1587 return; 1588 } 1589 1590 png_crc_read(png_ptr, buf, 9); 1591 if (png_crc_finish(png_ptr, 0)) 1592 return; 1593 1594 res_x = png_get_uint_32(buf); 1595 res_y = png_get_uint_32(buf + 4); 1596 unit_type = buf[8]; 1597 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); 1598 } 1599 #endif 1600 1601 #ifdef PNG_READ_oFFs_SUPPORTED 1602 void /* PRIVATE */ 1603 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1604 { 1605 png_byte buf[9]; 1606 png_int_32 offset_x, offset_y; 1607 int unit_type; 1608 1609 png_debug(1, "in png_handle_oFFs"); 1610 1611 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1612 png_error(png_ptr, "Missing IHDR before oFFs"); 1613 else if (png_ptr->mode & PNG_HAVE_IDAT) 1614 { 1615 png_warning(png_ptr, "Invalid oFFs after IDAT"); 1616 png_crc_finish(png_ptr, length); 1617 return; 1618 } 1619 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) 1620 { 1621 png_warning(png_ptr, "Duplicate oFFs chunk"); 1622 png_crc_finish(png_ptr, length); 1623 return; 1624 } 1625 1626 if (length != 9) 1627 { 1628 png_warning(png_ptr, "Incorrect oFFs chunk length"); 1629 png_crc_finish(png_ptr, length); 1630 return; 1631 } 1632 1633 png_crc_read(png_ptr, buf, 9); 1634 if (png_crc_finish(png_ptr, 0)) 1635 return; 1636 1637 offset_x = png_get_int_32(buf); 1638 offset_y = png_get_int_32(buf + 4); 1639 unit_type = buf[8]; 1640 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); 1641 } 1642 #endif 1643 1644 #ifdef PNG_READ_pCAL_SUPPORTED 1645 /* Read the pCAL chunk (described in the PNG Extensions document) */ 1646 void /* PRIVATE */ 1647 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1648 { 1649 png_int_32 X0, X1; 1650 png_byte type, nparams; 1651 png_charp buf, units, endptr; 1652 png_charpp params; 1653 png_size_t slength; 1654 int i; 1655 1656 png_debug(1, "in png_handle_pCAL"); 1657 1658 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1659 png_error(png_ptr, "Missing IHDR before pCAL"); 1660 else if (png_ptr->mode & PNG_HAVE_IDAT) 1661 { 1662 png_warning(png_ptr, "Invalid pCAL after IDAT"); 1663 png_crc_finish(png_ptr, length); 1664 return; 1665 } 1666 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) 1667 { 1668 png_warning(png_ptr, "Duplicate pCAL chunk"); 1669 png_crc_finish(png_ptr, length); 1670 return; 1671 } 1672 1673 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)", 1674 length + 1); 1675 png_free(png_ptr, png_ptr->chunkdata); 1676 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1677 if (png_ptr->chunkdata == NULL) 1678 { 1679 png_warning(png_ptr, "No memory for pCAL purpose."); 1680 return; 1681 } 1682 slength = (png_size_t)length; 1683 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1684 1685 if (png_crc_finish(png_ptr, 0)) 1686 { 1687 png_free(png_ptr, png_ptr->chunkdata); 1688 png_ptr->chunkdata = NULL; 1689 return; 1690 } 1691 1692 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 1693 1694 png_debug(3, "Finding end of pCAL purpose string"); 1695 for (buf = png_ptr->chunkdata; *buf; buf++) 1696 /* Empty loop */ ; 1697 1698 endptr = png_ptr->chunkdata + slength; 1699 1700 /* We need to have at least 12 bytes after the purpose string 1701 in order to get the parameter information. */ 1702 if (endptr <= buf + 12) 1703 { 1704 png_warning(png_ptr, "Invalid pCAL data"); 1705 png_free(png_ptr, png_ptr->chunkdata); 1706 png_ptr->chunkdata = NULL; 1707 return; 1708 } 1709 1710 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); 1711 X0 = png_get_int_32((png_bytep)buf+1); 1712 X1 = png_get_int_32((png_bytep)buf+5); 1713 type = buf[9]; 1714 nparams = buf[10]; 1715 units = buf + 11; 1716 1717 png_debug(3, "Checking pCAL equation type and number of parameters"); 1718 /* Check that we have the right number of parameters for known 1719 equation types. */ 1720 if ((type == PNG_EQUATION_LINEAR && nparams != 2) || 1721 (type == PNG_EQUATION_BASE_E && nparams != 3) || 1722 (type == PNG_EQUATION_ARBITRARY && nparams != 3) || 1723 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) 1724 { 1725 png_warning(png_ptr, "Invalid pCAL parameters for equation type"); 1726 png_free(png_ptr, png_ptr->chunkdata); 1727 png_ptr->chunkdata = NULL; 1728 return; 1729 } 1730 else if (type >= PNG_EQUATION_LAST) 1731 { 1732 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 1733 } 1734 1735 for (buf = units; *buf; buf++) 1736 /* Empty loop to move past the units string. */ ; 1737 1738 png_debug(3, "Allocating pCAL parameters array"); 1739 params = (png_charpp)png_malloc_warn(png_ptr, 1740 (png_uint_32)(nparams * png_sizeof(png_charp))) ; 1741 if (params == NULL) 1742 { 1743 png_free(png_ptr, png_ptr->chunkdata); 1744 png_ptr->chunkdata = NULL; 1745 png_warning(png_ptr, "No memory for pCAL params."); 1746 return; 1747 } 1748 1749 /* Get pointers to the start of each parameter string. */ 1750 for (i = 0; i < (int)nparams; i++) 1751 { 1752 buf++; /* Skip the null string terminator from previous parameter. */ 1753 1754 png_debug1(3, "Reading pCAL parameter %d", i); 1755 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) 1756 /* Empty loop to move past each parameter string */ ; 1757 1758 /* Make sure we haven't run out of data yet */ 1759 if (buf > endptr) 1760 { 1761 png_warning(png_ptr, "Invalid pCAL data"); 1762 png_free(png_ptr, png_ptr->chunkdata); 1763 png_ptr->chunkdata = NULL; 1764 png_free(png_ptr, params); 1765 return; 1766 } 1767 } 1768 1769 png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, 1770 units, params); 1771 1772 png_free(png_ptr, png_ptr->chunkdata); 1773 png_ptr->chunkdata = NULL; 1774 png_free(png_ptr, params); 1775 } 1776 #endif 1777 1778 #ifdef PNG_READ_sCAL_SUPPORTED 1779 /* Read the sCAL chunk */ 1780 void /* PRIVATE */ 1781 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1782 { 1783 png_charp ep; 1784 #ifdef PNG_FLOATING_POINT_SUPPORTED 1785 double width, height; 1786 png_charp vp; 1787 #else 1788 #ifdef PNG_FIXED_POINT_SUPPORTED 1789 png_charp swidth, sheight; 1790 #endif 1791 #endif 1792 png_size_t slength; 1793 1794 png_debug(1, "in png_handle_sCAL"); 1795 1796 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1797 png_error(png_ptr, "Missing IHDR before sCAL"); 1798 else if (png_ptr->mode & PNG_HAVE_IDAT) 1799 { 1800 png_warning(png_ptr, "Invalid sCAL after IDAT"); 1801 png_crc_finish(png_ptr, length); 1802 return; 1803 } 1804 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) 1805 { 1806 png_warning(png_ptr, "Duplicate sCAL chunk"); 1807 png_crc_finish(png_ptr, length); 1808 return; 1809 } 1810 1811 /* Need unit type, width, \0, height: minimum 4 bytes */ 1812 else if (length < 4) 1813 { 1814 png_warning(png_ptr, "sCAL chunk too short"); 1815 png_crc_finish(png_ptr, length); 1816 return; 1817 } 1818 1819 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)", 1820 length + 1); 1821 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1822 if (png_ptr->chunkdata == NULL) 1823 { 1824 png_warning(png_ptr, "Out of memory while processing sCAL chunk"); 1825 png_crc_finish(png_ptr, length); 1826 return; 1827 } 1828 slength = (png_size_t)length; 1829 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1830 1831 if (png_crc_finish(png_ptr, 0)) 1832 { 1833 png_free(png_ptr, png_ptr->chunkdata); 1834 png_ptr->chunkdata = NULL; 1835 return; 1836 } 1837 1838 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 1839 1840 ep = png_ptr->chunkdata + 1; /* Skip unit byte */ 1841 1842 #ifdef PNG_FLOATING_POINT_SUPPORTED 1843 width = png_strtod(png_ptr, ep, &vp); 1844 if (*vp) 1845 { 1846 png_warning(png_ptr, "malformed width string in sCAL chunk"); 1847 png_free(png_ptr, png_ptr->chunkdata); 1848 png_ptr->chunkdata = NULL; 1849 return; 1850 } 1851 #else 1852 #ifdef PNG_FIXED_POINT_SUPPORTED 1853 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1854 if (swidth == NULL) 1855 { 1856 png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); 1857 png_free(png_ptr, png_ptr->chunkdata); 1858 png_ptr->chunkdata = NULL; 1859 return; 1860 } 1861 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep) + 1); 1862 #endif 1863 #endif 1864 1865 for (ep = png_ptr->chunkdata + 1; *ep; ep++) 1866 /* Empty loop */ ; 1867 ep++; 1868 1869 if (png_ptr->chunkdata + slength < ep) 1870 { 1871 png_warning(png_ptr, "Truncated sCAL chunk"); 1872 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1873 png_free(png_ptr, swidth); 1874 #endif 1875 png_free(png_ptr, png_ptr->chunkdata); 1876 png_ptr->chunkdata = NULL; 1877 return; 1878 } 1879 1880 #ifdef PNG_FLOATING_POINT_SUPPORTED 1881 height = png_strtod(png_ptr, ep, &vp); 1882 if (*vp) 1883 { 1884 png_warning(png_ptr, "malformed height string in sCAL chunk"); 1885 png_free(png_ptr, png_ptr->chunkdata); 1886 png_ptr->chunkdata = NULL; 1887 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1888 png_free(png_ptr, swidth); 1889 #endif 1890 return; 1891 } 1892 #else 1893 #ifdef PNG_FIXED_POINT_SUPPORTED 1894 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1895 if (sheight == NULL) 1896 { 1897 png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); 1898 png_free(png_ptr, png_ptr->chunkdata); 1899 png_ptr->chunkdata = NULL; 1900 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1901 png_free(png_ptr, swidth); 1902 #endif 1903 return; 1904 } 1905 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep) + 1); 1906 #endif 1907 #endif 1908 1909 if (png_ptr->chunkdata + slength < ep 1910 #ifdef PNG_FLOATING_POINT_SUPPORTED 1911 || width <= 0. || height <= 0. 1912 #endif 1913 ) 1914 { 1915 png_warning(png_ptr, "Invalid sCAL data"); 1916 png_free(png_ptr, png_ptr->chunkdata); 1917 png_ptr->chunkdata = NULL; 1918 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1919 png_free(png_ptr, swidth); 1920 png_free(png_ptr, sheight); 1921 #endif 1922 return; 1923 } 1924 1925 1926 #ifdef PNG_FLOATING_POINT_SUPPORTED 1927 png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height); 1928 #else 1929 #ifdef PNG_FIXED_POINT_SUPPORTED 1930 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); 1931 #endif 1932 #endif 1933 1934 png_free(png_ptr, png_ptr->chunkdata); 1935 png_ptr->chunkdata = NULL; 1936 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1937 png_free(png_ptr, swidth); 1938 png_free(png_ptr, sheight); 1939 #endif 1940 } 1941 #endif 1942 1943 #ifdef PNG_READ_tIME_SUPPORTED 1944 void /* PRIVATE */ 1945 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1946 { 1947 png_byte buf[7]; 1948 png_time mod_time; 1949 1950 png_debug(1, "in png_handle_tIME"); 1951 1952 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1953 png_error(png_ptr, "Out of place tIME chunk"); 1954 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 1955 { 1956 png_warning(png_ptr, "Duplicate tIME chunk"); 1957 png_crc_finish(png_ptr, length); 1958 return; 1959 } 1960 1961 if (png_ptr->mode & PNG_HAVE_IDAT) 1962 png_ptr->mode |= PNG_AFTER_IDAT; 1963 1964 if (length != 7) 1965 { 1966 png_warning(png_ptr, "Incorrect tIME chunk length"); 1967 png_crc_finish(png_ptr, length); 1968 return; 1969 } 1970 1971 png_crc_read(png_ptr, buf, 7); 1972 if (png_crc_finish(png_ptr, 0)) 1973 return; 1974 1975 mod_time.second = buf[6]; 1976 mod_time.minute = buf[5]; 1977 mod_time.hour = buf[4]; 1978 mod_time.day = buf[3]; 1979 mod_time.month = buf[2]; 1980 mod_time.year = png_get_uint_16(buf); 1981 1982 png_set_tIME(png_ptr, info_ptr, &mod_time); 1983 } 1984 #endif 1985 1986 #ifdef PNG_READ_tEXt_SUPPORTED 1987 /* Note: this does not properly handle chunks that are > 64K under DOS */ 1988 void /* PRIVATE */ 1989 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1990 { 1991 png_textp text_ptr; 1992 png_charp key; 1993 png_charp text; 1994 png_uint_32 skip = 0; 1995 png_size_t slength; 1996 int ret; 1997 1998 png_debug(1, "in png_handle_tEXt"); 1999 2000 #ifdef PNG_USER_LIMITS_SUPPORTED 2001 if (png_ptr->user_chunk_cache_max != 0) 2002 { 2003 if (png_ptr->user_chunk_cache_max == 1) 2004 { 2005 png_crc_finish(png_ptr, length); 2006 return; 2007 } 2008 if (--png_ptr->user_chunk_cache_max == 1) 2009 { 2010 png_warning(png_ptr, "No space in chunk cache for tEXt"); 2011 png_crc_finish(png_ptr, length); 2012 return; 2013 } 2014 } 2015 #endif 2016 2017 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2018 png_error(png_ptr, "Missing IHDR before tEXt"); 2019 2020 if (png_ptr->mode & PNG_HAVE_IDAT) 2021 png_ptr->mode |= PNG_AFTER_IDAT; 2022 2023 #ifdef PNG_MAX_MALLOC_64K 2024 if (length > (png_uint_32)65535L) 2025 { 2026 png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 2027 skip = length - (png_uint_32)65535L; 2028 length = (png_uint_32)65535L; 2029 } 2030 #endif 2031 2032 png_free(png_ptr, png_ptr->chunkdata); 2033 2034 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2035 if (png_ptr->chunkdata == NULL) 2036 { 2037 png_warning(png_ptr, "No memory to process text chunk."); 2038 return; 2039 } 2040 slength = (png_size_t)length; 2041 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2042 2043 if (png_crc_finish(png_ptr, skip)) 2044 { 2045 png_free(png_ptr, png_ptr->chunkdata); 2046 png_ptr->chunkdata = NULL; 2047 return; 2048 } 2049 2050 key = png_ptr->chunkdata; 2051 2052 key[slength] = 0x00; 2053 2054 for (text = key; *text; text++) 2055 /* Empty loop to find end of key */ ; 2056 2057 if (text != key + slength) 2058 text++; 2059 2060 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2061 (png_uint_32)png_sizeof(png_text)); 2062 if (text_ptr == NULL) 2063 { 2064 png_warning(png_ptr, "Not enough memory to process text chunk."); 2065 png_free(png_ptr, png_ptr->chunkdata); 2066 png_ptr->chunkdata = NULL; 2067 return; 2068 } 2069 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 2070 text_ptr->key = key; 2071 #ifdef PNG_iTXt_SUPPORTED 2072 text_ptr->lang = NULL; 2073 text_ptr->lang_key = NULL; 2074 text_ptr->itxt_length = 0; 2075 #endif 2076 text_ptr->text = text; 2077 text_ptr->text_length = png_strlen(text); 2078 2079 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2080 2081 png_free(png_ptr, png_ptr->chunkdata); 2082 png_ptr->chunkdata = NULL; 2083 png_free(png_ptr, text_ptr); 2084 if (ret) 2085 png_warning(png_ptr, "Insufficient memory to process text chunk."); 2086 } 2087 #endif 2088 2089 #ifdef PNG_READ_zTXt_SUPPORTED 2090 /* Note: this does not correctly handle chunks that are > 64K under DOS */ 2091 void /* PRIVATE */ 2092 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2093 { 2094 png_textp text_ptr; 2095 png_charp text; 2096 int comp_type; 2097 int ret; 2098 png_size_t slength, prefix_len, data_len; 2099 2100 png_debug(1, "in png_handle_zTXt"); 2101 2102 #ifdef PNG_USER_LIMITS_SUPPORTED 2103 if (png_ptr->user_chunk_cache_max != 0) 2104 { 2105 if (png_ptr->user_chunk_cache_max == 1) 2106 { 2107 png_crc_finish(png_ptr, length); 2108 return; 2109 } 2110 if (--png_ptr->user_chunk_cache_max == 1) 2111 { 2112 png_warning(png_ptr, "No space in chunk cache for zTXt"); 2113 png_crc_finish(png_ptr, length); 2114 return; 2115 } 2116 } 2117 #endif 2118 2119 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2120 png_error(png_ptr, "Missing IHDR before zTXt"); 2121 2122 if (png_ptr->mode & PNG_HAVE_IDAT) 2123 png_ptr->mode |= PNG_AFTER_IDAT; 2124 2125 #ifdef PNG_MAX_MALLOC_64K 2126 /* We will no doubt have problems with chunks even half this size, but 2127 there is no hard and fast rule to tell us where to stop. */ 2128 if (length > (png_uint_32)65535L) 2129 { 2130 png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 2131 png_crc_finish(png_ptr, length); 2132 return; 2133 } 2134 #endif 2135 2136 png_free(png_ptr, png_ptr->chunkdata); 2137 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2138 if (png_ptr->chunkdata == NULL) 2139 { 2140 png_warning(png_ptr, "Out of memory processing zTXt chunk."); 2141 return; 2142 } 2143 slength = (png_size_t)length; 2144 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2145 if (png_crc_finish(png_ptr, 0)) 2146 { 2147 png_free(png_ptr, png_ptr->chunkdata); 2148 png_ptr->chunkdata = NULL; 2149 return; 2150 } 2151 2152 png_ptr->chunkdata[slength] = 0x00; 2153 2154 for (text = png_ptr->chunkdata; *text; text++) 2155 /* Empty loop */ ; 2156 2157 /* zTXt must have some text after the chunkdataword */ 2158 if (text >= png_ptr->chunkdata + slength - 2) 2159 { 2160 png_warning(png_ptr, "Truncated zTXt chunk"); 2161 png_free(png_ptr, png_ptr->chunkdata); 2162 png_ptr->chunkdata = NULL; 2163 return; 2164 } 2165 else 2166 { 2167 comp_type = *(++text); 2168 if (comp_type != PNG_TEXT_COMPRESSION_zTXt) 2169 { 2170 png_warning(png_ptr, "Unknown compression type in zTXt chunk"); 2171 comp_type = PNG_TEXT_COMPRESSION_zTXt; 2172 } 2173 text++; /* Skip the compression_method byte */ 2174 } 2175 prefix_len = text - png_ptr->chunkdata; 2176 2177 png_decompress_chunk(png_ptr, comp_type, 2178 (png_size_t)length, prefix_len, &data_len); 2179 2180 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2181 (png_uint_32)png_sizeof(png_text)); 2182 if (text_ptr == NULL) 2183 { 2184 png_warning(png_ptr, "Not enough memory to process zTXt chunk."); 2185 png_free(png_ptr, png_ptr->chunkdata); 2186 png_ptr->chunkdata = NULL; 2187 return; 2188 } 2189 text_ptr->compression = comp_type; 2190 text_ptr->key = png_ptr->chunkdata; 2191 #ifdef PNG_iTXt_SUPPORTED 2192 text_ptr->lang = NULL; 2193 text_ptr->lang_key = NULL; 2194 text_ptr->itxt_length = 0; 2195 #endif 2196 text_ptr->text = png_ptr->chunkdata + prefix_len; 2197 text_ptr->text_length = data_len; 2198 2199 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2200 2201 png_free(png_ptr, text_ptr); 2202 png_free(png_ptr, png_ptr->chunkdata); 2203 png_ptr->chunkdata = NULL; 2204 if (ret) 2205 png_error(png_ptr, "Insufficient memory to store zTXt chunk."); 2206 } 2207 #endif 2208 2209 #ifdef PNG_READ_iTXt_SUPPORTED 2210 /* Note: this does not correctly handle chunks that are > 64K under DOS */ 2211 void /* PRIVATE */ 2212 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2213 { 2214 png_textp text_ptr; 2215 png_charp key, lang, text, lang_key; 2216 int comp_flag; 2217 int comp_type = 0; 2218 int ret; 2219 png_size_t slength, prefix_len, data_len; 2220 2221 png_debug(1, "in png_handle_iTXt"); 2222 2223 #ifdef PNG_USER_LIMITS_SUPPORTED 2224 if (png_ptr->user_chunk_cache_max != 0) 2225 { 2226 if (png_ptr->user_chunk_cache_max == 1) 2227 { 2228 png_crc_finish(png_ptr, length); 2229 return; 2230 } 2231 if (--png_ptr->user_chunk_cache_max == 1) 2232 { 2233 png_warning(png_ptr, "No space in chunk cache for iTXt"); 2234 png_crc_finish(png_ptr, length); 2235 return; 2236 } 2237 } 2238 #endif 2239 2240 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2241 png_error(png_ptr, "Missing IHDR before iTXt"); 2242 2243 if (png_ptr->mode & PNG_HAVE_IDAT) 2244 png_ptr->mode |= PNG_AFTER_IDAT; 2245 2246 #ifdef PNG_MAX_MALLOC_64K 2247 /* We will no doubt have problems with chunks even half this size, but 2248 there is no hard and fast rule to tell us where to stop. */ 2249 if (length > (png_uint_32)65535L) 2250 { 2251 png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 2252 png_crc_finish(png_ptr, length); 2253 return; 2254 } 2255 #endif 2256 2257 png_free(png_ptr, png_ptr->chunkdata); 2258 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2259 if (png_ptr->chunkdata == NULL) 2260 { 2261 png_warning(png_ptr, "No memory to process iTXt chunk."); 2262 return; 2263 } 2264 slength = (png_size_t)length; 2265 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2266 if (png_crc_finish(png_ptr, 0)) 2267 { 2268 png_free(png_ptr, png_ptr->chunkdata); 2269 png_ptr->chunkdata = NULL; 2270 return; 2271 } 2272 2273 png_ptr->chunkdata[slength] = 0x00; 2274 2275 for (lang = png_ptr->chunkdata; *lang; lang++) 2276 /* Empty loop */ ; 2277 lang++; /* Skip NUL separator */ 2278 2279 /* iTXt must have a language tag (possibly empty), two compression bytes, 2280 * translated keyword (possibly empty), and possibly some text after the 2281 * keyword 2282 */ 2283 2284 if (lang >= png_ptr->chunkdata + slength - 3) 2285 { 2286 png_warning(png_ptr, "Truncated iTXt chunk"); 2287 png_free(png_ptr, png_ptr->chunkdata); 2288 png_ptr->chunkdata = NULL; 2289 return; 2290 } 2291 else 2292 { 2293 comp_flag = *lang++; 2294 comp_type = *lang++; 2295 } 2296 2297 for (lang_key = lang; *lang_key; lang_key++) 2298 /* Empty loop */ ; 2299 lang_key++; /* Skip NUL separator */ 2300 2301 if (lang_key >= png_ptr->chunkdata + slength) 2302 { 2303 png_warning(png_ptr, "Truncated iTXt chunk"); 2304 png_free(png_ptr, png_ptr->chunkdata); 2305 png_ptr->chunkdata = NULL; 2306 return; 2307 } 2308 2309 for (text = lang_key; *text; text++) 2310 /* Empty loop */ ; 2311 text++; /* Skip NUL separator */ 2312 if (text >= png_ptr->chunkdata + slength) 2313 { 2314 png_warning(png_ptr, "Malformed iTXt chunk"); 2315 png_free(png_ptr, png_ptr->chunkdata); 2316 png_ptr->chunkdata = NULL; 2317 return; 2318 } 2319 2320 prefix_len = text - png_ptr->chunkdata; 2321 2322 key=png_ptr->chunkdata; 2323 if (comp_flag) 2324 png_decompress_chunk(png_ptr, comp_type, 2325 (size_t)length, prefix_len, &data_len); 2326 else 2327 data_len = png_strlen(png_ptr->chunkdata + prefix_len); 2328 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2329 (png_uint_32)png_sizeof(png_text)); 2330 if (text_ptr == NULL) 2331 { 2332 png_warning(png_ptr, "Not enough memory to process iTXt chunk."); 2333 png_free(png_ptr, png_ptr->chunkdata); 2334 png_ptr->chunkdata = NULL; 2335 return; 2336 } 2337 text_ptr->compression = (int)comp_flag + 1; 2338 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); 2339 text_ptr->lang = png_ptr->chunkdata + (lang - key); 2340 text_ptr->itxt_length = data_len; 2341 text_ptr->text_length = 0; 2342 text_ptr->key = png_ptr->chunkdata; 2343 text_ptr->text = png_ptr->chunkdata + prefix_len; 2344 2345 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2346 2347 png_free(png_ptr, text_ptr); 2348 png_free(png_ptr, png_ptr->chunkdata); 2349 png_ptr->chunkdata = NULL; 2350 if (ret) 2351 png_error(png_ptr, "Insufficient memory to store iTXt chunk."); 2352 } 2353 #endif 2354 2355 /* This function is called when we haven't found a handler for a 2356 chunk. If there isn't a problem with the chunk itself (ie bad 2357 chunk name, CRC, or a critical chunk), the chunk is silently ignored 2358 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which 2359 case it will be saved away to be written out later. */ 2360 void /* PRIVATE */ 2361 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2362 { 2363 png_uint_32 skip = 0; 2364 2365 png_debug(1, "in png_handle_unknown"); 2366 2367 #ifdef PNG_USER_LIMITS_SUPPORTED 2368 if (png_ptr->user_chunk_cache_max != 0) 2369 { 2370 if (png_ptr->user_chunk_cache_max == 1) 2371 { 2372 png_crc_finish(png_ptr, length); 2373 return; 2374 } 2375 if (--png_ptr->user_chunk_cache_max == 1) 2376 { 2377 png_warning(png_ptr, "No space in chunk cache for unknown chunk"); 2378 png_crc_finish(png_ptr, length); 2379 return; 2380 } 2381 } 2382 #endif 2383 2384 if (png_ptr->mode & PNG_HAVE_IDAT) 2385 { 2386 #ifdef PNG_USE_LOCAL_ARRAYS 2387 PNG_CONST PNG_IDAT; 2388 #endif 2389 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ 2390 png_ptr->mode |= PNG_AFTER_IDAT; 2391 } 2392 2393 if (!(png_ptr->chunk_name[0] & 0x20)) 2394 { 2395 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 2396 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2397 PNG_HANDLE_CHUNK_ALWAYS 2398 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2399 && png_ptr->read_user_chunk_fn == NULL 2400 #endif 2401 ) 2402 #endif 2403 png_chunk_error(png_ptr, "unknown critical chunk"); 2404 } 2405 2406 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 2407 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) 2408 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2409 || (png_ptr->read_user_chunk_fn != NULL) 2410 #endif 2411 ) 2412 { 2413 #ifdef PNG_MAX_MALLOC_64K 2414 if (length > (png_uint_32)65535L) 2415 { 2416 png_warning(png_ptr, "unknown chunk too large to fit in memory"); 2417 skip = length - (png_uint_32)65535L; 2418 length = (png_uint_32)65535L; 2419 } 2420 #endif 2421 png_memcpy((png_charp)png_ptr->unknown_chunk.name, 2422 (png_charp)png_ptr->chunk_name, 2423 png_sizeof(png_ptr->unknown_chunk.name)); 2424 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] 2425 = '\0'; 2426 png_ptr->unknown_chunk.size = (png_size_t)length; 2427 if (length == 0) 2428 png_ptr->unknown_chunk.data = NULL; 2429 else 2430 { 2431 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); 2432 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 2433 } 2434 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2435 if (png_ptr->read_user_chunk_fn != NULL) 2436 { 2437 /* Callback to user unknown chunk handler */ 2438 int ret; 2439 ret = (*(png_ptr->read_user_chunk_fn)) 2440 (png_ptr, &png_ptr->unknown_chunk); 2441 if (ret < 0) 2442 png_chunk_error(png_ptr, "error in user chunk"); 2443 if (ret == 0) 2444 { 2445 if (!(png_ptr->chunk_name[0] & 0x20)) 2446 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 2447 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2448 PNG_HANDLE_CHUNK_ALWAYS) 2449 #endif 2450 png_chunk_error(png_ptr, "unknown critical chunk"); 2451 png_set_unknown_chunks(png_ptr, info_ptr, 2452 &png_ptr->unknown_chunk, 1); 2453 } 2454 } 2455 else 2456 #endif 2457 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 2458 png_free(png_ptr, png_ptr->unknown_chunk.data); 2459 png_ptr->unknown_chunk.data = NULL; 2460 } 2461 else 2462 #endif 2463 skip = length; 2464 2465 png_crc_finish(png_ptr, skip); 2466 2467 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED 2468 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ 2469 #endif 2470 } 2471 2472 /* This function is called to verify that a chunk name is valid. 2473 This function can't have the "critical chunk check" incorporated 2474 into it, since in the future we will need to be able to call user 2475 functions to handle unknown critical chunks after we check that 2476 the chunk name itself is valid. */ 2477 2478 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 2479 2480 void /* PRIVATE */ 2481 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) 2482 { 2483 png_debug(1, "in png_check_chunk_name"); 2484 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || 2485 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) 2486 { 2487 png_chunk_error(png_ptr, "invalid chunk type"); 2488 } 2489 } 2490 2491 /* Combines the row recently read in with the existing pixels in the 2492 row. This routine takes care of alpha and transparency if requested. 2493 This routine also handles the two methods of progressive display 2494 of interlaced images, depending on the mask value. 2495 The mask value describes which pixels are to be combined with 2496 the row. The pattern always repeats every 8 pixels, so just 8 2497 bits are needed. A one indicates the pixel is to be combined, 2498 a zero indicates the pixel is to be skipped. This is in addition 2499 to any alpha or transparency value associated with the pixel. If 2500 you want all pixels to be combined, pass 0xff (255) in mask. */ 2501 2502 void /* PRIVATE */ 2503 png_combine_row(png_structp png_ptr, png_bytep row, int mask) 2504 { 2505 png_debug(1, "in png_combine_row"); 2506 if (mask == 0xff) 2507 { 2508 png_memcpy(row, png_ptr->row_buf + 1, 2509 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); 2510 } 2511 else 2512 { 2513 switch (png_ptr->row_info.pixel_depth) 2514 { 2515 case 1: 2516 { 2517 png_bytep sp = png_ptr->row_buf + 1; 2518 png_bytep dp = row; 2519 int s_inc, s_start, s_end; 2520 int m = 0x80; 2521 int shift; 2522 png_uint_32 i; 2523 png_uint_32 row_width = png_ptr->width; 2524 2525 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2526 if (png_ptr->transformations & PNG_PACKSWAP) 2527 { 2528 s_start = 0; 2529 s_end = 7; 2530 s_inc = 1; 2531 } 2532 else 2533 #endif 2534 { 2535 s_start = 7; 2536 s_end = 0; 2537 s_inc = -1; 2538 } 2539 2540 shift = s_start; 2541 2542 for (i = 0; i < row_width; i++) 2543 { 2544 if (m & mask) 2545 { 2546 int value; 2547 2548 value = (*sp >> shift) & 0x01; 2549 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 2550 *dp |= (png_byte)(value << shift); 2551 } 2552 2553 if (shift == s_end) 2554 { 2555 shift = s_start; 2556 sp++; 2557 dp++; 2558 } 2559 else 2560 shift += s_inc; 2561 2562 if (m == 1) 2563 m = 0x80; 2564 else 2565 m >>= 1; 2566 } 2567 break; 2568 } 2569 case 2: 2570 { 2571 png_bytep sp = png_ptr->row_buf + 1; 2572 png_bytep dp = row; 2573 int s_start, s_end, s_inc; 2574 int m = 0x80; 2575 int shift; 2576 png_uint_32 i; 2577 png_uint_32 row_width = png_ptr->width; 2578 int value; 2579 2580 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2581 if (png_ptr->transformations & PNG_PACKSWAP) 2582 { 2583 s_start = 0; 2584 s_end = 6; 2585 s_inc = 2; 2586 } 2587 else 2588 #endif 2589 { 2590 s_start = 6; 2591 s_end = 0; 2592 s_inc = -2; 2593 } 2594 2595 shift = s_start; 2596 2597 for (i = 0; i < row_width; i++) 2598 { 2599 if (m & mask) 2600 { 2601 value = (*sp >> shift) & 0x03; 2602 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 2603 *dp |= (png_byte)(value << shift); 2604 } 2605 2606 if (shift == s_end) 2607 { 2608 shift = s_start; 2609 sp++; 2610 dp++; 2611 } 2612 else 2613 shift += s_inc; 2614 if (m == 1) 2615 m = 0x80; 2616 else 2617 m >>= 1; 2618 } 2619 break; 2620 } 2621 case 4: 2622 { 2623 png_bytep sp = png_ptr->row_buf + 1; 2624 png_bytep dp = row; 2625 int s_start, s_end, s_inc; 2626 int m = 0x80; 2627 int shift; 2628 png_uint_32 i; 2629 png_uint_32 row_width = png_ptr->width; 2630 int value; 2631 2632 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2633 if (png_ptr->transformations & PNG_PACKSWAP) 2634 { 2635 s_start = 0; 2636 s_end = 4; 2637 s_inc = 4; 2638 } 2639 else 2640 #endif 2641 { 2642 s_start = 4; 2643 s_end = 0; 2644 s_inc = -4; 2645 } 2646 shift = s_start; 2647 2648 for (i = 0; i < row_width; i++) 2649 { 2650 if (m & mask) 2651 { 2652 value = (*sp >> shift) & 0xf; 2653 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 2654 *dp |= (png_byte)(value << shift); 2655 } 2656 2657 if (shift == s_end) 2658 { 2659 shift = s_start; 2660 sp++; 2661 dp++; 2662 } 2663 else 2664 shift += s_inc; 2665 if (m == 1) 2666 m = 0x80; 2667 else 2668 m >>= 1; 2669 } 2670 break; 2671 } 2672 default: 2673 { 2674 png_bytep sp = png_ptr->row_buf + 1; 2675 png_bytep dp = row; 2676 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); 2677 png_uint_32 i; 2678 png_uint_32 row_width = png_ptr->width; 2679 png_byte m = 0x80; 2680 2681 2682 for (i = 0; i < row_width; i++) 2683 { 2684 if (m & mask) 2685 { 2686 png_memcpy(dp, sp, pixel_bytes); 2687 } 2688 2689 sp += pixel_bytes; 2690 dp += pixel_bytes; 2691 2692 if (m == 1) 2693 m = 0x80; 2694 else 2695 m >>= 1; 2696 } 2697 break; 2698 } 2699 } 2700 } 2701 } 2702 2703 #ifdef PNG_READ_INTERLACING_SUPPORTED 2704 /* OLD pre-1.0.9 interface: 2705 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 2706 png_uint_32 transformations) 2707 */ 2708 void /* PRIVATE */ 2709 png_do_read_interlace(png_structp png_ptr) 2710 { 2711 png_row_infop row_info = &(png_ptr->row_info); 2712 png_bytep row = png_ptr->row_buf + 1; 2713 int pass = png_ptr->pass; 2714 png_uint_32 transformations = png_ptr->transformations; 2715 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2716 /* Offset to next interlace block */ 2717 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2718 2719 png_debug(1, "in png_do_read_interlace"); 2720 if (row != NULL && row_info != NULL) 2721 { 2722 png_uint_32 final_width; 2723 2724 final_width = row_info->width * png_pass_inc[pass]; 2725 2726 switch (row_info->pixel_depth) 2727 { 2728 case 1: 2729 { 2730 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 2731 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 2732 int sshift, dshift; 2733 int s_start, s_end, s_inc; 2734 int jstop = png_pass_inc[pass]; 2735 png_byte v; 2736 png_uint_32 i; 2737 int j; 2738 2739 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2740 if (transformations & PNG_PACKSWAP) 2741 { 2742 sshift = (int)((row_info->width + 7) & 0x07); 2743 dshift = (int)((final_width + 7) & 0x07); 2744 s_start = 7; 2745 s_end = 0; 2746 s_inc = -1; 2747 } 2748 else 2749 #endif 2750 { 2751 sshift = 7 - (int)((row_info->width + 7) & 0x07); 2752 dshift = 7 - (int)((final_width + 7) & 0x07); 2753 s_start = 0; 2754 s_end = 7; 2755 s_inc = 1; 2756 } 2757 2758 for (i = 0; i < row_info->width; i++) 2759 { 2760 v = (png_byte)((*sp >> sshift) & 0x01); 2761 for (j = 0; j < jstop; j++) 2762 { 2763 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 2764 *dp |= (png_byte)(v << dshift); 2765 if (dshift == s_end) 2766 { 2767 dshift = s_start; 2768 dp--; 2769 } 2770 else 2771 dshift += s_inc; 2772 } 2773 if (sshift == s_end) 2774 { 2775 sshift = s_start; 2776 sp--; 2777 } 2778 else 2779 sshift += s_inc; 2780 } 2781 break; 2782 } 2783 case 2: 2784 { 2785 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 2786 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 2787 int sshift, dshift; 2788 int s_start, s_end, s_inc; 2789 int jstop = png_pass_inc[pass]; 2790 png_uint_32 i; 2791 2792 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2793 if (transformations & PNG_PACKSWAP) 2794 { 2795 sshift = (int)(((row_info->width + 3) & 0x03) << 1); 2796 dshift = (int)(((final_width + 3) & 0x03) << 1); 2797 s_start = 6; 2798 s_end = 0; 2799 s_inc = -2; 2800 } 2801 else 2802 #endif 2803 { 2804 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 2805 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 2806 s_start = 0; 2807 s_end = 6; 2808 s_inc = 2; 2809 } 2810 2811 for (i = 0; i < row_info->width; i++) 2812 { 2813 png_byte v; 2814 int j; 2815 2816 v = (png_byte)((*sp >> sshift) & 0x03); 2817 for (j = 0; j < jstop; j++) 2818 { 2819 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 2820 *dp |= (png_byte)(v << dshift); 2821 if (dshift == s_end) 2822 { 2823 dshift = s_start; 2824 dp--; 2825 } 2826 else 2827 dshift += s_inc; 2828 } 2829 if (sshift == s_end) 2830 { 2831 sshift = s_start; 2832 sp--; 2833 } 2834 else 2835 sshift += s_inc; 2836 } 2837 break; 2838 } 2839 case 4: 2840 { 2841 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 2842 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 2843 int sshift, dshift; 2844 int s_start, s_end, s_inc; 2845 png_uint_32 i; 2846 int jstop = png_pass_inc[pass]; 2847 2848 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2849 if (transformations & PNG_PACKSWAP) 2850 { 2851 sshift = (int)(((row_info->width + 1) & 0x01) << 2); 2852 dshift = (int)(((final_width + 1) & 0x01) << 2); 2853 s_start = 4; 2854 s_end = 0; 2855 s_inc = -4; 2856 } 2857 else 2858 #endif 2859 { 2860 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 2861 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 2862 s_start = 0; 2863 s_end = 4; 2864 s_inc = 4; 2865 } 2866 2867 for (i = 0; i < row_info->width; i++) 2868 { 2869 png_byte v = (png_byte)((*sp >> sshift) & 0xf); 2870 int j; 2871 2872 for (j = 0; j < jstop; j++) 2873 { 2874 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 2875 *dp |= (png_byte)(v << dshift); 2876 if (dshift == s_end) 2877 { 2878 dshift = s_start; 2879 dp--; 2880 } 2881 else 2882 dshift += s_inc; 2883 } 2884 if (sshift == s_end) 2885 { 2886 sshift = s_start; 2887 sp--; 2888 } 2889 else 2890 sshift += s_inc; 2891 } 2892 break; 2893 } 2894 default: 2895 { 2896 png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 2897 png_bytep sp = row + (png_size_t)(row_info->width - 1) 2898 * pixel_bytes; 2899 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 2900 2901 int jstop = png_pass_inc[pass]; 2902 png_uint_32 i; 2903 2904 for (i = 0; i < row_info->width; i++) 2905 { 2906 png_byte v[8]; 2907 int j; 2908 2909 png_memcpy(v, sp, pixel_bytes); 2910 for (j = 0; j < jstop; j++) 2911 { 2912 png_memcpy(dp, v, pixel_bytes); 2913 dp -= pixel_bytes; 2914 } 2915 sp -= pixel_bytes; 2916 } 2917 break; 2918 } 2919 } 2920 row_info->width = final_width; 2921 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); 2922 } 2923 #ifndef PNG_READ_PACKSWAP_SUPPORTED 2924 transformations = transformations; /* Silence compiler warning */ 2925 #endif 2926 } 2927 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 2928 2929 void /* PRIVATE */ 2930 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, 2931 png_bytep prev_row, int filter) 2932 { 2933 png_debug(1, "in png_read_filter_row"); 2934 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); 2935 switch (filter) 2936 { 2937 case PNG_FILTER_VALUE_NONE: 2938 break; 2939 case PNG_FILTER_VALUE_SUB: 2940 { 2941 png_uint_32 i; 2942 png_uint_32 istop = row_info->rowbytes; 2943 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 2944 png_bytep rp = row + bpp; 2945 png_bytep lp = row; 2946 2947 for (i = bpp; i < istop; i++) 2948 { 2949 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); 2950 rp++; 2951 } 2952 break; 2953 } 2954 case PNG_FILTER_VALUE_UP: 2955 { 2956 png_uint_32 i; 2957 png_uint_32 istop = row_info->rowbytes; 2958 png_bytep rp = row; 2959 png_bytep pp = prev_row; 2960 2961 for (i = 0; i < istop; i++) 2962 { 2963 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 2964 rp++; 2965 } 2966 break; 2967 } 2968 case PNG_FILTER_VALUE_AVG: 2969 { 2970 png_uint_32 i; 2971 png_bytep rp = row; 2972 png_bytep pp = prev_row; 2973 png_bytep lp = row; 2974 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 2975 png_uint_32 istop = row_info->rowbytes - bpp; 2976 2977 for (i = 0; i < bpp; i++) 2978 { 2979 *rp = (png_byte)(((int)(*rp) + 2980 ((int)(*pp++) / 2 )) & 0xff); 2981 rp++; 2982 } 2983 2984 for (i = 0; i < istop; i++) 2985 { 2986 *rp = (png_byte)(((int)(*rp) + 2987 (int)(*pp++ + *lp++) / 2 ) & 0xff); 2988 rp++; 2989 } 2990 break; 2991 } 2992 case PNG_FILTER_VALUE_PAETH: 2993 { 2994 png_uint_32 i; 2995 png_bytep rp = row; 2996 png_bytep pp = prev_row; 2997 png_bytep lp = row; 2998 png_bytep cp = prev_row; 2999 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3000 png_uint_32 istop=row_info->rowbytes - bpp; 3001 3002 for (i = 0; i < bpp; i++) 3003 { 3004 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3005 rp++; 3006 } 3007 3008 for (i = 0; i < istop; i++) /* Use leftover rp,pp */ 3009 { 3010 int a, b, c, pa, pb, pc, p; 3011 3012 a = *lp++; 3013 b = *pp++; 3014 c = *cp++; 3015 3016 p = b - c; 3017 pc = a - c; 3018 3019 #ifdef PNG_USE_ABS 3020 pa = abs(p); 3021 pb = abs(pc); 3022 pc = abs(p + pc); 3023 #else 3024 pa = p < 0 ? -p : p; 3025 pb = pc < 0 ? -pc : pc; 3026 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 3027 #endif 3028 3029 /* 3030 if (pa <= pb && pa <= pc) 3031 p = a; 3032 else if (pb <= pc) 3033 p = b; 3034 else 3035 p = c; 3036 */ 3037 3038 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; 3039 3040 *rp = (png_byte)(((int)(*rp) + p) & 0xff); 3041 rp++; 3042 } 3043 break; 3044 } 3045 default: 3046 png_warning(png_ptr, "Ignoring bad adaptive filter type"); 3047 *row = 0; 3048 break; 3049 } 3050 } 3051 3052 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 3053 void /* PRIVATE */ 3054 png_read_finish_row(png_structp png_ptr) 3055 { 3056 #ifdef PNG_READ_INTERLACING_SUPPORTED 3057 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3058 3059 /* Start of interlace block */ 3060 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3061 3062 /* Offset to next interlace block */ 3063 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3064 3065 /* Start of interlace block in the y direction */ 3066 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3067 3068 /* Offset to next interlace block in the y direction */ 3069 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3070 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3071 3072 png_debug(1, "in png_read_finish_row"); 3073 png_ptr->row_number++; 3074 if (png_ptr->row_number < png_ptr->num_rows) 3075 return; 3076 3077 #ifdef PNG_READ_INTERLACING_SUPPORTED 3078 if (png_ptr->interlaced) 3079 { 3080 png_ptr->row_number = 0; 3081 png_memset_check(png_ptr, png_ptr->prev_row, 0, 3082 png_ptr->rowbytes + 1); 3083 do 3084 { 3085 png_ptr->pass++; 3086 if (png_ptr->pass >= 7) 3087 break; 3088 png_ptr->iwidth = (png_ptr->width + 3089 png_pass_inc[png_ptr->pass] - 1 - 3090 png_pass_start[png_ptr->pass]) / 3091 png_pass_inc[png_ptr->pass]; 3092 3093 if (!(png_ptr->transformations & PNG_INTERLACE)) 3094 { 3095 png_ptr->num_rows = (png_ptr->height + 3096 png_pass_yinc[png_ptr->pass] - 1 - 3097 png_pass_ystart[png_ptr->pass]) / 3098 png_pass_yinc[png_ptr->pass]; 3099 if (!(png_ptr->num_rows)) 3100 continue; 3101 } 3102 else /* if (png_ptr->transformations & PNG_INTERLACE) */ 3103 break; 3104 } while (png_ptr->iwidth == 0); 3105 3106 if (png_ptr->pass < 7) 3107 return; 3108 } 3109 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3110 3111 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 3112 { 3113 #ifdef PNG_USE_LOCAL_ARRAYS 3114 PNG_CONST PNG_IDAT; 3115 #endif 3116 char extra; 3117 int ret; 3118 3119 png_ptr->zstream.next_out = (Byte *)&extra; 3120 png_ptr->zstream.avail_out = (uInt)1; 3121 for (;;) 3122 { 3123 if (!(png_ptr->zstream.avail_in)) 3124 { 3125 while (!png_ptr->idat_size) 3126 { 3127 png_byte chunk_length[4]; 3128 3129 png_crc_finish(png_ptr, 0); 3130 3131 png_read_data(png_ptr, chunk_length, 4); 3132 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); 3133 png_reset_crc(png_ptr); 3134 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 3135 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 3136 png_error(png_ptr, "Not enough image data"); 3137 3138 } 3139 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 3140 png_ptr->zstream.next_in = png_ptr->zbuf; 3141 if (png_ptr->zbuf_size > png_ptr->idat_size) 3142 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 3143 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); 3144 png_ptr->idat_size -= png_ptr->zstream.avail_in; 3145 } 3146 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 3147 if (ret == Z_STREAM_END) 3148 { 3149 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || 3150 png_ptr->idat_size) 3151 png_warning(png_ptr, "Extra compressed data."); 3152 png_ptr->mode |= PNG_AFTER_IDAT; 3153 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3154 break; 3155 } 3156 if (ret != Z_OK) 3157 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 3158 "Decompression Error"); 3159 3160 if (!(png_ptr->zstream.avail_out)) 3161 { 3162 png_warning(png_ptr, "Extra compressed data."); 3163 png_ptr->mode |= PNG_AFTER_IDAT; 3164 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3165 break; 3166 } 3167 3168 } 3169 png_ptr->zstream.avail_out = 0; 3170 } 3171 3172 if (png_ptr->idat_size || png_ptr->zstream.avail_in) 3173 png_warning(png_ptr, "Extra compression data."); 3174 3175 inflateReset(&png_ptr->zstream); 3176 3177 png_ptr->mode |= PNG_AFTER_IDAT; 3178 } 3179 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 3180 3181 void /* PRIVATE */ 3182 png_read_start_row(png_structp png_ptr) 3183 { 3184 #ifdef PNG_READ_INTERLACING_SUPPORTED 3185 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3186 3187 /* Start of interlace block */ 3188 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3189 3190 /* Offset to next interlace block */ 3191 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3192 3193 /* Start of interlace block in the y direction */ 3194 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3195 3196 /* Offset to next interlace block in the y direction */ 3197 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3198 #endif 3199 3200 int max_pixel_depth; 3201 png_size_t row_bytes; 3202 3203 png_debug(1, "in png_read_start_row"); 3204 png_ptr->zstream.avail_in = 0; 3205 png_init_read_transformations(png_ptr); 3206 #ifdef PNG_READ_INTERLACING_SUPPORTED 3207 if (png_ptr->interlaced) 3208 { 3209 if (!(png_ptr->transformations & PNG_INTERLACE)) 3210 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 3211 png_pass_ystart[0]) / png_pass_yinc[0]; 3212 else 3213 png_ptr->num_rows = png_ptr->height; 3214 3215 png_ptr->iwidth = (png_ptr->width + 3216 png_pass_inc[png_ptr->pass] - 1 - 3217 png_pass_start[png_ptr->pass]) / 3218 png_pass_inc[png_ptr->pass]; 3219 } 3220 else 3221 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3222 { 3223 png_ptr->num_rows = png_ptr->height; 3224 png_ptr->iwidth = png_ptr->width; 3225 } 3226 max_pixel_depth = png_ptr->pixel_depth; 3227 3228 #ifdef PNG_READ_PACK_SUPPORTED 3229 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 3230 max_pixel_depth = 8; 3231 #endif 3232 3233 #ifdef PNG_READ_EXPAND_SUPPORTED 3234 if (png_ptr->transformations & PNG_EXPAND) 3235 { 3236 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3237 { 3238 if (png_ptr->num_trans) 3239 max_pixel_depth = 32; 3240 else 3241 max_pixel_depth = 24; 3242 } 3243 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3244 { 3245 if (max_pixel_depth < 8) 3246 max_pixel_depth = 8; 3247 if (png_ptr->num_trans) 3248 max_pixel_depth *= 2; 3249 } 3250 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3251 { 3252 if (png_ptr->num_trans) 3253 { 3254 max_pixel_depth *= 4; 3255 max_pixel_depth /= 3; 3256 } 3257 } 3258 } 3259 #endif 3260 3261 #ifdef PNG_READ_FILLER_SUPPORTED 3262 if (png_ptr->transformations & (PNG_FILLER)) 3263 { 3264 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3265 max_pixel_depth = 32; 3266 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3267 { 3268 if (max_pixel_depth <= 8) 3269 max_pixel_depth = 16; 3270 else 3271 max_pixel_depth = 32; 3272 } 3273 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3274 { 3275 if (max_pixel_depth <= 32) 3276 max_pixel_depth = 32; 3277 else 3278 max_pixel_depth = 64; 3279 } 3280 } 3281 #endif 3282 3283 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 3284 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 3285 { 3286 if ( 3287 #ifdef PNG_READ_EXPAND_SUPPORTED 3288 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 3289 #endif 3290 #ifdef PNG_READ_FILLER_SUPPORTED 3291 (png_ptr->transformations & (PNG_FILLER)) || 3292 #endif 3293 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 3294 { 3295 if (max_pixel_depth <= 16) 3296 max_pixel_depth = 32; 3297 else 3298 max_pixel_depth = 64; 3299 } 3300 else 3301 { 3302 if (max_pixel_depth <= 8) 3303 { 3304 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3305 max_pixel_depth = 32; 3306 else 3307 max_pixel_depth = 24; 3308 } 3309 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3310 max_pixel_depth = 64; 3311 else 3312 max_pixel_depth = 48; 3313 } 3314 } 3315 #endif 3316 3317 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 3318 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 3319 if (png_ptr->transformations & PNG_USER_TRANSFORM) 3320 { 3321 int user_pixel_depth = png_ptr->user_transform_depth* 3322 png_ptr->user_transform_channels; 3323 if (user_pixel_depth > max_pixel_depth) 3324 max_pixel_depth=user_pixel_depth; 3325 } 3326 #endif 3327 3328 /* Align the width on the next larger 8 pixels. Mainly used 3329 * for interlacing 3330 */ 3331 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 3332 /* Calculate the maximum bytes needed, adding a byte and a pixel 3333 * for safety's sake 3334 */ 3335 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 3336 1 + ((max_pixel_depth + 7) >> 3); 3337 #ifdef PNG_MAX_MALLOC_64K 3338 if (row_bytes > (png_uint_32)65536L) 3339 png_error(png_ptr, "This image requires a row greater than 64KB"); 3340 #endif 3341 3342 if (row_bytes + 64 > png_ptr->old_big_row_buf_size) 3343 { 3344 png_free(png_ptr, png_ptr->big_row_buf); 3345 if (png_ptr->interlaced) 3346 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, 3347 row_bytes + 64); 3348 else 3349 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, 3350 row_bytes + 64); 3351 png_ptr->old_big_row_buf_size = row_bytes + 64; 3352 3353 /* Use 32 bytes of padding before and after row_buf. */ 3354 png_ptr->row_buf = png_ptr->big_row_buf + 32; 3355 png_ptr->old_big_row_buf_size = row_bytes + 64; 3356 } 3357 3358 #ifdef PNG_MAX_MALLOC_64K 3359 if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L) 3360 png_error(png_ptr, "This image requires a row greater than 64KB"); 3361 #endif 3362 if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1)) 3363 png_error(png_ptr, "Row has too many bytes to allocate in memory."); 3364 3365 if (row_bytes + 1 > png_ptr->old_prev_row_size) 3366 { 3367 png_free(png_ptr, png_ptr->prev_row); 3368 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( 3369 row_bytes + 1)); 3370 png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1); 3371 png_ptr->old_prev_row_size = row_bytes + 1; 3372 } 3373 3374 png_ptr->rowbytes = row_bytes; 3375 3376 png_debug1(3, "width = %lu,", png_ptr->width); 3377 png_debug1(3, "height = %lu,", png_ptr->height); 3378 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); 3379 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); 3380 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes); 3381 png_debug1(3, "irowbytes = %lu", 3382 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); 3383 3384 png_ptr->flags |= PNG_FLAG_ROW_INIT; 3385 } 3386 #endif /* PNG_READ_SUPPORTED */