1 2 /* pngrutil.c - utilities to read a PNG file 3 * 4 * Last changed in libpng 1.2.44 [June 26, 2010] 5 * Copyright (c) 1998-2010 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 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)", 1833 length + 1); 1834 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 1835 if (png_ptr->chunkdata == NULL) 1836 { 1837 png_warning(png_ptr, "Out of memory while processing sCAL chunk"); 1838 png_crc_finish(png_ptr, length); 1839 return; 1840 } 1841 slength = (png_size_t)length; 1842 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1843 1844 if (png_crc_finish(png_ptr, 0)) 1845 { 1846 png_free(png_ptr, png_ptr->chunkdata); 1847 png_ptr->chunkdata = NULL; 1848 return; 1849 } 1850 1851 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 1852 1853 ep = png_ptr->chunkdata + 1; /* Skip unit byte */ 1854 1855 #ifdef PNG_FLOATING_POINT_SUPPORTED 1856 width = png_strtod(png_ptr, ep, &vp); 1857 if (*vp) 1858 { 1859 png_warning(png_ptr, "malformed width string in sCAL chunk"); 1860 png_free(png_ptr, png_ptr->chunkdata); 1861 png_ptr->chunkdata = NULL; 1862 return; 1863 } 1864 #else 1865 #ifdef PNG_FIXED_POINT_SUPPORTED 1866 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1867 if (swidth == NULL) 1868 { 1869 png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); 1870 png_free(png_ptr, png_ptr->chunkdata); 1871 png_ptr->chunkdata = NULL; 1872 return; 1873 } 1874 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); 1875 #endif 1876 #endif 1877 1878 for (ep = png_ptr->chunkdata; *ep; ep++) 1879 /* Empty loop */ ; 1880 ep++; 1881 1882 if (png_ptr->chunkdata + slength < ep) 1883 { 1884 png_warning(png_ptr, "Truncated sCAL chunk"); 1885 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1886 png_free(png_ptr, swidth); 1887 #endif 1888 png_free(png_ptr, png_ptr->chunkdata); 1889 png_ptr->chunkdata = NULL; 1890 return; 1891 } 1892 1893 #ifdef PNG_FLOATING_POINT_SUPPORTED 1894 height = png_strtod(png_ptr, ep, &vp); 1895 if (*vp) 1896 { 1897 png_warning(png_ptr, "malformed height string in sCAL chunk"); 1898 png_free(png_ptr, png_ptr->chunkdata); 1899 png_ptr->chunkdata = NULL; 1900 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1901 png_free(png_ptr, swidth); 1902 #endif 1903 return; 1904 } 1905 #else 1906 #ifdef PNG_FIXED_POINT_SUPPORTED 1907 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1908 if (sheight == NULL) 1909 { 1910 png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); 1911 png_free(png_ptr, png_ptr->chunkdata); 1912 png_ptr->chunkdata = NULL; 1913 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1914 png_free(png_ptr, swidth); 1915 #endif 1916 return; 1917 } 1918 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); 1919 #endif 1920 #endif 1921 1922 if (png_ptr->chunkdata + slength < ep 1923 #ifdef PNG_FLOATING_POINT_SUPPORTED 1924 || width <= 0. || height <= 0. 1925 #endif 1926 ) 1927 { 1928 png_warning(png_ptr, "Invalid sCAL data"); 1929 png_free(png_ptr, png_ptr->chunkdata); 1930 png_ptr->chunkdata = NULL; 1931 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1932 png_free(png_ptr, swidth); 1933 png_free(png_ptr, sheight); 1934 #endif 1935 return; 1936 } 1937 1938 1939 #ifdef PNG_FLOATING_POINT_SUPPORTED 1940 png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height); 1941 #else 1942 #ifdef PNG_FIXED_POINT_SUPPORTED 1943 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); 1944 #endif 1945 #endif 1946 1947 png_free(png_ptr, png_ptr->chunkdata); 1948 png_ptr->chunkdata = NULL; 1949 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1950 png_free(png_ptr, swidth); 1951 png_free(png_ptr, sheight); 1952 #endif 1953 } 1954 #endif 1955 1956 #ifdef PNG_READ_tIME_SUPPORTED 1957 void /* PRIVATE */ 1958 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1959 { 1960 png_byte buf[7]; 1961 png_time mod_time; 1962 1963 png_debug(1, "in png_handle_tIME"); 1964 1965 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1966 png_error(png_ptr, "Out of place tIME chunk"); 1967 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 1968 { 1969 png_warning(png_ptr, "Duplicate tIME chunk"); 1970 png_crc_finish(png_ptr, length); 1971 return; 1972 } 1973 1974 if (png_ptr->mode & PNG_HAVE_IDAT) 1975 png_ptr->mode |= PNG_AFTER_IDAT; 1976 1977 if (length != 7) 1978 { 1979 png_warning(png_ptr, "Incorrect tIME chunk length"); 1980 png_crc_finish(png_ptr, length); 1981 return; 1982 } 1983 1984 png_crc_read(png_ptr, buf, 7); 1985 if (png_crc_finish(png_ptr, 0)) 1986 return; 1987 1988 mod_time.second = buf[6]; 1989 mod_time.minute = buf[5]; 1990 mod_time.hour = buf[4]; 1991 mod_time.day = buf[3]; 1992 mod_time.month = buf[2]; 1993 mod_time.year = png_get_uint_16(buf); 1994 1995 png_set_tIME(png_ptr, info_ptr, &mod_time); 1996 } 1997 #endif 1998 1999 #ifdef PNG_READ_tEXt_SUPPORTED 2000 /* Note: this does not properly handle chunks that are > 64K under DOS */ 2001 void /* PRIVATE */ 2002 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2003 { 2004 png_textp text_ptr; 2005 png_charp key; 2006 png_charp text; 2007 png_uint_32 skip = 0; 2008 png_size_t slength; 2009 int ret; 2010 2011 png_debug(1, "in png_handle_tEXt"); 2012 2013 #ifdef PNG_USER_LIMITS_SUPPORTED 2014 if (png_ptr->user_chunk_cache_max != 0) 2015 { 2016 if (png_ptr->user_chunk_cache_max == 1) 2017 { 2018 png_crc_finish(png_ptr, length); 2019 return; 2020 } 2021 if (--png_ptr->user_chunk_cache_max == 1) 2022 { 2023 png_warning(png_ptr, "No space in chunk cache for tEXt"); 2024 png_crc_finish(png_ptr, length); 2025 return; 2026 } 2027 } 2028 #endif 2029 2030 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2031 png_error(png_ptr, "Missing IHDR before tEXt"); 2032 2033 if (png_ptr->mode & PNG_HAVE_IDAT) 2034 png_ptr->mode |= PNG_AFTER_IDAT; 2035 2036 #ifdef PNG_MAX_MALLOC_64K 2037 if (length > (png_uint_32)65535L) 2038 { 2039 png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 2040 skip = length - (png_uint_32)65535L; 2041 length = (png_uint_32)65535L; 2042 } 2043 #endif 2044 2045 png_free(png_ptr, png_ptr->chunkdata); 2046 2047 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2048 if (png_ptr->chunkdata == NULL) 2049 { 2050 png_warning(png_ptr, "No memory to process text chunk."); 2051 return; 2052 } 2053 slength = (png_size_t)length; 2054 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2055 2056 if (png_crc_finish(png_ptr, skip)) 2057 { 2058 png_free(png_ptr, png_ptr->chunkdata); 2059 png_ptr->chunkdata = NULL; 2060 return; 2061 } 2062 2063 key = png_ptr->chunkdata; 2064 2065 key[slength] = 0x00; 2066 2067 for (text = key; *text; text++) 2068 /* Empty loop to find end of key */ ; 2069 2070 if (text != key + slength) 2071 text++; 2072 2073 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2074 (png_uint_32)png_sizeof(png_text)); 2075 if (text_ptr == NULL) 2076 { 2077 png_warning(png_ptr, "Not enough memory to process text chunk."); 2078 png_free(png_ptr, png_ptr->chunkdata); 2079 png_ptr->chunkdata = NULL; 2080 return; 2081 } 2082 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 2083 text_ptr->key = key; 2084 #ifdef PNG_iTXt_SUPPORTED 2085 text_ptr->lang = NULL; 2086 text_ptr->lang_key = NULL; 2087 text_ptr->itxt_length = 0; 2088 #endif 2089 text_ptr->text = text; 2090 text_ptr->text_length = png_strlen(text); 2091 2092 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2093 2094 png_free(png_ptr, png_ptr->chunkdata); 2095 png_ptr->chunkdata = NULL; 2096 png_free(png_ptr, text_ptr); 2097 if (ret) 2098 png_warning(png_ptr, "Insufficient memory to process text chunk."); 2099 } 2100 #endif 2101 2102 #ifdef PNG_READ_zTXt_SUPPORTED 2103 /* Note: this does not correctly handle chunks that are > 64K under DOS */ 2104 void /* PRIVATE */ 2105 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2106 { 2107 png_textp text_ptr; 2108 png_charp text; 2109 int comp_type; 2110 int ret; 2111 png_size_t slength, prefix_len, data_len; 2112 2113 png_debug(1, "in png_handle_zTXt"); 2114 2115 #ifdef PNG_USER_LIMITS_SUPPORTED 2116 if (png_ptr->user_chunk_cache_max != 0) 2117 { 2118 if (png_ptr->user_chunk_cache_max == 1) 2119 { 2120 png_crc_finish(png_ptr, length); 2121 return; 2122 } 2123 if (--png_ptr->user_chunk_cache_max == 1) 2124 { 2125 png_warning(png_ptr, "No space in chunk cache for zTXt"); 2126 png_crc_finish(png_ptr, length); 2127 return; 2128 } 2129 } 2130 #endif 2131 2132 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2133 png_error(png_ptr, "Missing IHDR before zTXt"); 2134 2135 if (png_ptr->mode & PNG_HAVE_IDAT) 2136 png_ptr->mode |= PNG_AFTER_IDAT; 2137 2138 #ifdef PNG_MAX_MALLOC_64K 2139 /* We will no doubt have problems with chunks even half this size, but 2140 there is no hard and fast rule to tell us where to stop. */ 2141 if (length > (png_uint_32)65535L) 2142 { 2143 png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 2144 png_crc_finish(png_ptr, length); 2145 return; 2146 } 2147 #endif 2148 2149 png_free(png_ptr, png_ptr->chunkdata); 2150 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2151 if (png_ptr->chunkdata == NULL) 2152 { 2153 png_warning(png_ptr, "Out of memory processing zTXt chunk."); 2154 return; 2155 } 2156 slength = (png_size_t)length; 2157 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2158 if (png_crc_finish(png_ptr, 0)) 2159 { 2160 png_free(png_ptr, png_ptr->chunkdata); 2161 png_ptr->chunkdata = NULL; 2162 return; 2163 } 2164 2165 png_ptr->chunkdata[slength] = 0x00; 2166 2167 for (text = png_ptr->chunkdata; *text; text++) 2168 /* Empty loop */ ; 2169 2170 /* zTXt must have some text after the chunkdataword */ 2171 if (text >= png_ptr->chunkdata + slength - 2) 2172 { 2173 png_warning(png_ptr, "Truncated zTXt chunk"); 2174 png_free(png_ptr, png_ptr->chunkdata); 2175 png_ptr->chunkdata = NULL; 2176 return; 2177 } 2178 else 2179 { 2180 comp_type = *(++text); 2181 if (comp_type != PNG_TEXT_COMPRESSION_zTXt) 2182 { 2183 png_warning(png_ptr, "Unknown compression type in zTXt chunk"); 2184 comp_type = PNG_TEXT_COMPRESSION_zTXt; 2185 } 2186 text++; /* Skip the compression_method byte */ 2187 } 2188 prefix_len = text - png_ptr->chunkdata; 2189 2190 png_decompress_chunk(png_ptr, comp_type, 2191 (png_size_t)length, prefix_len, &data_len); 2192 2193 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2194 (png_uint_32)png_sizeof(png_text)); 2195 if (text_ptr == NULL) 2196 { 2197 png_warning(png_ptr, "Not enough memory to process zTXt chunk."); 2198 png_free(png_ptr, png_ptr->chunkdata); 2199 png_ptr->chunkdata = NULL; 2200 return; 2201 } 2202 text_ptr->compression = comp_type; 2203 text_ptr->key = png_ptr->chunkdata; 2204 #ifdef PNG_iTXt_SUPPORTED 2205 text_ptr->lang = NULL; 2206 text_ptr->lang_key = NULL; 2207 text_ptr->itxt_length = 0; 2208 #endif 2209 text_ptr->text = png_ptr->chunkdata + prefix_len; 2210 text_ptr->text_length = data_len; 2211 2212 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2213 2214 png_free(png_ptr, text_ptr); 2215 png_free(png_ptr, png_ptr->chunkdata); 2216 png_ptr->chunkdata = NULL; 2217 if (ret) 2218 png_error(png_ptr, "Insufficient memory to store zTXt chunk."); 2219 } 2220 #endif 2221 2222 #ifdef PNG_READ_iTXt_SUPPORTED 2223 /* Note: this does not correctly handle chunks that are > 64K under DOS */ 2224 void /* PRIVATE */ 2225 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2226 { 2227 png_textp text_ptr; 2228 png_charp key, lang, text, lang_key; 2229 int comp_flag; 2230 int comp_type = 0; 2231 int ret; 2232 png_size_t slength, prefix_len, data_len; 2233 2234 png_debug(1, "in png_handle_iTXt"); 2235 2236 #ifdef PNG_USER_LIMITS_SUPPORTED 2237 if (png_ptr->user_chunk_cache_max != 0) 2238 { 2239 if (png_ptr->user_chunk_cache_max == 1) 2240 { 2241 png_crc_finish(png_ptr, length); 2242 return; 2243 } 2244 if (--png_ptr->user_chunk_cache_max == 1) 2245 { 2246 png_warning(png_ptr, "No space in chunk cache for iTXt"); 2247 png_crc_finish(png_ptr, length); 2248 return; 2249 } 2250 } 2251 #endif 2252 2253 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2254 png_error(png_ptr, "Missing IHDR before iTXt"); 2255 2256 if (png_ptr->mode & PNG_HAVE_IDAT) 2257 png_ptr->mode |= PNG_AFTER_IDAT; 2258 2259 #ifdef PNG_MAX_MALLOC_64K 2260 /* We will no doubt have problems with chunks even half this size, but 2261 there is no hard and fast rule to tell us where to stop. */ 2262 if (length > (png_uint_32)65535L) 2263 { 2264 png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 2265 png_crc_finish(png_ptr, length); 2266 return; 2267 } 2268 #endif 2269 2270 png_free(png_ptr, png_ptr->chunkdata); 2271 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 2272 if (png_ptr->chunkdata == NULL) 2273 { 2274 png_warning(png_ptr, "No memory to process iTXt chunk."); 2275 return; 2276 } 2277 slength = (png_size_t)length; 2278 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2279 if (png_crc_finish(png_ptr, 0)) 2280 { 2281 png_free(png_ptr, png_ptr->chunkdata); 2282 png_ptr->chunkdata = NULL; 2283 return; 2284 } 2285 2286 png_ptr->chunkdata[slength] = 0x00; 2287 2288 for (lang = png_ptr->chunkdata; *lang; lang++) 2289 /* Empty loop */ ; 2290 lang++; /* Skip NUL separator */ 2291 2292 /* iTXt must have a language tag (possibly empty), two compression bytes, 2293 * translated keyword (possibly empty), and possibly some text after the 2294 * keyword 2295 */ 2296 2297 if (lang >= png_ptr->chunkdata + slength - 3) 2298 { 2299 png_warning(png_ptr, "Truncated iTXt chunk"); 2300 png_free(png_ptr, png_ptr->chunkdata); 2301 png_ptr->chunkdata = NULL; 2302 return; 2303 } 2304 else 2305 { 2306 comp_flag = *lang++; 2307 comp_type = *lang++; 2308 } 2309 2310 for (lang_key = lang; *lang_key; lang_key++) 2311 /* Empty loop */ ; 2312 lang_key++; /* Skip NUL separator */ 2313 2314 if (lang_key >= png_ptr->chunkdata + slength) 2315 { 2316 png_warning(png_ptr, "Truncated iTXt chunk"); 2317 png_free(png_ptr, png_ptr->chunkdata); 2318 png_ptr->chunkdata = NULL; 2319 return; 2320 } 2321 2322 for (text = lang_key; *text; text++) 2323 /* Empty loop */ ; 2324 text++; /* Skip NUL separator */ 2325 if (text >= png_ptr->chunkdata + slength) 2326 { 2327 png_warning(png_ptr, "Malformed iTXt chunk"); 2328 png_free(png_ptr, png_ptr->chunkdata); 2329 png_ptr->chunkdata = NULL; 2330 return; 2331 } 2332 2333 prefix_len = text - png_ptr->chunkdata; 2334 2335 key=png_ptr->chunkdata; 2336 if (comp_flag) 2337 png_decompress_chunk(png_ptr, comp_type, 2338 (size_t)length, prefix_len, &data_len); 2339 else 2340 data_len = png_strlen(png_ptr->chunkdata + prefix_len); 2341 text_ptr = (png_textp)png_malloc_warn(png_ptr, 2342 (png_uint_32)png_sizeof(png_text)); 2343 if (text_ptr == NULL) 2344 { 2345 png_warning(png_ptr, "Not enough memory to process iTXt chunk."); 2346 png_free(png_ptr, png_ptr->chunkdata); 2347 png_ptr->chunkdata = NULL; 2348 return; 2349 } 2350 text_ptr->compression = (int)comp_flag + 1; 2351 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); 2352 text_ptr->lang = png_ptr->chunkdata + (lang - key); 2353 text_ptr->itxt_length = data_len; 2354 text_ptr->text_length = 0; 2355 text_ptr->key = png_ptr->chunkdata; 2356 text_ptr->text = png_ptr->chunkdata + prefix_len; 2357 2358 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2359 2360 png_free(png_ptr, text_ptr); 2361 png_free(png_ptr, png_ptr->chunkdata); 2362 png_ptr->chunkdata = NULL; 2363 if (ret) 2364 png_error(png_ptr, "Insufficient memory to store iTXt chunk."); 2365 } 2366 #endif 2367 2368 /* This function is called when we haven't found a handler for a 2369 chunk. If there isn't a problem with the chunk itself (ie bad 2370 chunk name, CRC, or a critical chunk), the chunk is silently ignored 2371 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which 2372 case it will be saved away to be written out later. */ 2373 void /* PRIVATE */ 2374 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2375 { 2376 png_uint_32 skip = 0; 2377 2378 png_debug(1, "in png_handle_unknown"); 2379 2380 #ifdef PNG_USER_LIMITS_SUPPORTED 2381 if (png_ptr->user_chunk_cache_max != 0) 2382 { 2383 if (png_ptr->user_chunk_cache_max == 1) 2384 { 2385 png_crc_finish(png_ptr, length); 2386 return; 2387 } 2388 if (--png_ptr->user_chunk_cache_max == 1) 2389 { 2390 png_warning(png_ptr, "No space in chunk cache for unknown chunk"); 2391 png_crc_finish(png_ptr, length); 2392 return; 2393 } 2394 } 2395 #endif 2396 2397 if (png_ptr->mode & PNG_HAVE_IDAT) 2398 { 2399 #ifdef PNG_USE_LOCAL_ARRAYS 2400 PNG_CONST PNG_IDAT; 2401 #endif 2402 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ 2403 png_ptr->mode |= PNG_AFTER_IDAT; 2404 } 2405 2406 if (!(png_ptr->chunk_name[0] & 0x20)) 2407 { 2408 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 2409 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2410 PNG_HANDLE_CHUNK_ALWAYS 2411 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2412 && png_ptr->read_user_chunk_fn == NULL 2413 #endif 2414 ) 2415 #endif 2416 png_chunk_error(png_ptr, "unknown critical chunk"); 2417 } 2418 2419 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 2420 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) 2421 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2422 || (png_ptr->read_user_chunk_fn != NULL) 2423 #endif 2424 ) 2425 { 2426 #ifdef PNG_MAX_MALLOC_64K 2427 if (length > (png_uint_32)65535L) 2428 { 2429 png_warning(png_ptr, "unknown chunk too large to fit in memory"); 2430 skip = length - (png_uint_32)65535L; 2431 length = (png_uint_32)65535L; 2432 } 2433 #endif 2434 png_memcpy((png_charp)png_ptr->unknown_chunk.name, 2435 (png_charp)png_ptr->chunk_name, 2436 png_sizeof(png_ptr->unknown_chunk.name)); 2437 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] 2438 = '\0'; 2439 png_ptr->unknown_chunk.size = (png_size_t)length; 2440 if (length == 0) 2441 png_ptr->unknown_chunk.data = NULL; 2442 else 2443 { 2444 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); 2445 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 2446 } 2447 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2448 if (png_ptr->read_user_chunk_fn != NULL) 2449 { 2450 /* Callback to user unknown chunk handler */ 2451 int ret; 2452 ret = (*(png_ptr->read_user_chunk_fn)) 2453 (png_ptr, &png_ptr->unknown_chunk); 2454 if (ret < 0) 2455 png_chunk_error(png_ptr, "error in user chunk"); 2456 if (ret == 0) 2457 { 2458 if (!(png_ptr->chunk_name[0] & 0x20)) 2459 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 2460 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2461 PNG_HANDLE_CHUNK_ALWAYS) 2462 #endif 2463 png_chunk_error(png_ptr, "unknown critical chunk"); 2464 png_set_unknown_chunks(png_ptr, info_ptr, 2465 &png_ptr->unknown_chunk, 1); 2466 } 2467 } 2468 else 2469 #endif 2470 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 2471 png_free(png_ptr, png_ptr->unknown_chunk.data); 2472 png_ptr->unknown_chunk.data = NULL; 2473 } 2474 else 2475 #endif 2476 skip = length; 2477 2478 png_crc_finish(png_ptr, skip); 2479 2480 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED 2481 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ 2482 #endif 2483 } 2484 2485 /* This function is called to verify that a chunk name is valid. 2486 This function can't have the "critical chunk check" incorporated 2487 into it, since in the future we will need to be able to call user 2488 functions to handle unknown critical chunks after we check that 2489 the chunk name itself is valid. */ 2490 2491 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 2492 2493 void /* PRIVATE */ 2494 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) 2495 { 2496 png_debug(1, "in png_check_chunk_name"); 2497 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || 2498 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) 2499 { 2500 png_chunk_error(png_ptr, "invalid chunk type"); 2501 } 2502 } 2503 2504 /* Combines the row recently read in with the existing pixels in the 2505 row. This routine takes care of alpha and transparency if requested. 2506 This routine also handles the two methods of progressive display 2507 of interlaced images, depending on the mask value. 2508 The mask value describes which pixels are to be combined with 2509 the row. The pattern always repeats every 8 pixels, so just 8 2510 bits are needed. A one indicates the pixel is to be combined, 2511 a zero indicates the pixel is to be skipped. This is in addition 2512 to any alpha or transparency value associated with the pixel. If 2513 you want all pixels to be combined, pass 0xff (255) in mask. */ 2514 2515 void /* PRIVATE */ 2516 png_combine_row(png_structp png_ptr, png_bytep row, int mask) 2517 { 2518 png_debug(1, "in png_combine_row"); 2519 if (mask == 0xff) 2520 { 2521 png_memcpy(row, png_ptr->row_buf + 1, 2522 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); 2523 } 2524 else 2525 { 2526 switch (png_ptr->row_info.pixel_depth) 2527 { 2528 case 1: 2529 { 2530 png_bytep sp = png_ptr->row_buf + 1; 2531 png_bytep dp = row; 2532 int s_inc, s_start, s_end; 2533 int m = 0x80; 2534 int shift; 2535 png_uint_32 i; 2536 png_uint_32 row_width = png_ptr->width; 2537 2538 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2539 if (png_ptr->transformations & PNG_PACKSWAP) 2540 { 2541 s_start = 0; 2542 s_end = 7; 2543 s_inc = 1; 2544 } 2545 else 2546 #endif 2547 { 2548 s_start = 7; 2549 s_end = 0; 2550 s_inc = -1; 2551 } 2552 2553 shift = s_start; 2554 2555 for (i = 0; i < row_width; i++) 2556 { 2557 if (m & mask) 2558 { 2559 int value; 2560 2561 value = (*sp >> shift) & 0x01; 2562 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 2563 *dp |= (png_byte)(value << shift); 2564 } 2565 2566 if (shift == s_end) 2567 { 2568 shift = s_start; 2569 sp++; 2570 dp++; 2571 } 2572 else 2573 shift += s_inc; 2574 2575 if (m == 1) 2576 m = 0x80; 2577 else 2578 m >>= 1; 2579 } 2580 break; 2581 } 2582 case 2: 2583 { 2584 png_bytep sp = png_ptr->row_buf + 1; 2585 png_bytep dp = row; 2586 int s_start, s_end, s_inc; 2587 int m = 0x80; 2588 int shift; 2589 png_uint_32 i; 2590 png_uint_32 row_width = png_ptr->width; 2591 int value; 2592 2593 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2594 if (png_ptr->transformations & PNG_PACKSWAP) 2595 { 2596 s_start = 0; 2597 s_end = 6; 2598 s_inc = 2; 2599 } 2600 else 2601 #endif 2602 { 2603 s_start = 6; 2604 s_end = 0; 2605 s_inc = -2; 2606 } 2607 2608 shift = s_start; 2609 2610 for (i = 0; i < row_width; i++) 2611 { 2612 if (m & mask) 2613 { 2614 value = (*sp >> shift) & 0x03; 2615 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 2616 *dp |= (png_byte)(value << shift); 2617 } 2618 2619 if (shift == s_end) 2620 { 2621 shift = s_start; 2622 sp++; 2623 dp++; 2624 } 2625 else 2626 shift += s_inc; 2627 if (m == 1) 2628 m = 0x80; 2629 else 2630 m >>= 1; 2631 } 2632 break; 2633 } 2634 case 4: 2635 { 2636 png_bytep sp = png_ptr->row_buf + 1; 2637 png_bytep dp = row; 2638 int s_start, s_end, s_inc; 2639 int m = 0x80; 2640 int shift; 2641 png_uint_32 i; 2642 png_uint_32 row_width = png_ptr->width; 2643 int value; 2644 2645 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2646 if (png_ptr->transformations & PNG_PACKSWAP) 2647 { 2648 s_start = 0; 2649 s_end = 4; 2650 s_inc = 4; 2651 } 2652 else 2653 #endif 2654 { 2655 s_start = 4; 2656 s_end = 0; 2657 s_inc = -4; 2658 } 2659 shift = s_start; 2660 2661 for (i = 0; i < row_width; i++) 2662 { 2663 if (m & mask) 2664 { 2665 value = (*sp >> shift) & 0xf; 2666 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 2667 *dp |= (png_byte)(value << shift); 2668 } 2669 2670 if (shift == s_end) 2671 { 2672 shift = s_start; 2673 sp++; 2674 dp++; 2675 } 2676 else 2677 shift += s_inc; 2678 if (m == 1) 2679 m = 0x80; 2680 else 2681 m >>= 1; 2682 } 2683 break; 2684 } 2685 default: 2686 { 2687 png_bytep sp = png_ptr->row_buf + 1; 2688 png_bytep dp = row; 2689 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); 2690 png_uint_32 i; 2691 png_uint_32 row_width = png_ptr->width; 2692 png_byte m = 0x80; 2693 2694 2695 for (i = 0; i < row_width; i++) 2696 { 2697 if (m & mask) 2698 { 2699 png_memcpy(dp, sp, pixel_bytes); 2700 } 2701 2702 sp += pixel_bytes; 2703 dp += pixel_bytes; 2704 2705 if (m == 1) 2706 m = 0x80; 2707 else 2708 m >>= 1; 2709 } 2710 break; 2711 } 2712 } 2713 } 2714 } 2715 2716 #ifdef PNG_READ_INTERLACING_SUPPORTED 2717 /* OLD pre-1.0.9 interface: 2718 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 2719 png_uint_32 transformations) 2720 */ 2721 void /* PRIVATE */ 2722 png_do_read_interlace(png_structp png_ptr) 2723 { 2724 png_row_infop row_info = &(png_ptr->row_info); 2725 png_bytep row = png_ptr->row_buf + 1; 2726 int pass = png_ptr->pass; 2727 png_uint_32 transformations = png_ptr->transformations; 2728 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2729 /* Offset to next interlace block */ 2730 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2731 2732 png_debug(1, "in png_do_read_interlace"); 2733 if (row != NULL && row_info != NULL) 2734 { 2735 png_uint_32 final_width; 2736 2737 final_width = row_info->width * png_pass_inc[pass]; 2738 2739 switch (row_info->pixel_depth) 2740 { 2741 case 1: 2742 { 2743 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 2744 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 2745 int sshift, dshift; 2746 int s_start, s_end, s_inc; 2747 int jstop = png_pass_inc[pass]; 2748 png_byte v; 2749 png_uint_32 i; 2750 int j; 2751 2752 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2753 if (transformations & PNG_PACKSWAP) 2754 { 2755 sshift = (int)((row_info->width + 7) & 0x07); 2756 dshift = (int)((final_width + 7) & 0x07); 2757 s_start = 7; 2758 s_end = 0; 2759 s_inc = -1; 2760 } 2761 else 2762 #endif 2763 { 2764 sshift = 7 - (int)((row_info->width + 7) & 0x07); 2765 dshift = 7 - (int)((final_width + 7) & 0x07); 2766 s_start = 0; 2767 s_end = 7; 2768 s_inc = 1; 2769 } 2770 2771 for (i = 0; i < row_info->width; i++) 2772 { 2773 v = (png_byte)((*sp >> sshift) & 0x01); 2774 for (j = 0; j < jstop; j++) 2775 { 2776 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 2777 *dp |= (png_byte)(v << dshift); 2778 if (dshift == s_end) 2779 { 2780 dshift = s_start; 2781 dp--; 2782 } 2783 else 2784 dshift += s_inc; 2785 } 2786 if (sshift == s_end) 2787 { 2788 sshift = s_start; 2789 sp--; 2790 } 2791 else 2792 sshift += s_inc; 2793 } 2794 break; 2795 } 2796 case 2: 2797 { 2798 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 2799 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 2800 int sshift, dshift; 2801 int s_start, s_end, s_inc; 2802 int jstop = png_pass_inc[pass]; 2803 png_uint_32 i; 2804 2805 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2806 if (transformations & PNG_PACKSWAP) 2807 { 2808 sshift = (int)(((row_info->width + 3) & 0x03) << 1); 2809 dshift = (int)(((final_width + 3) & 0x03) << 1); 2810 s_start = 6; 2811 s_end = 0; 2812 s_inc = -2; 2813 } 2814 else 2815 #endif 2816 { 2817 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 2818 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 2819 s_start = 0; 2820 s_end = 6; 2821 s_inc = 2; 2822 } 2823 2824 for (i = 0; i < row_info->width; i++) 2825 { 2826 png_byte v; 2827 int j; 2828 2829 v = (png_byte)((*sp >> sshift) & 0x03); 2830 for (j = 0; j < jstop; j++) 2831 { 2832 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 2833 *dp |= (png_byte)(v << dshift); 2834 if (dshift == s_end) 2835 { 2836 dshift = s_start; 2837 dp--; 2838 } 2839 else 2840 dshift += s_inc; 2841 } 2842 if (sshift == s_end) 2843 { 2844 sshift = s_start; 2845 sp--; 2846 } 2847 else 2848 sshift += s_inc; 2849 } 2850 break; 2851 } 2852 case 4: 2853 { 2854 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 2855 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 2856 int sshift, dshift; 2857 int s_start, s_end, s_inc; 2858 png_uint_32 i; 2859 int jstop = png_pass_inc[pass]; 2860 2861 #ifdef PNG_READ_PACKSWAP_SUPPORTED 2862 if (transformations & PNG_PACKSWAP) 2863 { 2864 sshift = (int)(((row_info->width + 1) & 0x01) << 2); 2865 dshift = (int)(((final_width + 1) & 0x01) << 2); 2866 s_start = 4; 2867 s_end = 0; 2868 s_inc = -4; 2869 } 2870 else 2871 #endif 2872 { 2873 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 2874 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 2875 s_start = 0; 2876 s_end = 4; 2877 s_inc = 4; 2878 } 2879 2880 for (i = 0; i < row_info->width; i++) 2881 { 2882 png_byte v = (png_byte)((*sp >> sshift) & 0xf); 2883 int j; 2884 2885 for (j = 0; j < jstop; j++) 2886 { 2887 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 2888 *dp |= (png_byte)(v << dshift); 2889 if (dshift == s_end) 2890 { 2891 dshift = s_start; 2892 dp--; 2893 } 2894 else 2895 dshift += s_inc; 2896 } 2897 if (sshift == s_end) 2898 { 2899 sshift = s_start; 2900 sp--; 2901 } 2902 else 2903 sshift += s_inc; 2904 } 2905 break; 2906 } 2907 default: 2908 { 2909 png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 2910 png_bytep sp = row + (png_size_t)(row_info->width - 1) 2911 * pixel_bytes; 2912 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 2913 2914 int jstop = png_pass_inc[pass]; 2915 png_uint_32 i; 2916 2917 for (i = 0; i < row_info->width; i++) 2918 { 2919 png_byte v[8]; 2920 int j; 2921 2922 png_memcpy(v, sp, pixel_bytes); 2923 for (j = 0; j < jstop; j++) 2924 { 2925 png_memcpy(dp, v, pixel_bytes); 2926 dp -= pixel_bytes; 2927 } 2928 sp -= pixel_bytes; 2929 } 2930 break; 2931 } 2932 } 2933 row_info->width = final_width; 2934 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); 2935 } 2936 #ifndef PNG_READ_PACKSWAP_SUPPORTED 2937 transformations = transformations; /* Silence compiler warning */ 2938 #endif 2939 } 2940 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 2941 2942 void /* PRIVATE */ 2943 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, 2944 png_bytep prev_row, int filter) 2945 { 2946 png_debug(1, "in png_read_filter_row"); 2947 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); 2948 switch (filter) 2949 { 2950 case PNG_FILTER_VALUE_NONE: 2951 break; 2952 case PNG_FILTER_VALUE_SUB: 2953 { 2954 png_uint_32 i; 2955 png_uint_32 istop = row_info->rowbytes; 2956 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 2957 png_bytep rp = row + bpp; 2958 png_bytep lp = row; 2959 2960 for (i = bpp; i < istop; i++) 2961 { 2962 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); 2963 rp++; 2964 } 2965 break; 2966 } 2967 case PNG_FILTER_VALUE_UP: 2968 { 2969 png_uint_32 i; 2970 png_uint_32 istop = row_info->rowbytes; 2971 png_bytep rp = row; 2972 png_bytep pp = prev_row; 2973 2974 for (i = 0; i < istop; i++) 2975 { 2976 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 2977 rp++; 2978 } 2979 break; 2980 } 2981 case PNG_FILTER_VALUE_AVG: 2982 { 2983 png_uint_32 i; 2984 png_bytep rp = row; 2985 png_bytep pp = prev_row; 2986 png_bytep lp = row; 2987 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 2988 png_uint_32 istop = row_info->rowbytes - bpp; 2989 2990 for (i = 0; i < bpp; i++) 2991 { 2992 *rp = (png_byte)(((int)(*rp) + 2993 ((int)(*pp++) / 2 )) & 0xff); 2994 rp++; 2995 } 2996 2997 for (i = 0; i < istop; i++) 2998 { 2999 *rp = (png_byte)(((int)(*rp) + 3000 (int)(*pp++ + *lp++) / 2 ) & 0xff); 3001 rp++; 3002 } 3003 break; 3004 } 3005 case PNG_FILTER_VALUE_PAETH: 3006 { 3007 png_uint_32 i; 3008 png_bytep rp = row; 3009 png_bytep pp = prev_row; 3010 png_bytep lp = row; 3011 png_bytep cp = prev_row; 3012 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3013 png_uint_32 istop=row_info->rowbytes - bpp; 3014 3015 for (i = 0; i < bpp; i++) 3016 { 3017 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3018 rp++; 3019 } 3020 3021 for (i = 0; i < istop; i++) /* Use leftover rp,pp */ 3022 { 3023 int a, b, c, pa, pb, pc, p; 3024 3025 a = *lp++; 3026 b = *pp++; 3027 c = *cp++; 3028 3029 p = b - c; 3030 pc = a - c; 3031 3032 #ifdef PNG_USE_ABS 3033 pa = abs(p); 3034 pb = abs(pc); 3035 pc = abs(p + pc); 3036 #else 3037 pa = p < 0 ? -p : p; 3038 pb = pc < 0 ? -pc : pc; 3039 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 3040 #endif 3041 3042 /* 3043 if (pa <= pb && pa <= pc) 3044 p = a; 3045 else if (pb <= pc) 3046 p = b; 3047 else 3048 p = c; 3049 */ 3050 3051 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; 3052 3053 *rp = (png_byte)(((int)(*rp) + p) & 0xff); 3054 rp++; 3055 } 3056 break; 3057 } 3058 default: 3059 png_warning(png_ptr, "Ignoring bad adaptive filter type"); 3060 *row = 0; 3061 break; 3062 } 3063 } 3064 3065 #ifdef PNG_INDEX_SUPPORTED 3066 void /* PRIVATE */ 3067 png_set_interlaced_pass(png_structp png_ptr, int pass) 3068 { 3069 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3070 3071 /* Start of interlace block */ 3072 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3073 3074 /* Offset to next interlace block */ 3075 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3076 3077 /* Start of interlace block in the y direction */ 3078 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3079 3080 /* Offset to next interlace block in the y direction */ 3081 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3082 3083 png_ptr->pass = pass; 3084 png_ptr->iwidth = (png_ptr->width + 3085 png_pass_inc[png_ptr->pass] - 1 - 3086 png_pass_start[png_ptr->pass]) / 3087 png_pass_inc[png_ptr->pass]; 3088 } 3089 #endif 3090 3091 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 3092 void /* PRIVATE */ 3093 png_read_finish_row(png_structp png_ptr) 3094 { 3095 #ifdef PNG_READ_INTERLACING_SUPPORTED 3096 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3097 3098 /* Start of interlace block */ 3099 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3100 3101 /* Offset to next interlace block */ 3102 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3103 3104 /* Start of interlace block in the y direction */ 3105 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3106 3107 /* Offset to next interlace block in the y direction */ 3108 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3109 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3110 3111 png_debug(1, "in png_read_finish_row"); 3112 png_ptr->row_number++; 3113 if (png_ptr->row_number < png_ptr->num_rows) 3114 return; 3115 3116 #ifdef PNG_READ_INTERLACING_SUPPORTED 3117 if (png_ptr->interlaced) 3118 { 3119 png_ptr->row_number = 0; 3120 png_memset_check(png_ptr, png_ptr->prev_row, 0, 3121 png_ptr->rowbytes + 1); 3122 do 3123 { 3124 png_ptr->pass++; 3125 if (png_ptr->pass >= 7) 3126 break; 3127 png_ptr->iwidth = (png_ptr->width + 3128 png_pass_inc[png_ptr->pass] - 1 - 3129 png_pass_start[png_ptr->pass]) / 3130 png_pass_inc[png_ptr->pass]; 3131 3132 if (!(png_ptr->transformations & PNG_INTERLACE)) 3133 { 3134 png_ptr->num_rows = (png_ptr->height + 3135 png_pass_yinc[png_ptr->pass] - 1 - 3136 png_pass_ystart[png_ptr->pass]) / 3137 png_pass_yinc[png_ptr->pass]; 3138 if (!(png_ptr->num_rows)) 3139 continue; 3140 } 3141 else /* if (png_ptr->transformations & PNG_INTERLACE) */ 3142 break; 3143 } while (png_ptr->iwidth == 0); 3144 3145 if (png_ptr->pass < 7) 3146 return; 3147 } 3148 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3149 3150 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 3151 { 3152 #ifdef PNG_USE_LOCAL_ARRAYS 3153 PNG_CONST PNG_IDAT; 3154 #endif 3155 char extra; 3156 int ret; 3157 3158 png_ptr->zstream.next_out = (Byte *)&extra; 3159 png_ptr->zstream.avail_out = (uInt)1; 3160 for (;;) 3161 { 3162 if (!(png_ptr->zstream.avail_in)) 3163 { 3164 while (!png_ptr->idat_size) 3165 { 3166 png_byte chunk_length[4]; 3167 3168 png_crc_finish(png_ptr, 0); 3169 3170 png_read_data(png_ptr, chunk_length, 4); 3171 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); 3172 png_reset_crc(png_ptr); 3173 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 3174 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 3175 png_error(png_ptr, "Not enough image data"); 3176 3177 } 3178 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 3179 png_ptr->zstream.next_in = png_ptr->zbuf; 3180 if (png_ptr->zbuf_size > png_ptr->idat_size) 3181 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 3182 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); 3183 png_ptr->idat_size -= png_ptr->zstream.avail_in; 3184 } 3185 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 3186 if (ret == Z_STREAM_END) 3187 { 3188 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || 3189 png_ptr->idat_size) 3190 png_warning(png_ptr, "Extra compressed data."); 3191 png_ptr->mode |= PNG_AFTER_IDAT; 3192 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3193 break; 3194 } 3195 if (ret != Z_OK) 3196 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 3197 "Decompression Error"); 3198 3199 if (!(png_ptr->zstream.avail_out)) 3200 { 3201 png_warning(png_ptr, "Extra compressed data."); 3202 png_ptr->mode |= PNG_AFTER_IDAT; 3203 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3204 break; 3205 } 3206 3207 } 3208 png_ptr->zstream.avail_out = 0; 3209 } 3210 3211 if (png_ptr->idat_size || png_ptr->zstream.avail_in) 3212 png_warning(png_ptr, "Extra compression data."); 3213 3214 inflateReset(&png_ptr->zstream); 3215 3216 png_ptr->mode |= PNG_AFTER_IDAT; 3217 } 3218 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 3219 3220 void /* PRIVATE */ 3221 png_read_start_row(png_structp png_ptr) 3222 { 3223 #ifdef PNG_READ_INTERLACING_SUPPORTED 3224 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3225 3226 /* Start of interlace block */ 3227 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3228 3229 /* Offset to next interlace block */ 3230 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3231 3232 /* Start of interlace block in the y direction */ 3233 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3234 3235 /* Offset to next interlace block in the y direction */ 3236 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3237 #endif 3238 3239 int max_pixel_depth; 3240 png_size_t row_bytes; 3241 3242 png_debug(1, "in png_read_start_row"); 3243 png_ptr->zstream.avail_in = 0; 3244 png_init_read_transformations(png_ptr); 3245 #ifdef PNG_READ_INTERLACING_SUPPORTED 3246 if (png_ptr->interlaced) 3247 { 3248 if (!(png_ptr->transformations & PNG_INTERLACE)) 3249 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 3250 png_pass_ystart[0]) / png_pass_yinc[0]; 3251 else 3252 png_ptr->num_rows = png_ptr->height; 3253 3254 png_ptr->iwidth = (png_ptr->width + 3255 png_pass_inc[png_ptr->pass] - 1 - 3256 png_pass_start[png_ptr->pass]) / 3257 png_pass_inc[png_ptr->pass]; 3258 } 3259 else 3260 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 3261 { 3262 png_ptr->num_rows = png_ptr->height; 3263 png_ptr->iwidth = png_ptr->width; 3264 } 3265 max_pixel_depth = png_ptr->pixel_depth; 3266 3267 #ifdef PNG_READ_PACK_SUPPORTED 3268 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 3269 max_pixel_depth = 8; 3270 #endif 3271 3272 #ifdef PNG_READ_EXPAND_SUPPORTED 3273 if (png_ptr->transformations & PNG_EXPAND) 3274 { 3275 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3276 { 3277 if (png_ptr->num_trans) 3278 max_pixel_depth = 32; 3279 else 3280 max_pixel_depth = 24; 3281 } 3282 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3283 { 3284 if (max_pixel_depth < 8) 3285 max_pixel_depth = 8; 3286 if (png_ptr->num_trans) 3287 max_pixel_depth *= 2; 3288 } 3289 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3290 { 3291 if (png_ptr->num_trans) 3292 { 3293 max_pixel_depth *= 4; 3294 max_pixel_depth /= 3; 3295 } 3296 } 3297 } 3298 #endif 3299 3300 #ifdef PNG_READ_FILLER_SUPPORTED 3301 if (png_ptr->transformations & (PNG_FILLER)) 3302 { 3303 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3304 max_pixel_depth = 32; 3305 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3306 { 3307 if (max_pixel_depth <= 8) 3308 max_pixel_depth = 16; 3309 else 3310 max_pixel_depth = 32; 3311 } 3312 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3313 { 3314 if (max_pixel_depth <= 32) 3315 max_pixel_depth = 32; 3316 else 3317 max_pixel_depth = 64; 3318 } 3319 } 3320 #endif 3321 3322 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 3323 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 3324 { 3325 if ( 3326 #ifdef PNG_READ_EXPAND_SUPPORTED 3327 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 3328 #endif 3329 #ifdef PNG_READ_FILLER_SUPPORTED 3330 (png_ptr->transformations & (PNG_FILLER)) || 3331 #endif 3332 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 3333 { 3334 if (max_pixel_depth <= 16) 3335 max_pixel_depth = 32; 3336 else 3337 max_pixel_depth = 64; 3338 } 3339 else 3340 { 3341 if (max_pixel_depth <= 8) 3342 { 3343 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3344 max_pixel_depth = 32; 3345 else 3346 max_pixel_depth = 24; 3347 } 3348 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3349 max_pixel_depth = 64; 3350 else 3351 max_pixel_depth = 48; 3352 } 3353 } 3354 #endif 3355 3356 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 3357 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 3358 if (png_ptr->transformations & PNG_USER_TRANSFORM) 3359 { 3360 int user_pixel_depth = png_ptr->user_transform_depth* 3361 png_ptr->user_transform_channels; 3362 if (user_pixel_depth > max_pixel_depth) 3363 max_pixel_depth=user_pixel_depth; 3364 } 3365 #endif 3366 3367 /* Align the width on the next larger 8 pixels. Mainly used 3368 * for interlacing 3369 */ 3370 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 3371 /* Calculate the maximum bytes needed, adding a byte and a pixel 3372 * for safety's sake 3373 */ 3374 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 3375 1 + ((max_pixel_depth + 7) >> 3); 3376 #ifdef PNG_MAX_MALLOC_64K 3377 if (row_bytes > (png_uint_32)65536L) 3378 png_error(png_ptr, "This image requires a row greater than 64KB"); 3379 #endif 3380 3381 if (row_bytes + 64 > png_ptr->old_big_row_buf_size) 3382 { 3383 png_free(png_ptr, png_ptr->big_row_buf); 3384 if (png_ptr->interlaced) 3385 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, 3386 row_bytes + 64); 3387 else 3388 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, 3389 row_bytes + 64); 3390 png_ptr->old_big_row_buf_size = row_bytes + 64; 3391 3392 /* Use 32 bytes of padding before and after row_buf. */ 3393 png_ptr->row_buf = png_ptr->big_row_buf + 32; 3394 png_ptr->old_big_row_buf_size = row_bytes + 64; 3395 } 3396 3397 #ifdef PNG_MAX_MALLOC_64K 3398 if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L) 3399 png_error(png_ptr, "This image requires a row greater than 64KB"); 3400 #endif 3401 if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1)) 3402 png_error(png_ptr, "Row has too many bytes to allocate in memory."); 3403 3404 if (row_bytes + 1 > png_ptr->old_prev_row_size) 3405 { 3406 png_free(png_ptr, png_ptr->prev_row); 3407 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( 3408 row_bytes + 1)); 3409 png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1); 3410 png_ptr->old_prev_row_size = row_bytes + 1; 3411 } 3412 3413 png_ptr->rowbytes = row_bytes; 3414 3415 png_debug1(3, "width = %lu,", png_ptr->width); 3416 png_debug1(3, "height = %lu,", png_ptr->height); 3417 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); 3418 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); 3419 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes); 3420 png_debug1(3, "irowbytes = %lu", 3421 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); 3422 3423 png_ptr->flags |= PNG_FLAG_ROW_INIT; 3424 } 3425 #endif /* PNG_READ_SUPPORTED */ 3426