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