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