pngpread.c revision a0bb96c34e65378853ee518bac502842d26c2d1a
1 2/* pngpread.c - read a png file in push mode 3 * 4 * Last changed in libpng 1.2.37 [July 16, 2009] 5 * Copyright (c) 1998-2009 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 14#define PNG_INTERNAL 15#include "png.h" 16#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 17 18/* Push model modes */ 19#define PNG_READ_SIG_MODE 0 20#define PNG_READ_CHUNK_MODE 1 21#define PNG_READ_IDAT_MODE 2 22#define PNG_SKIP_MODE 3 23#define PNG_READ_tEXt_MODE 4 24#define PNG_READ_zTXt_MODE 5 25#define PNG_READ_DONE_MODE 6 26#define PNG_READ_iTXt_MODE 7 27#define PNG_ERROR_MODE 8 28 29void PNGAPI 30png_process_data(png_structp png_ptr, png_infop info_ptr, 31 png_bytep buffer, png_size_t buffer_size) 32{ 33 if (png_ptr == NULL || info_ptr == NULL) 34 return; 35 36 png_push_restore_buffer(png_ptr, buffer, buffer_size); 37 38 while (png_ptr->buffer_size) 39 { 40 png_process_some_data(png_ptr, info_ptr); 41 } 42} 43 44/* What we do with the incoming data depends on what we were previously 45 * doing before we ran out of data... 46 */ 47void /* PRIVATE */ 48png_process_some_data(png_structp png_ptr, png_infop info_ptr) 49{ 50 if (png_ptr == NULL) 51 return; 52 53 switch (png_ptr->process_mode) 54 { 55 case PNG_READ_SIG_MODE: 56 { 57 png_push_read_sig(png_ptr, info_ptr); 58 break; 59 } 60 61 case PNG_READ_CHUNK_MODE: 62 { 63 png_push_read_chunk(png_ptr, info_ptr); 64 break; 65 } 66 67 case PNG_READ_IDAT_MODE: 68 { 69 png_push_read_IDAT(png_ptr); 70 break; 71 } 72 73#if defined(PNG_READ_tEXt_SUPPORTED) 74 case PNG_READ_tEXt_MODE: 75 { 76 png_push_read_tEXt(png_ptr, info_ptr); 77 break; 78 } 79 80#endif 81#if defined(PNG_READ_zTXt_SUPPORTED) 82 case PNG_READ_zTXt_MODE: 83 { 84 png_push_read_zTXt(png_ptr, info_ptr); 85 break; 86 } 87 88#endif 89#if defined(PNG_READ_iTXt_SUPPORTED) 90 case PNG_READ_iTXt_MODE: 91 { 92 png_push_read_iTXt(png_ptr, info_ptr); 93 break; 94 } 95 96#endif 97 case PNG_SKIP_MODE: 98 { 99 png_push_crc_finish(png_ptr); 100 break; 101 } 102 103 default: 104 { 105 png_ptr->buffer_size = 0; 106 break; 107 } 108 } 109} 110 111/* Read any remaining signature bytes from the stream and compare them with 112 * the correct PNG signature. It is possible that this routine is called 113 * with bytes already read from the signature, either because they have been 114 * checked by the calling application, or because of multiple calls to this 115 * routine. 116 */ 117void /* PRIVATE */ 118png_push_read_sig(png_structp png_ptr, png_infop info_ptr) 119{ 120 png_size_t num_checked = png_ptr->sig_bytes, 121 num_to_check = 8 - num_checked; 122 123 if (png_ptr->buffer_size < num_to_check) 124 { 125 num_to_check = png_ptr->buffer_size; 126 } 127 128 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), 129 num_to_check); 130 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); 131 132 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) 133 { 134 if (num_checked < 4 && 135 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) 136 png_error(png_ptr, "Not a PNG file"); 137 else 138 png_error(png_ptr, "PNG file corrupted by ASCII conversion"); 139 } 140 else 141 { 142 if (png_ptr->sig_bytes >= 8) 143 { 144 png_ptr->process_mode = PNG_READ_CHUNK_MODE; 145 } 146 } 147} 148 149void /* PRIVATE */ 150png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) 151{ 152#ifdef PNG_USE_LOCAL_ARRAYS 153 PNG_CONST PNG_IHDR; 154 PNG_CONST PNG_IDAT; 155 PNG_CONST PNG_IEND; 156 PNG_CONST PNG_PLTE; 157#if defined(PNG_READ_bKGD_SUPPORTED) 158 PNG_CONST PNG_bKGD; 159#endif 160#if defined(PNG_READ_cHRM_SUPPORTED) 161 PNG_CONST PNG_cHRM; 162#endif 163#if defined(PNG_READ_gAMA_SUPPORTED) 164 PNG_CONST PNG_gAMA; 165#endif 166#if defined(PNG_READ_hIST_SUPPORTED) 167 PNG_CONST PNG_hIST; 168#endif 169#if defined(PNG_READ_iCCP_SUPPORTED) 170 PNG_CONST PNG_iCCP; 171#endif 172#if defined(PNG_READ_iTXt_SUPPORTED) 173 PNG_CONST PNG_iTXt; 174#endif 175#if defined(PNG_READ_oFFs_SUPPORTED) 176 PNG_CONST PNG_oFFs; 177#endif 178#if defined(PNG_READ_pCAL_SUPPORTED) 179 PNG_CONST PNG_pCAL; 180#endif 181#if defined(PNG_READ_pHYs_SUPPORTED) 182 PNG_CONST PNG_pHYs; 183#endif 184#if defined(PNG_READ_sBIT_SUPPORTED) 185 PNG_CONST PNG_sBIT; 186#endif 187#if defined(PNG_READ_sCAL_SUPPORTED) 188 PNG_CONST PNG_sCAL; 189#endif 190#if defined(PNG_READ_sRGB_SUPPORTED) 191 PNG_CONST PNG_sRGB; 192#endif 193#if defined(PNG_READ_sPLT_SUPPORTED) 194 PNG_CONST PNG_sPLT; 195#endif 196#if defined(PNG_READ_tEXt_SUPPORTED) 197 PNG_CONST PNG_tEXt; 198#endif 199#if defined(PNG_READ_tIME_SUPPORTED) 200 PNG_CONST PNG_tIME; 201#endif 202#if defined(PNG_READ_tRNS_SUPPORTED) 203 PNG_CONST PNG_tRNS; 204#endif 205#if defined(PNG_READ_zTXt_SUPPORTED) 206 PNG_CONST PNG_zTXt; 207#endif 208#endif /* PNG_USE_LOCAL_ARRAYS */ 209 /* First we make sure we have enough data for the 4 byte chunk name 210 * and the 4 byte chunk length before proceeding with decoding the 211 * chunk data. To fully decode each of these chunks, we also make 212 * sure we have enough data in the buffer for the 4 byte CRC at the 213 * end of every chunk (except IDAT, which is handled separately). 214 */ 215 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) 216 { 217 png_byte chunk_length[4]; 218 219 if (png_ptr->buffer_size < 8) 220 { 221 png_push_save_buffer(png_ptr); 222 return; 223 } 224 225 png_push_fill_buffer(png_ptr, chunk_length, 4); 226 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 227 png_reset_crc(png_ptr); 228 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 229 png_check_chunk_name(png_ptr, png_ptr->chunk_name); 230 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 231 } 232 233 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 234 if (png_ptr->mode & PNG_AFTER_IDAT) 235 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 236 237 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) 238 { 239 if (png_ptr->push_length != 13) 240 png_error(png_ptr, "Invalid IHDR length"); 241 242 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 243 { 244 png_push_save_buffer(png_ptr); 245 return; 246 } 247 248 png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); 249 } 250 251 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) 252 { 253 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 254 { 255 png_push_save_buffer(png_ptr); 256 return; 257 } 258 259 png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); 260 261 png_ptr->process_mode = PNG_READ_DONE_MODE; 262 png_push_have_end(png_ptr, info_ptr); 263 } 264 265#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 266 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) 267 { 268 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 269 { 270 png_push_save_buffer(png_ptr); 271 return; 272 } 273 274 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 275 png_ptr->mode |= PNG_HAVE_IDAT; 276 277 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); 278 279 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 280 png_ptr->mode |= PNG_HAVE_PLTE; 281 282 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 283 { 284 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 285 png_error(png_ptr, "Missing IHDR before IDAT"); 286 287 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 288 !(png_ptr->mode & PNG_HAVE_PLTE)) 289 png_error(png_ptr, "Missing PLTE before IDAT"); 290 } 291 } 292 293#endif 294 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) 295 { 296 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 297 { 298 png_push_save_buffer(png_ptr); 299 return; 300 } 301 png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); 302 } 303 304 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 305 { 306 /* If we reach an IDAT chunk, this means we have read all of the 307 * header chunks, and we can start reading the image (or if this 308 * is called after the image has been read - we have an error). 309 */ 310 311 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 312 png_error(png_ptr, "Missing IHDR before IDAT"); 313 314 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 315 !(png_ptr->mode & PNG_HAVE_PLTE)) 316 png_error(png_ptr, "Missing PLTE before IDAT"); 317 318 if (png_ptr->mode & PNG_HAVE_IDAT) 319 { 320 if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 321 if (png_ptr->push_length == 0) 322 return; 323 324 if (png_ptr->mode & PNG_AFTER_IDAT) 325 png_error(png_ptr, "Too many IDAT's found"); 326 } 327 328 png_ptr->idat_size = png_ptr->push_length; 329 png_ptr->mode |= PNG_HAVE_IDAT; 330 png_ptr->process_mode = PNG_READ_IDAT_MODE; 331 png_push_have_info(png_ptr, info_ptr); 332 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; 333 png_ptr->zstream.next_out = png_ptr->row_buf; 334 return; 335 } 336 337#if defined(PNG_READ_gAMA_SUPPORTED) 338 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) 339 { 340 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 341 { 342 png_push_save_buffer(png_ptr); 343 return; 344 } 345 346 png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); 347 } 348 349#endif 350#if defined(PNG_READ_sBIT_SUPPORTED) 351 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) 352 { 353 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 354 { 355 png_push_save_buffer(png_ptr); 356 return; 357 } 358 359 png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); 360 } 361 362#endif 363#if defined(PNG_READ_cHRM_SUPPORTED) 364 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) 365 { 366 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 367 { 368 png_push_save_buffer(png_ptr); 369 return; 370 } 371 372 png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); 373 } 374 375#endif 376#if defined(PNG_READ_sRGB_SUPPORTED) 377 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) 378 { 379 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 380 { 381 png_push_save_buffer(png_ptr); 382 return; 383 } 384 385 png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); 386 } 387 388#endif 389#if defined(PNG_READ_iCCP_SUPPORTED) 390 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) 391 { 392 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 393 { 394 png_push_save_buffer(png_ptr); 395 return; 396 } 397 398 png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); 399 } 400 401#endif 402#if defined(PNG_READ_sPLT_SUPPORTED) 403 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) 404 { 405 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 406 { 407 png_push_save_buffer(png_ptr); 408 return; 409 } 410 411 png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); 412 } 413 414#endif 415#if defined(PNG_READ_tRNS_SUPPORTED) 416 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) 417 { 418 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 419 { 420 png_push_save_buffer(png_ptr); 421 return; 422 } 423 424 png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); 425 } 426 427#endif 428#if defined(PNG_READ_bKGD_SUPPORTED) 429 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) 430 { 431 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 432 { 433 png_push_save_buffer(png_ptr); 434 return; 435 } 436 437 png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); 438 } 439 440#endif 441#if defined(PNG_READ_hIST_SUPPORTED) 442 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) 443 { 444 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 445 { 446 png_push_save_buffer(png_ptr); 447 return; 448 } 449 450 png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); 451 } 452 453#endif 454#if defined(PNG_READ_pHYs_SUPPORTED) 455 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) 456 { 457 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 458 { 459 png_push_save_buffer(png_ptr); 460 return; 461 } 462 463 png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); 464 } 465 466#endif 467#if defined(PNG_READ_oFFs_SUPPORTED) 468 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) 469 { 470 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 471 { 472 png_push_save_buffer(png_ptr); 473 return; 474 } 475 476 png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); 477 } 478#endif 479 480#if defined(PNG_READ_pCAL_SUPPORTED) 481 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) 482 { 483 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 484 { 485 png_push_save_buffer(png_ptr); 486 return; 487 } 488 489 png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); 490 } 491 492#endif 493#if defined(PNG_READ_sCAL_SUPPORTED) 494 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) 495 { 496 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 497 { 498 png_push_save_buffer(png_ptr); 499 return; 500 } 501 502 png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); 503 } 504 505#endif 506#if defined(PNG_READ_tIME_SUPPORTED) 507 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) 508 { 509 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 510 { 511 png_push_save_buffer(png_ptr); 512 return; 513 } 514 515 png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); 516 } 517 518#endif 519#if defined(PNG_READ_tEXt_SUPPORTED) 520 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) 521 { 522 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 523 { 524 png_push_save_buffer(png_ptr); 525 return; 526 } 527 528 png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); 529 } 530 531#endif 532#if defined(PNG_READ_zTXt_SUPPORTED) 533 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) 534 { 535 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 536 { 537 png_push_save_buffer(png_ptr); 538 return; 539 } 540 541 png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); 542 } 543 544#endif 545#if defined(PNG_READ_iTXt_SUPPORTED) 546 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) 547 { 548 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 549 { 550 png_push_save_buffer(png_ptr); 551 return; 552 } 553 554 png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); 555 } 556 557#endif 558 else 559 { 560 if (png_ptr->push_length + 4 > png_ptr->buffer_size) 561 { 562 png_push_save_buffer(png_ptr); 563 return; 564 } 565 png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); 566 } 567 568 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 569} 570 571void /* PRIVATE */ 572png_push_crc_skip(png_structp png_ptr, png_uint_32 skip) 573{ 574 png_ptr->process_mode = PNG_SKIP_MODE; 575 png_ptr->skip_length = skip; 576} 577 578void /* PRIVATE */ 579png_push_crc_finish(png_structp png_ptr) 580{ 581 if (png_ptr->skip_length && png_ptr->save_buffer_size) 582 { 583 png_size_t save_size; 584 585 if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) 586 save_size = (png_size_t)png_ptr->skip_length; 587 else 588 save_size = png_ptr->save_buffer_size; 589 590 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); 591 592 png_ptr->skip_length -= save_size; 593 png_ptr->buffer_size -= save_size; 594 png_ptr->save_buffer_size -= save_size; 595 png_ptr->save_buffer_ptr += save_size; 596 } 597 if (png_ptr->skip_length && png_ptr->current_buffer_size) 598 { 599 png_size_t save_size; 600 601 if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) 602 save_size = (png_size_t)png_ptr->skip_length; 603 else 604 save_size = png_ptr->current_buffer_size; 605 606 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); 607 608 png_ptr->skip_length -= save_size; 609 png_ptr->buffer_size -= save_size; 610 png_ptr->current_buffer_size -= save_size; 611 png_ptr->current_buffer_ptr += save_size; 612 } 613 if (!png_ptr->skip_length) 614 { 615 if (png_ptr->buffer_size < 4) 616 { 617 png_push_save_buffer(png_ptr); 618 return; 619 } 620 621 png_crc_finish(png_ptr, 0); 622 png_ptr->process_mode = PNG_READ_CHUNK_MODE; 623 } 624} 625 626void PNGAPI 627png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) 628{ 629 png_bytep ptr; 630 631 if (png_ptr == NULL) 632 return; 633 634 ptr = buffer; 635 if (png_ptr->save_buffer_size) 636 { 637 png_size_t save_size; 638 639 if (length < png_ptr->save_buffer_size) 640 save_size = length; 641 else 642 save_size = png_ptr->save_buffer_size; 643 644 png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size); 645 length -= save_size; 646 ptr += save_size; 647 png_ptr->buffer_size -= save_size; 648 png_ptr->save_buffer_size -= save_size; 649 png_ptr->save_buffer_ptr += save_size; 650 } 651 if (length && png_ptr->current_buffer_size) 652 { 653 png_size_t save_size; 654 655 if (length < png_ptr->current_buffer_size) 656 save_size = length; 657 658 else 659 save_size = png_ptr->current_buffer_size; 660 661 png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size); 662 png_ptr->buffer_size -= save_size; 663 png_ptr->current_buffer_size -= save_size; 664 png_ptr->current_buffer_ptr += save_size; 665 } 666} 667 668void /* PRIVATE */ 669png_push_save_buffer(png_structp png_ptr) 670{ 671 if (png_ptr->save_buffer_size) 672 { 673 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) 674 { 675 png_size_t i, istop; 676 png_bytep sp; 677 png_bytep dp; 678 679 istop = png_ptr->save_buffer_size; 680 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; 681 i < istop; i++, sp++, dp++) 682 { 683 *dp = *sp; 684 } 685 } 686 } 687 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > 688 png_ptr->save_buffer_max) 689 { 690 png_size_t new_max; 691 png_bytep old_buffer; 692 693 if (png_ptr->save_buffer_size > PNG_SIZE_MAX - 694 (png_ptr->current_buffer_size + 256)) 695 { 696 png_error(png_ptr, "Potential overflow of save_buffer"); 697 } 698 699 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; 700 old_buffer = png_ptr->save_buffer; 701 png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, 702 (png_uint_32)new_max); 703 png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); 704 png_free(png_ptr, old_buffer); 705 png_ptr->save_buffer_max = new_max; 706 } 707 if (png_ptr->current_buffer_size) 708 { 709 png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, 710 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); 711 png_ptr->save_buffer_size += png_ptr->current_buffer_size; 712 png_ptr->current_buffer_size = 0; 713 } 714 png_ptr->save_buffer_ptr = png_ptr->save_buffer; 715 png_ptr->buffer_size = 0; 716} 717 718void /* PRIVATE */ 719png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, 720 png_size_t buffer_length) 721{ 722 png_ptr->current_buffer = buffer; 723 png_ptr->current_buffer_size = buffer_length; 724 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; 725 png_ptr->current_buffer_ptr = png_ptr->current_buffer; 726} 727 728void /* PRIVATE */ 729png_push_read_IDAT(png_structp png_ptr) 730{ 731#ifdef PNG_USE_LOCAL_ARRAYS 732 PNG_CONST PNG_IDAT; 733#endif 734 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) 735 { 736 png_byte chunk_length[4]; 737 738 if (png_ptr->buffer_size < 8) 739 { 740 png_push_save_buffer(png_ptr); 741 return; 742 } 743 744 png_push_fill_buffer(png_ptr, chunk_length, 4); 745 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 746 png_reset_crc(png_ptr); 747 png_crc_read(png_ptr, png_ptr->chunk_name, 4); 748 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 749 750 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 751 { 752 png_ptr->process_mode = PNG_READ_CHUNK_MODE; 753 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 754 png_error(png_ptr, "Not enough compressed data"); 755 return; 756 } 757 758 png_ptr->idat_size = png_ptr->push_length; 759 } 760 if (png_ptr->idat_size && png_ptr->save_buffer_size) 761 { 762 png_size_t save_size; 763 764 if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) 765 { 766 save_size = (png_size_t)png_ptr->idat_size; 767 768 /* Check for overflow */ 769 if ((png_uint_32)save_size != png_ptr->idat_size) 770 png_error(png_ptr, "save_size overflowed in pngpread"); 771 } 772 else 773 save_size = png_ptr->save_buffer_size; 774 775 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); 776 777 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 778 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); 779 780 png_ptr->idat_size -= save_size; 781 png_ptr->buffer_size -= save_size; 782 png_ptr->save_buffer_size -= save_size; 783 png_ptr->save_buffer_ptr += save_size; 784 } 785 if (png_ptr->idat_size && png_ptr->current_buffer_size) 786 { 787 png_size_t save_size; 788 789 if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) 790 { 791 save_size = (png_size_t)png_ptr->idat_size; 792 793 /* Check for overflow */ 794 if ((png_uint_32)save_size != png_ptr->idat_size) 795 png_error(png_ptr, "save_size overflowed in pngpread"); 796 } 797 else 798 save_size = png_ptr->current_buffer_size; 799 800 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); 801 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 802 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); 803 804 png_ptr->idat_size -= save_size; 805 png_ptr->buffer_size -= save_size; 806 png_ptr->current_buffer_size -= save_size; 807 png_ptr->current_buffer_ptr += save_size; 808 } 809 if (!png_ptr->idat_size) 810 { 811 if (png_ptr->buffer_size < 4) 812 { 813 png_push_save_buffer(png_ptr); 814 return; 815 } 816 817 png_crc_finish(png_ptr, 0); 818 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 819 png_ptr->mode |= PNG_AFTER_IDAT; 820 } 821} 822 823void /* PRIVATE */ 824png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, 825 png_size_t buffer_length) 826{ 827 int ret; 828 829 if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length) 830 png_error(png_ptr, "Extra compression data"); 831 832 png_ptr->zstream.next_in = buffer; 833 png_ptr->zstream.avail_in = (uInt)buffer_length; 834 for (;;) 835 { 836 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 837 if (ret != Z_OK) 838 { 839 if (ret == Z_STREAM_END) 840 { 841 if (png_ptr->zstream.avail_in) 842 png_error(png_ptr, "Extra compressed data"); 843 844 if (!(png_ptr->zstream.avail_out)) 845 { 846 png_push_process_row(png_ptr); 847 } 848 849 png_ptr->mode |= PNG_AFTER_IDAT; 850 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 851 break; 852 } 853 else if (ret == Z_BUF_ERROR) 854 break; 855 856 else 857 png_error(png_ptr, "Decompression Error"); 858 } 859 if (!(png_ptr->zstream.avail_out)) 860 { 861 if (( 862#if defined(PNG_READ_INTERLACING_SUPPORTED) 863 png_ptr->interlaced && png_ptr->pass > 6) || 864 (!png_ptr->interlaced && 865#endif 866 png_ptr->row_number == png_ptr->num_rows)) 867 { 868 if (png_ptr->zstream.avail_in) 869 png_warning(png_ptr, "Too much data in IDAT chunks"); 870 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 871 break; 872 } 873 png_push_process_row(png_ptr); 874 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; 875 png_ptr->zstream.next_out = png_ptr->row_buf; 876 } 877 878 else 879 break; 880 } 881} 882 883void /* PRIVATE */ 884png_push_process_row(png_structp png_ptr) 885{ 886 png_ptr->row_info.color_type = png_ptr->color_type; 887 png_ptr->row_info.width = png_ptr->iwidth; 888 png_ptr->row_info.channels = png_ptr->channels; 889 png_ptr->row_info.bit_depth = png_ptr->bit_depth; 890 png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; 891 892 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, 893 png_ptr->row_info.width); 894 895 png_read_filter_row(png_ptr, &(png_ptr->row_info), 896 png_ptr->row_buf + 1, png_ptr->prev_row + 1, 897 (int)(png_ptr->row_buf[0])); 898 899 png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, 900 png_ptr->rowbytes + 1); 901 902 if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) 903 png_do_read_transformations(png_ptr); 904 905#if defined(PNG_READ_INTERLACING_SUPPORTED) 906 /* Blow up interlaced rows to full size */ 907 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) 908 { 909 if (png_ptr->pass < 6) 910/* old interface (pre-1.0.9): 911 png_do_read_interlace(&(png_ptr->row_info), 912 png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); 913 */ 914 png_do_read_interlace(png_ptr); 915 916 switch (png_ptr->pass) 917 { 918 case 0: 919 { 920 int i; 921 for (i = 0; i < 8 && png_ptr->pass == 0; i++) 922 { 923 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 924 png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ 925 } 926 927 if (png_ptr->pass == 2) /* Pass 1 might be empty */ 928 { 929 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 930 { 931 png_push_have_row(png_ptr, png_bytep_NULL); 932 png_read_push_finish_row(png_ptr); 933 } 934 } 935 936 if (png_ptr->pass == 4 && png_ptr->height <= 4) 937 { 938 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 939 { 940 png_push_have_row(png_ptr, png_bytep_NULL); 941 png_read_push_finish_row(png_ptr); 942 } 943 } 944 945 if (png_ptr->pass == 6 && png_ptr->height <= 4) 946 { 947 png_push_have_row(png_ptr, png_bytep_NULL); 948 png_read_push_finish_row(png_ptr); 949 } 950 951 break; 952 } 953 954 case 1: 955 { 956 int i; 957 for (i = 0; i < 8 && png_ptr->pass == 1; i++) 958 { 959 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 960 png_read_push_finish_row(png_ptr); 961 } 962 963 if (png_ptr->pass == 2) /* Skip top 4 generated rows */ 964 { 965 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 966 { 967 png_push_have_row(png_ptr, png_bytep_NULL); 968 png_read_push_finish_row(png_ptr); 969 } 970 } 971 972 break; 973 } 974 975 case 2: 976 { 977 int i; 978 979 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 980 { 981 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 982 png_read_push_finish_row(png_ptr); 983 } 984 985 for (i = 0; i < 4 && png_ptr->pass == 2; i++) 986 { 987 png_push_have_row(png_ptr, png_bytep_NULL); 988 png_read_push_finish_row(png_ptr); 989 } 990 991 if (png_ptr->pass == 4) /* Pass 3 might be empty */ 992 { 993 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 994 { 995 png_push_have_row(png_ptr, png_bytep_NULL); 996 png_read_push_finish_row(png_ptr); 997 } 998 } 999 1000 break; 1001 } 1002 1003 case 3: 1004 { 1005 int i; 1006 1007 for (i = 0; i < 4 && png_ptr->pass == 3; i++) 1008 { 1009 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1010 png_read_push_finish_row(png_ptr); 1011 } 1012 1013 if (png_ptr->pass == 4) /* Skip top two generated rows */ 1014 { 1015 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1016 { 1017 png_push_have_row(png_ptr, png_bytep_NULL); 1018 png_read_push_finish_row(png_ptr); 1019 } 1020 } 1021 1022 break; 1023 } 1024 1025 case 4: 1026 { 1027 int i; 1028 1029 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1030 { 1031 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1032 png_read_push_finish_row(png_ptr); 1033 } 1034 1035 for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1036 { 1037 png_push_have_row(png_ptr, png_bytep_NULL); 1038 png_read_push_finish_row(png_ptr); 1039 } 1040 1041 if (png_ptr->pass == 6) /* Pass 5 might be empty */ 1042 { 1043 png_push_have_row(png_ptr, png_bytep_NULL); 1044 png_read_push_finish_row(png_ptr); 1045 } 1046 1047 break; 1048 } 1049 1050 case 5: 1051 { 1052 int i; 1053 1054 for (i = 0; i < 2 && png_ptr->pass == 5; i++) 1055 { 1056 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1057 png_read_push_finish_row(png_ptr); 1058 } 1059 1060 if (png_ptr->pass == 6) /* Skip top generated row */ 1061 { 1062 png_push_have_row(png_ptr, png_bytep_NULL); 1063 png_read_push_finish_row(png_ptr); 1064 } 1065 1066 break; 1067 } 1068 case 6: 1069 { 1070 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1071 png_read_push_finish_row(png_ptr); 1072 1073 if (png_ptr->pass != 6) 1074 break; 1075 1076 png_push_have_row(png_ptr, png_bytep_NULL); 1077 png_read_push_finish_row(png_ptr); 1078 } 1079 } 1080 } 1081 else 1082#endif 1083 { 1084 png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1085 png_read_push_finish_row(png_ptr); 1086 } 1087} 1088 1089void /* PRIVATE */ 1090png_read_push_finish_row(png_structp png_ptr) 1091{ 1092#ifdef PNG_USE_LOCAL_ARRAYS 1093 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1094 1095 /* Start of interlace block */ 1096 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; 1097 1098 /* Offset to next interlace block */ 1099 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; 1100 1101 /* Start of interlace block in the y direction */ 1102 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; 1103 1104 /* Offset to next interlace block in the y direction */ 1105 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; 1106 1107 /* Height of interlace block. This is not currently used - if you need 1108 * it, uncomment it here and in png.h 1109 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; 1110 */ 1111#endif 1112 1113 png_ptr->row_number++; 1114 if (png_ptr->row_number < png_ptr->num_rows) 1115 return; 1116 1117#if defined(PNG_READ_INTERLACING_SUPPORTED) 1118 if (png_ptr->interlaced) 1119 { 1120 png_ptr->row_number = 0; 1121 png_memset_check(png_ptr, png_ptr->prev_row, 0, 1122 png_ptr->rowbytes + 1); 1123 do 1124 { 1125 png_ptr->pass++; 1126 if ((png_ptr->pass == 1 && png_ptr->width < 5) || 1127 (png_ptr->pass == 3 && png_ptr->width < 3) || 1128 (png_ptr->pass == 5 && png_ptr->width < 2)) 1129 png_ptr->pass++; 1130 1131 if (png_ptr->pass > 7) 1132 png_ptr->pass--; 1133 1134 if (png_ptr->pass >= 7) 1135 break; 1136 1137 png_ptr->iwidth = (png_ptr->width + 1138 png_pass_inc[png_ptr->pass] - 1 - 1139 png_pass_start[png_ptr->pass]) / 1140 png_pass_inc[png_ptr->pass]; 1141 1142 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, 1143 png_ptr->iwidth) + 1; 1144 1145 if (png_ptr->transformations & PNG_INTERLACE) 1146 break; 1147 1148 png_ptr->num_rows = (png_ptr->height + 1149 png_pass_yinc[png_ptr->pass] - 1 - 1150 png_pass_ystart[png_ptr->pass]) / 1151 png_pass_yinc[png_ptr->pass]; 1152 1153 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); 1154 } 1155#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1156} 1157 1158#if defined(PNG_READ_tEXt_SUPPORTED) 1159void /* PRIVATE */ 1160png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 1161 length) 1162{ 1163 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) 1164 { 1165 png_error(png_ptr, "Out of place tEXt"); 1166 info_ptr = info_ptr; /* To quiet some compiler warnings */ 1167 } 1168 1169#ifdef PNG_MAX_MALLOC_64K 1170 png_ptr->skip_length = 0; /* This may not be necessary */ 1171 1172 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ 1173 { 1174 png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 1175 png_ptr->skip_length = length - (png_uint_32)65535L; 1176 length = (png_uint_32)65535L; 1177 } 1178#endif 1179 1180 png_ptr->current_text = (png_charp)png_malloc(png_ptr, 1181 (png_uint_32)(length + 1)); 1182 png_ptr->current_text[length] = '\0'; 1183 png_ptr->current_text_ptr = png_ptr->current_text; 1184 png_ptr->current_text_size = (png_size_t)length; 1185 png_ptr->current_text_left = (png_size_t)length; 1186 png_ptr->process_mode = PNG_READ_tEXt_MODE; 1187} 1188 1189void /* PRIVATE */ 1190png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) 1191{ 1192 if (png_ptr->buffer_size && png_ptr->current_text_left) 1193 { 1194 png_size_t text_size; 1195 1196 if (png_ptr->buffer_size < png_ptr->current_text_left) 1197 text_size = png_ptr->buffer_size; 1198 1199 else 1200 text_size = png_ptr->current_text_left; 1201 1202 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); 1203 png_ptr->current_text_left -= text_size; 1204 png_ptr->current_text_ptr += text_size; 1205 } 1206 if (!(png_ptr->current_text_left)) 1207 { 1208 png_textp text_ptr; 1209 png_charp text; 1210 png_charp key; 1211 int ret; 1212 1213 if (png_ptr->buffer_size < 4) 1214 { 1215 png_push_save_buffer(png_ptr); 1216 return; 1217 } 1218 1219 png_push_crc_finish(png_ptr); 1220 1221#if defined(PNG_MAX_MALLOC_64K) 1222 if (png_ptr->skip_length) 1223 return; 1224#endif 1225 1226 key = png_ptr->current_text; 1227 1228 for (text = key; *text; text++) 1229 /* Empty loop */ ; 1230 1231 if (text < key + png_ptr->current_text_size) 1232 text++; 1233 1234 text_ptr = (png_textp)png_malloc(png_ptr, 1235 (png_uint_32)png_sizeof(png_text)); 1236 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 1237 text_ptr->key = key; 1238#ifdef PNG_iTXt_SUPPORTED 1239 text_ptr->lang = NULL; 1240 text_ptr->lang_key = NULL; 1241#endif 1242 text_ptr->text = text; 1243 1244 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 1245 1246 png_free(png_ptr, key); 1247 png_free(png_ptr, text_ptr); 1248 png_ptr->current_text = NULL; 1249 1250 if (ret) 1251 png_warning(png_ptr, "Insufficient memory to store text chunk."); 1252 } 1253} 1254#endif 1255 1256#if defined(PNG_READ_zTXt_SUPPORTED) 1257void /* PRIVATE */ 1258png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 1259 length) 1260{ 1261 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) 1262 { 1263 png_error(png_ptr, "Out of place zTXt"); 1264 info_ptr = info_ptr; /* To quiet some compiler warnings */ 1265 } 1266 1267#ifdef PNG_MAX_MALLOC_64K 1268 /* We can't handle zTXt chunks > 64K, since we don't have enough space 1269 * to be able to store the uncompressed data. Actually, the threshold 1270 * is probably around 32K, but it isn't as definite as 64K is. 1271 */ 1272 if (length > (png_uint_32)65535L) 1273 { 1274 png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 1275 png_push_crc_skip(png_ptr, length); 1276 return; 1277 } 1278#endif 1279 1280 png_ptr->current_text = (png_charp)png_malloc(png_ptr, 1281 (png_uint_32)(length + 1)); 1282 png_ptr->current_text[length] = '\0'; 1283 png_ptr->current_text_ptr = png_ptr->current_text; 1284 png_ptr->current_text_size = (png_size_t)length; 1285 png_ptr->current_text_left = (png_size_t)length; 1286 png_ptr->process_mode = PNG_READ_zTXt_MODE; 1287} 1288 1289void /* PRIVATE */ 1290png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) 1291{ 1292 if (png_ptr->buffer_size && png_ptr->current_text_left) 1293 { 1294 png_size_t text_size; 1295 1296 if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) 1297 text_size = png_ptr->buffer_size; 1298 1299 else 1300 text_size = png_ptr->current_text_left; 1301 1302 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); 1303 png_ptr->current_text_left -= text_size; 1304 png_ptr->current_text_ptr += text_size; 1305 } 1306 if (!(png_ptr->current_text_left)) 1307 { 1308 png_textp text_ptr; 1309 png_charp text; 1310 png_charp key; 1311 int ret; 1312 png_size_t text_size, key_size; 1313 1314 if (png_ptr->buffer_size < 4) 1315 { 1316 png_push_save_buffer(png_ptr); 1317 return; 1318 } 1319 1320 png_push_crc_finish(png_ptr); 1321 1322 key = png_ptr->current_text; 1323 1324 for (text = key; *text; text++) 1325 /* Empty loop */ ; 1326 1327 /* zTXt can't have zero text */ 1328 if (text >= key + png_ptr->current_text_size) 1329 { 1330 png_ptr->current_text = NULL; 1331 png_free(png_ptr, key); 1332 return; 1333 } 1334 1335 text++; 1336 1337 if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ 1338 { 1339 png_ptr->current_text = NULL; 1340 png_free(png_ptr, key); 1341 return; 1342 } 1343 1344 text++; 1345 1346 png_ptr->zstream.next_in = (png_bytep )text; 1347 png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - 1348 (text - key)); 1349 png_ptr->zstream.next_out = png_ptr->zbuf; 1350 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 1351 1352 key_size = text - key; 1353 text_size = 0; 1354 text = NULL; 1355 ret = Z_STREAM_END; 1356 1357 while (png_ptr->zstream.avail_in) 1358 { 1359 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 1360 if (ret != Z_OK && ret != Z_STREAM_END) 1361 { 1362 inflateReset(&png_ptr->zstream); 1363 png_ptr->zstream.avail_in = 0; 1364 png_ptr->current_text = NULL; 1365 png_free(png_ptr, key); 1366 png_free(png_ptr, text); 1367 return; 1368 } 1369 if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) 1370 { 1371 if (text == NULL) 1372 { 1373 text = (png_charp)png_malloc(png_ptr, 1374 (png_uint_32)(png_ptr->zbuf_size 1375 - png_ptr->zstream.avail_out + key_size + 1)); 1376 1377 png_memcpy(text + key_size, png_ptr->zbuf, 1378 png_ptr->zbuf_size - png_ptr->zstream.avail_out); 1379 1380 png_memcpy(text, key, key_size); 1381 1382 text_size = key_size + png_ptr->zbuf_size - 1383 png_ptr->zstream.avail_out; 1384 1385 *(text + text_size) = '\0'; 1386 } 1387 else 1388 { 1389 png_charp tmp; 1390 1391 tmp = text; 1392 text = (png_charp)png_malloc(png_ptr, text_size + 1393 (png_uint_32)(png_ptr->zbuf_size 1394 - png_ptr->zstream.avail_out + 1)); 1395 1396 png_memcpy(text, tmp, text_size); 1397 png_free(png_ptr, tmp); 1398 1399 png_memcpy(text + text_size, png_ptr->zbuf, 1400 png_ptr->zbuf_size - png_ptr->zstream.avail_out); 1401 1402 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; 1403 *(text + text_size) = '\0'; 1404 } 1405 if (ret != Z_STREAM_END) 1406 { 1407 png_ptr->zstream.next_out = png_ptr->zbuf; 1408 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 1409 } 1410 } 1411 else 1412 { 1413 break; 1414 } 1415 1416 if (ret == Z_STREAM_END) 1417 break; 1418 } 1419 1420 inflateReset(&png_ptr->zstream); 1421 png_ptr->zstream.avail_in = 0; 1422 1423 if (ret != Z_STREAM_END) 1424 { 1425 png_ptr->current_text = NULL; 1426 png_free(png_ptr, key); 1427 png_free(png_ptr, text); 1428 return; 1429 } 1430 1431 png_ptr->current_text = NULL; 1432 png_free(png_ptr, key); 1433 key = text; 1434 text += key_size; 1435 1436 text_ptr = (png_textp)png_malloc(png_ptr, 1437 (png_uint_32)png_sizeof(png_text)); 1438 text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; 1439 text_ptr->key = key; 1440#ifdef PNG_iTXt_SUPPORTED 1441 text_ptr->lang = NULL; 1442 text_ptr->lang_key = NULL; 1443#endif 1444 text_ptr->text = text; 1445 1446 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 1447 1448 png_free(png_ptr, key); 1449 png_free(png_ptr, text_ptr); 1450 1451 if (ret) 1452 png_warning(png_ptr, "Insufficient memory to store text chunk."); 1453 } 1454} 1455#endif 1456 1457#if defined(PNG_READ_iTXt_SUPPORTED) 1458void /* PRIVATE */ 1459png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 1460 length) 1461{ 1462 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) 1463 { 1464 png_error(png_ptr, "Out of place iTXt"); 1465 info_ptr = info_ptr; /* To quiet some compiler warnings */ 1466 } 1467 1468#ifdef PNG_MAX_MALLOC_64K 1469 png_ptr->skip_length = 0; /* This may not be necessary */ 1470 1471 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */ 1472 { 1473 png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 1474 png_ptr->skip_length = length - (png_uint_32)65535L; 1475 length = (png_uint_32)65535L; 1476 } 1477#endif 1478 1479 png_ptr->current_text = (png_charp)png_malloc(png_ptr, 1480 (png_uint_32)(length + 1)); 1481 png_ptr->current_text[length] = '\0'; 1482 png_ptr->current_text_ptr = png_ptr->current_text; 1483 png_ptr->current_text_size = (png_size_t)length; 1484 png_ptr->current_text_left = (png_size_t)length; 1485 png_ptr->process_mode = PNG_READ_iTXt_MODE; 1486} 1487 1488void /* PRIVATE */ 1489png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) 1490{ 1491 1492 if (png_ptr->buffer_size && png_ptr->current_text_left) 1493 { 1494 png_size_t text_size; 1495 1496 if (png_ptr->buffer_size < png_ptr->current_text_left) 1497 text_size = png_ptr->buffer_size; 1498 1499 else 1500 text_size = png_ptr->current_text_left; 1501 1502 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); 1503 png_ptr->current_text_left -= text_size; 1504 png_ptr->current_text_ptr += text_size; 1505 } 1506 if (!(png_ptr->current_text_left)) 1507 { 1508 png_textp text_ptr; 1509 png_charp key; 1510 int comp_flag; 1511 png_charp lang; 1512 png_charp lang_key; 1513 png_charp text; 1514 int ret; 1515 1516 if (png_ptr->buffer_size < 4) 1517 { 1518 png_push_save_buffer(png_ptr); 1519 return; 1520 } 1521 1522 png_push_crc_finish(png_ptr); 1523 1524#if defined(PNG_MAX_MALLOC_64K) 1525 if (png_ptr->skip_length) 1526 return; 1527#endif 1528 1529 key = png_ptr->current_text; 1530 1531 for (lang = key; *lang; lang++) 1532 /* Empty loop */ ; 1533 1534 if (lang < key + png_ptr->current_text_size - 3) 1535 lang++; 1536 1537 comp_flag = *lang++; 1538 lang++; /* Skip comp_type, always zero */ 1539 1540 for (lang_key = lang; *lang_key; lang_key++) 1541 /* Empty loop */ ; 1542 1543 lang_key++; /* Skip NUL separator */ 1544 1545 text=lang_key; 1546 1547 if (lang_key < key + png_ptr->current_text_size - 1) 1548 { 1549 for (; *text; text++) 1550 /* Empty loop */ ; 1551 } 1552 1553 if (text < key + png_ptr->current_text_size) 1554 text++; 1555 1556 text_ptr = (png_textp)png_malloc(png_ptr, 1557 (png_uint_32)png_sizeof(png_text)); 1558 1559 text_ptr->compression = comp_flag + 2; 1560 text_ptr->key = key; 1561 text_ptr->lang = lang; 1562 text_ptr->lang_key = lang_key; 1563 text_ptr->text = text; 1564 text_ptr->text_length = 0; 1565 text_ptr->itxt_length = png_strlen(text); 1566 1567 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 1568 1569 png_ptr->current_text = NULL; 1570 1571 png_free(png_ptr, text_ptr); 1572 if (ret) 1573 png_warning(png_ptr, "Insufficient memory to store iTXt chunk."); 1574 } 1575} 1576#endif 1577 1578/* This function is called when we haven't found a handler for this 1579 * chunk. If there isn't a problem with the chunk itself (ie a bad chunk 1580 * name or a critical chunk), the chunk is (currently) silently ignored. 1581 */ 1582void /* PRIVATE */ 1583png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 1584 length) 1585{ 1586 png_uint_32 skip = 0; 1587 1588 if (!(png_ptr->chunk_name[0] & 0x20)) 1589 { 1590#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 1591 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 1592 PNG_HANDLE_CHUNK_ALWAYS 1593#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 1594 && png_ptr->read_user_chunk_fn == NULL 1595#endif 1596 ) 1597#endif 1598 png_chunk_error(png_ptr, "unknown critical chunk"); 1599 1600 info_ptr = info_ptr; /* To quiet some compiler warnings */ 1601 } 1602 1603#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 1604 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) 1605 { 1606#ifdef PNG_MAX_MALLOC_64K 1607 if (length > (png_uint_32)65535L) 1608 { 1609 png_warning(png_ptr, "unknown chunk too large to fit in memory"); 1610 skip = length - (png_uint_32)65535L; 1611 length = (png_uint_32)65535L; 1612 } 1613#endif 1614 png_memcpy((png_charp)png_ptr->unknown_chunk.name, 1615 (png_charp)png_ptr->chunk_name, 1616 png_sizeof(png_ptr->unknown_chunk.name)); 1617 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] 1618 = '\0'; 1619 1620 png_ptr->unknown_chunk.size = (png_size_t)length; 1621 1622 if (length == 0) 1623 png_ptr->unknown_chunk.data = NULL; 1624 1625 else 1626 { 1627 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, 1628 (png_uint_32)length); 1629 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 1630 } 1631 1632#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) 1633 if (png_ptr->read_user_chunk_fn != NULL) 1634 { 1635 /* Callback to user unknown chunk handler */ 1636 int ret; 1637 ret = (*(png_ptr->read_user_chunk_fn)) 1638 (png_ptr, &png_ptr->unknown_chunk); 1639 1640 if (ret < 0) 1641 png_chunk_error(png_ptr, "error in user chunk"); 1642 1643 if (ret == 0) 1644 { 1645 if (!(png_ptr->chunk_name[0] & 0x20)) 1646 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 1647 PNG_HANDLE_CHUNK_ALWAYS) 1648 png_chunk_error(png_ptr, "unknown critical chunk"); 1649 png_set_unknown_chunks(png_ptr, info_ptr, 1650 &png_ptr->unknown_chunk, 1); 1651 } 1652 } 1653 1654 else 1655#endif 1656 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 1657 png_free(png_ptr, png_ptr->unknown_chunk.data); 1658 png_ptr->unknown_chunk.data = NULL; 1659 } 1660 1661 else 1662#endif 1663 skip=length; 1664 png_push_crc_skip(png_ptr, skip); 1665} 1666 1667void /* PRIVATE */ 1668png_push_have_info(png_structp png_ptr, png_infop info_ptr) 1669{ 1670 if (png_ptr->info_fn != NULL) 1671 (*(png_ptr->info_fn))(png_ptr, info_ptr); 1672} 1673 1674void /* PRIVATE */ 1675png_push_have_end(png_structp png_ptr, png_infop info_ptr) 1676{ 1677 if (png_ptr->end_fn != NULL) 1678 (*(png_ptr->end_fn))(png_ptr, info_ptr); 1679} 1680 1681void /* PRIVATE */ 1682png_push_have_row(png_structp png_ptr, png_bytep row) 1683{ 1684 if (png_ptr->row_fn != NULL) 1685 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, 1686 (int)png_ptr->pass); 1687} 1688 1689void PNGAPI 1690png_progressive_combine_row (png_structp png_ptr, 1691 png_bytep old_row, png_bytep new_row) 1692{ 1693#ifdef PNG_USE_LOCAL_ARRAYS 1694 PNG_CONST int FARDATA png_pass_dsp_mask[7] = 1695 {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; 1696#endif 1697 if (png_ptr == NULL) 1698 return; 1699 1700 if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ 1701 png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); 1702} 1703 1704void PNGAPI 1705png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, 1706 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, 1707 png_progressive_end_ptr end_fn) 1708{ 1709 if (png_ptr == NULL) 1710 return; 1711 1712 png_ptr->info_fn = info_fn; 1713 png_ptr->row_fn = row_fn; 1714 png_ptr->end_fn = end_fn; 1715 1716 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); 1717} 1718 1719png_voidp PNGAPI 1720png_get_progressive_ptr(png_structp png_ptr) 1721{ 1722 if (png_ptr == NULL) 1723 return (NULL); 1724 1725 return png_ptr->io_ptr; 1726} 1727#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ 1728