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