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