1 2 /* pngread.c - read a PNG file 3 * 4 * Last changed in libpng 1.5.10 [March 8, 2012] 5 * Copyright (c) 1998-2012 Glenn Randers-Pehrson 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 8 * 9 * This code is released under the libpng license. 10 * For conditions of distribution and use, see the disclaimer 11 * and license in png.h 12 * 13 * This file contains routines that an application calls directly to 14 * read a PNG file or stream. 15 */ 16 17 #include "pngpriv.h" 18 19 #ifdef PNG_READ_SUPPORTED 20 21 /* Create a PNG structure for reading, and allocate any memory needed. */ 22 PNG_FUNCTION(png_structp,PNGAPI 23 png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, 24 png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) 25 { 26 27 #ifdef PNG_USER_MEM_SUPPORTED 28 return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, 29 warn_fn, NULL, NULL, NULL)); 30 } 31 32 /* Alternate create PNG structure for reading, and allocate any memory 33 * needed. 34 */ 35 PNG_FUNCTION(png_structp,PNGAPI 36 png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, 37 png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, 38 png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) 39 { 40 #endif /* PNG_USER_MEM_SUPPORTED */ 41 42 #ifdef PNG_SETJMP_SUPPORTED 43 volatile 44 #endif 45 png_structp png_ptr; 46 volatile int png_cleanup_needed = 0; 47 48 #ifdef PNG_SETJMP_SUPPORTED 49 #ifdef USE_FAR_KEYWORD 50 jmp_buf tmp_jmpbuf; 51 #endif 52 #endif 53 54 png_debug(1, "in png_create_read_struct"); 55 56 #ifdef PNG_USER_MEM_SUPPORTED 57 png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, 58 malloc_fn, mem_ptr); 59 #else 60 png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); 61 #endif 62 if (png_ptr == NULL) 63 return (NULL); 64 65 /* Added at libpng-1.2.6 */ 66 #ifdef PNG_USER_LIMITS_SUPPORTED 67 png_ptr->user_width_max = PNG_USER_WIDTH_MAX; 68 png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; 69 70 /* Added at libpng-1.2.43 and 1.4.0 */ 71 png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; 72 73 /* Added at libpng-1.2.43 and 1.4.1 */ 74 png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; 75 #endif 76 77 #ifdef PNG_SETJMP_SUPPORTED 78 /* Applications that neglect to set up their own setjmp() and then 79 * encounter a png_error() will longjmp here. Since the jmpbuf is 80 * then meaningless we abort instead of returning. 81 */ 82 #ifdef USE_FAR_KEYWORD 83 if (setjmp(tmp_jmpbuf)) 84 #else 85 if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ 86 #endif 87 PNG_ABORT(); 88 #ifdef USE_FAR_KEYWORD 89 png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); 90 #endif 91 #endif /* PNG_SETJMP_SUPPORTED */ 92 93 #ifdef PNG_USER_MEM_SUPPORTED 94 png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); 95 #endif 96 97 png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); 98 99 /* Call the general version checker (shared with read and write code): */ 100 if (!png_user_version_check(png_ptr, user_png_ver)) 101 png_cleanup_needed = 1; 102 103 if (!png_cleanup_needed) 104 { 105 /* Initialize zbuf - compression buffer */ 106 png_ptr->zbuf_size = PNG_ZBUF_SIZE; 107 png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); 108 109 if (png_ptr->zbuf == NULL) 110 png_cleanup_needed = 1; 111 } 112 113 png_ptr->zstream.zalloc = png_zalloc; 114 png_ptr->zstream.zfree = png_zfree; 115 png_ptr->zstream.opaque = (voidpf)png_ptr; 116 117 if (!png_cleanup_needed) 118 { 119 switch (inflateInit(&png_ptr->zstream)) 120 { 121 case Z_OK: 122 break; /* Do nothing */ 123 124 case Z_MEM_ERROR: 125 png_warning(png_ptr, "zlib memory error"); 126 png_cleanup_needed = 1; 127 break; 128 129 case Z_STREAM_ERROR: 130 png_warning(png_ptr, "zlib stream error"); 131 png_cleanup_needed = 1; 132 break; 133 134 case Z_VERSION_ERROR: 135 png_warning(png_ptr, "zlib version error"); 136 png_cleanup_needed = 1; 137 break; 138 139 default: png_warning(png_ptr, "Unknown zlib error"); 140 png_cleanup_needed = 1; 141 } 142 } 143 144 if (png_cleanup_needed) 145 { 146 /* Clean up PNG structure and deallocate any memory. */ 147 png_free(png_ptr, png_ptr->zbuf); 148 png_ptr->zbuf = NULL; 149 #ifdef PNG_USER_MEM_SUPPORTED 150 png_destroy_struct_2((png_voidp)png_ptr, 151 (png_free_ptr)free_fn, (png_voidp)mem_ptr); 152 #else 153 png_destroy_struct((png_voidp)png_ptr); 154 #endif 155 return (NULL); 156 } 157 158 png_ptr->zstream.next_out = png_ptr->zbuf; 159 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 160 161 png_set_read_fn(png_ptr, NULL, NULL); 162 163 164 return (png_ptr); 165 } 166 167 168 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 169 /* Read the information before the actual image data. This has been 170 * changed in v0.90 to allow reading a file that already has the magic 171 * bytes read from the stream. You can tell libpng how many bytes have 172 * been read from the beginning of the stream (up to the maximum of 8) 173 * via png_set_sig_bytes(), and we will only check the remaining bytes 174 * here. The application can then have access to the signature bytes we 175 * read if it is determined that this isn't a valid PNG file. 176 */ 177 void PNGAPI 178 png_read_info(png_structp png_ptr, png_infop info_ptr) 179 { 180 png_debug(1, "in png_read_info"); 181 182 if (png_ptr == NULL || info_ptr == NULL) 183 return; 184 185 /* Read and check the PNG file signature. */ 186 png_read_sig(png_ptr, info_ptr); 187 188 for (;;) 189 { 190 png_uint_32 length = png_read_chunk_header(png_ptr); 191 png_uint_32 chunk_name = png_ptr->chunk_name; 192 193 /* This should be a binary subdivision search or a hash for 194 * matching the chunk name rather than a linear search. 195 */ 196 if (chunk_name == png_IDAT) 197 if (png_ptr->mode & PNG_AFTER_IDAT) 198 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 199 200 if (chunk_name == png_IHDR) 201 png_handle_IHDR(png_ptr, info_ptr, length); 202 203 else if (chunk_name == png_IEND) 204 png_handle_IEND(png_ptr, info_ptr, length); 205 206 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 207 else if (png_chunk_unknown_handling(png_ptr, chunk_name) != 208 PNG_HANDLE_CHUNK_AS_DEFAULT) 209 { 210 if (chunk_name == png_IDAT) 211 png_ptr->mode |= PNG_HAVE_IDAT; 212 213 png_handle_unknown(png_ptr, info_ptr, length); 214 215 if (chunk_name == png_PLTE) 216 png_ptr->mode |= PNG_HAVE_PLTE; 217 218 else if (chunk_name == png_IDAT) 219 { 220 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 221 png_error(png_ptr, "Missing IHDR before IDAT"); 222 223 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 224 !(png_ptr->mode & PNG_HAVE_PLTE)) 225 png_error(png_ptr, "Missing PLTE before IDAT"); 226 227 break; 228 } 229 } 230 #endif 231 else if (chunk_name == png_PLTE) 232 png_handle_PLTE(png_ptr, info_ptr, length); 233 234 else if (chunk_name == png_IDAT) 235 { 236 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 237 png_error(png_ptr, "Missing IHDR before IDAT"); 238 239 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 240 !(png_ptr->mode & PNG_HAVE_PLTE)) 241 png_error(png_ptr, "Missing PLTE before IDAT"); 242 243 png_ptr->idat_size = length; 244 png_ptr->mode |= PNG_HAVE_IDAT; 245 break; 246 } 247 248 #ifdef PNG_READ_bKGD_SUPPORTED 249 else if (chunk_name == png_bKGD) 250 png_handle_bKGD(png_ptr, info_ptr, length); 251 #endif 252 253 #ifdef PNG_READ_cHRM_SUPPORTED 254 else if (chunk_name == png_cHRM) 255 png_handle_cHRM(png_ptr, info_ptr, length); 256 #endif 257 258 #ifdef PNG_READ_gAMA_SUPPORTED 259 else if (chunk_name == png_gAMA) 260 png_handle_gAMA(png_ptr, info_ptr, length); 261 #endif 262 263 #ifdef PNG_READ_hIST_SUPPORTED 264 else if (chunk_name == png_hIST) 265 png_handle_hIST(png_ptr, info_ptr, length); 266 #endif 267 268 #ifdef PNG_READ_oFFs_SUPPORTED 269 else if (chunk_name == png_oFFs) 270 png_handle_oFFs(png_ptr, info_ptr, length); 271 #endif 272 273 #ifdef PNG_READ_pCAL_SUPPORTED 274 else if (chunk_name == png_pCAL) 275 png_handle_pCAL(png_ptr, info_ptr, length); 276 #endif 277 278 #ifdef PNG_READ_sCAL_SUPPORTED 279 else if (chunk_name == png_sCAL) 280 png_handle_sCAL(png_ptr, info_ptr, length); 281 #endif 282 283 #ifdef PNG_READ_pHYs_SUPPORTED 284 else if (chunk_name == png_pHYs) 285 png_handle_pHYs(png_ptr, info_ptr, length); 286 #endif 287 288 #ifdef PNG_READ_sBIT_SUPPORTED 289 else if (chunk_name == png_sBIT) 290 png_handle_sBIT(png_ptr, info_ptr, length); 291 #endif 292 293 #ifdef PNG_READ_sRGB_SUPPORTED 294 else if (chunk_name == png_sRGB) 295 png_handle_sRGB(png_ptr, info_ptr, length); 296 #endif 297 298 #ifdef PNG_READ_iCCP_SUPPORTED 299 else if (chunk_name == png_iCCP) 300 png_handle_iCCP(png_ptr, info_ptr, length); 301 #endif 302 303 #ifdef PNG_READ_sPLT_SUPPORTED 304 else if (chunk_name == png_sPLT) 305 png_handle_sPLT(png_ptr, info_ptr, length); 306 #endif 307 308 #ifdef PNG_READ_tEXt_SUPPORTED 309 else if (chunk_name == png_tEXt) 310 png_handle_tEXt(png_ptr, info_ptr, length); 311 #endif 312 313 #ifdef PNG_READ_tIME_SUPPORTED 314 else if (chunk_name == png_tIME) 315 png_handle_tIME(png_ptr, info_ptr, length); 316 #endif 317 318 #ifdef PNG_READ_tRNS_SUPPORTED 319 else if (chunk_name == png_tRNS) 320 png_handle_tRNS(png_ptr, info_ptr, length); 321 #endif 322 323 #ifdef PNG_READ_zTXt_SUPPORTED 324 else if (chunk_name == png_zTXt) 325 png_handle_zTXt(png_ptr, info_ptr, length); 326 #endif 327 328 #ifdef PNG_READ_iTXt_SUPPORTED 329 else if (chunk_name == png_iTXt) 330 png_handle_iTXt(png_ptr, info_ptr, length); 331 #endif 332 333 else 334 png_handle_unknown(png_ptr, info_ptr, length); 335 } 336 } 337 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 338 339 /* Optional call to update the users info_ptr structure */ 340 void PNGAPI 341 png_read_update_info(png_structp png_ptr, png_infop info_ptr) 342 { 343 png_debug(1, "in png_read_update_info"); 344 345 if (png_ptr == NULL) 346 return; 347 348 png_read_start_row(png_ptr); 349 350 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 351 png_read_transform_info(png_ptr, info_ptr); 352 #else 353 PNG_UNUSED(info_ptr) 354 #endif 355 } 356 357 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 358 /* Initialize palette, background, etc, after transformations 359 * are set, but before any reading takes place. This allows 360 * the user to obtain a gamma-corrected palette, for example. 361 * If the user doesn't call this, we will do it ourselves. 362 */ 363 void PNGAPI 364 png_start_read_image(png_structp png_ptr) 365 { 366 png_debug(1, "in png_start_read_image"); 367 368 if (png_ptr != NULL) 369 png_read_start_row(png_ptr); 370 } 371 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 372 373 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 374 void PNGAPI 375 png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) 376 { 377 int ret; 378 379 png_row_info row_info; 380 381 if (png_ptr == NULL) 382 return; 383 384 png_debug2(1, "in png_read_row (row %lu, pass %d)", 385 (unsigned long)png_ptr->row_number, png_ptr->pass); 386 387 /* png_read_start_row sets the information (in particular iwidth) for this 388 * interlace pass. 389 */ 390 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 391 png_read_start_row(png_ptr); 392 393 /* 1.5.6: row_info moved out of png_struct to a local here. */ 394 row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ 395 row_info.color_type = png_ptr->color_type; 396 row_info.bit_depth = png_ptr->bit_depth; 397 row_info.channels = png_ptr->channels; 398 row_info.pixel_depth = png_ptr->pixel_depth; 399 row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); 400 401 if (png_ptr->row_number == 0 && png_ptr->pass == 0) 402 { 403 /* Check for transforms that have been set but were defined out */ 404 #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) 405 if (png_ptr->transformations & PNG_INVERT_MONO) 406 png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); 407 #endif 408 409 #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) 410 if (png_ptr->transformations & PNG_FILLER) 411 png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); 412 #endif 413 414 #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ 415 !defined(PNG_READ_PACKSWAP_SUPPORTED) 416 if (png_ptr->transformations & PNG_PACKSWAP) 417 png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); 418 #endif 419 420 #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) 421 if (png_ptr->transformations & PNG_PACK) 422 png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); 423 #endif 424 425 #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) 426 if (png_ptr->transformations & PNG_SHIFT) 427 png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); 428 #endif 429 430 #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) 431 if (png_ptr->transformations & PNG_BGR) 432 png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); 433 #endif 434 435 #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) 436 if (png_ptr->transformations & PNG_SWAP_BYTES) 437 png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); 438 #endif 439 } 440 441 #ifdef PNG_READ_INTERLACING_SUPPORTED 442 /* If interlaced and we do not need a new row, combine row and return. 443 * Notice that the pixels we have from previous rows have been transformed 444 * already; we can only combine like with like (transformed or 445 * untransformed) and, because of the libpng API for interlaced images, this 446 * means we must transform before de-interlacing. 447 */ 448 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) 449 { 450 switch (png_ptr->pass) 451 { 452 case 0: 453 if (png_ptr->row_number & 0x07) 454 { 455 if (dsp_row != NULL) 456 png_combine_row(png_ptr, dsp_row, 1/*display*/); 457 png_read_finish_row(png_ptr); 458 return; 459 } 460 break; 461 462 case 1: 463 if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) 464 { 465 if (dsp_row != NULL) 466 png_combine_row(png_ptr, dsp_row, 1/*display*/); 467 468 png_read_finish_row(png_ptr); 469 return; 470 } 471 break; 472 473 case 2: 474 if ((png_ptr->row_number & 0x07) != 4) 475 { 476 if (dsp_row != NULL && (png_ptr->row_number & 4)) 477 png_combine_row(png_ptr, dsp_row, 1/*display*/); 478 479 png_read_finish_row(png_ptr); 480 return; 481 } 482 break; 483 484 case 3: 485 if ((png_ptr->row_number & 3) || png_ptr->width < 3) 486 { 487 if (dsp_row != NULL) 488 png_combine_row(png_ptr, dsp_row, 1/*display*/); 489 490 png_read_finish_row(png_ptr); 491 return; 492 } 493 break; 494 495 case 4: 496 if ((png_ptr->row_number & 3) != 2) 497 { 498 if (dsp_row != NULL && (png_ptr->row_number & 2)) 499 png_combine_row(png_ptr, dsp_row, 1/*display*/); 500 501 png_read_finish_row(png_ptr); 502 return; 503 } 504 break; 505 case 5: 506 if ((png_ptr->row_number & 1) || png_ptr->width < 2) 507 { 508 if (dsp_row != NULL) 509 png_combine_row(png_ptr, dsp_row, 1/*display*/); 510 511 png_read_finish_row(png_ptr); 512 return; 513 } 514 break; 515 516 default: 517 case 6: 518 if (!(png_ptr->row_number & 1)) 519 { 520 png_read_finish_row(png_ptr); 521 return; 522 } 523 break; 524 } 525 } 526 #endif 527 528 if (!(png_ptr->mode & PNG_HAVE_IDAT)) 529 png_error(png_ptr, "Invalid attempt to read row data"); 530 531 png_ptr->zstream.next_out = png_ptr->row_buf; 532 png_ptr->zstream.avail_out = 533 (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, 534 png_ptr->iwidth) + 1); 535 536 do 537 { 538 if (!(png_ptr->zstream.avail_in)) 539 { 540 while (!png_ptr->idat_size) 541 { 542 png_crc_finish(png_ptr, 0); 543 544 png_ptr->idat_size = png_read_chunk_header(png_ptr); 545 if (png_ptr->chunk_name != png_IDAT) 546 png_error(png_ptr, "Not enough image data"); 547 } 548 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 549 png_ptr->zstream.next_in = png_ptr->zbuf; 550 if (png_ptr->zbuf_size > png_ptr->idat_size) 551 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 552 png_crc_read(png_ptr, png_ptr->zbuf, 553 (png_size_t)png_ptr->zstream.avail_in); 554 png_ptr->idat_size -= png_ptr->zstream.avail_in; 555 } 556 557 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 558 559 if (ret == Z_STREAM_END) 560 { 561 if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || 562 png_ptr->idat_size) 563 png_benign_error(png_ptr, "Extra compressed data"); 564 png_ptr->mode |= PNG_AFTER_IDAT; 565 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 566 break; 567 } 568 569 if (ret != Z_OK) 570 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 571 "Decompression error"); 572 573 } while (png_ptr->zstream.avail_out); 574 575 if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) 576 { 577 if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) 578 png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, 579 png_ptr->prev_row + 1, png_ptr->row_buf[0]); 580 else 581 png_error(png_ptr, "bad adaptive filter value"); 582 } 583 584 /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before 585 * 1.5.6, while the buffer really is this big in current versions of libpng 586 * it may not be in the future, so this was changed just to copy the 587 * interlaced count: 588 */ 589 png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); 590 591 #ifdef PNG_MNG_FEATURES_SUPPORTED 592 if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 593 (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) 594 { 595 /* Intrapixel differencing */ 596 png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); 597 } 598 #endif 599 600 601 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 602 if (png_ptr->transformations) 603 png_do_read_transformations(png_ptr, &row_info); 604 #endif 605 606 /* The transformed pixel depth should match the depth now in row_info. */ 607 if (png_ptr->transformed_pixel_depth == 0) 608 { 609 png_ptr->transformed_pixel_depth = row_info.pixel_depth; 610 if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) 611 png_error(png_ptr, "sequential row overflow"); 612 } 613 614 else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) 615 png_error(png_ptr, "internal sequential row size calculation error"); 616 617 #ifdef PNG_READ_INTERLACING_SUPPORTED 618 /* Blow up interlaced rows to full size */ 619 if (png_ptr->interlaced && 620 (png_ptr->transformations & PNG_INTERLACE)) 621 { 622 if (png_ptr->pass < 6) 623 png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, 624 png_ptr->transformations); 625 626 if (dsp_row != NULL) 627 png_combine_row(png_ptr, dsp_row, 1/*display*/); 628 629 if (row != NULL) 630 png_combine_row(png_ptr, row, 0/*row*/); 631 } 632 633 else 634 #endif 635 { 636 if (row != NULL) 637 png_combine_row(png_ptr, row, -1/*ignored*/); 638 639 if (dsp_row != NULL) 640 png_combine_row(png_ptr, dsp_row, -1/*ignored*/); 641 } 642 png_read_finish_row(png_ptr); 643 644 if (png_ptr->read_row_fn != NULL) 645 (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); 646 } 647 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 648 649 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 650 /* Read one or more rows of image data. If the image is interlaced, 651 * and png_set_interlace_handling() has been called, the rows need to 652 * contain the contents of the rows from the previous pass. If the 653 * image has alpha or transparency, and png_handle_alpha()[*] has been 654 * called, the rows contents must be initialized to the contents of the 655 * screen. 656 * 657 * "row" holds the actual image, and pixels are placed in it 658 * as they arrive. If the image is displayed after each pass, it will 659 * appear to "sparkle" in. "display_row" can be used to display a 660 * "chunky" progressive image, with finer detail added as it becomes 661 * available. If you do not want this "chunky" display, you may pass 662 * NULL for display_row. If you do not want the sparkle display, and 663 * you have not called png_handle_alpha(), you may pass NULL for rows. 664 * If you have called png_handle_alpha(), and the image has either an 665 * alpha channel or a transparency chunk, you must provide a buffer for 666 * rows. In this case, you do not have to provide a display_row buffer 667 * also, but you may. If the image is not interlaced, or if you have 668 * not called png_set_interlace_handling(), the display_row buffer will 669 * be ignored, so pass NULL to it. 670 * 671 * [*] png_handle_alpha() does not exist yet, as of this version of libpng 672 */ 673 674 void PNGAPI 675 png_read_rows(png_structp png_ptr, png_bytepp row, 676 png_bytepp display_row, png_uint_32 num_rows) 677 { 678 png_uint_32 i; 679 png_bytepp rp; 680 png_bytepp dp; 681 682 png_debug(1, "in png_read_rows"); 683 684 if (png_ptr == NULL) 685 return; 686 687 rp = row; 688 dp = display_row; 689 if (rp != NULL && dp != NULL) 690 for (i = 0; i < num_rows; i++) 691 { 692 png_bytep rptr = *rp++; 693 png_bytep dptr = *dp++; 694 695 png_read_row(png_ptr, rptr, dptr); 696 } 697 698 else if (rp != NULL) 699 for (i = 0; i < num_rows; i++) 700 { 701 png_bytep rptr = *rp; 702 png_read_row(png_ptr, rptr, NULL); 703 rp++; 704 } 705 706 else if (dp != NULL) 707 for (i = 0; i < num_rows; i++) 708 { 709 png_bytep dptr = *dp; 710 png_read_row(png_ptr, NULL, dptr); 711 dp++; 712 } 713 } 714 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 715 716 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 717 /* Read the entire image. If the image has an alpha channel or a tRNS 718 * chunk, and you have called png_handle_alpha()[*], you will need to 719 * initialize the image to the current image that PNG will be overlaying. 720 * We set the num_rows again here, in case it was incorrectly set in 721 * png_read_start_row() by a call to png_read_update_info() or 722 * png_start_read_image() if png_set_interlace_handling() wasn't called 723 * prior to either of these functions like it should have been. You can 724 * only call this function once. If you desire to have an image for 725 * each pass of a interlaced image, use png_read_rows() instead. 726 * 727 * [*] png_handle_alpha() does not exist yet, as of this version of libpng 728 */ 729 void PNGAPI 730 png_read_image(png_structp png_ptr, png_bytepp image) 731 { 732 png_uint_32 i, image_height; 733 int pass, j; 734 png_bytepp rp; 735 736 png_debug(1, "in png_read_image"); 737 738 if (png_ptr == NULL) 739 return; 740 741 #ifdef PNG_READ_INTERLACING_SUPPORTED 742 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 743 { 744 pass = png_set_interlace_handling(png_ptr); 745 /* And make sure transforms are initialized. */ 746 png_start_read_image(png_ptr); 747 } 748 else 749 { 750 if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) 751 { 752 /* Caller called png_start_read_image or png_read_update_info without 753 * first turning on the PNG_INTERLACE transform. We can fix this here, 754 * but the caller should do it! 755 */ 756 png_warning(png_ptr, "Interlace handling should be turned on when " 757 "using png_read_image"); 758 /* Make sure this is set correctly */ 759 png_ptr->num_rows = png_ptr->height; 760 } 761 762 /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in 763 * the above error case. 764 */ 765 pass = png_set_interlace_handling(png_ptr); 766 } 767 #else 768 if (png_ptr->interlaced) 769 png_error(png_ptr, 770 "Cannot read interlaced image -- interlace handler disabled"); 771 772 pass = 1; 773 #endif 774 775 image_height=png_ptr->height; 776 777 for (j = 0; j < pass; j++) 778 { 779 rp = image; 780 for (i = 0; i < image_height; i++) 781 { 782 png_read_row(png_ptr, *rp, NULL); 783 rp++; 784 } 785 } 786 } 787 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 788 789 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 790 /* Read the end of the PNG file. Will not read past the end of the 791 * file, will verify the end is accurate, and will read any comments 792 * or time information at the end of the file, if info is not NULL. 793 */ 794 void PNGAPI 795 png_read_end(png_structp png_ptr, png_infop info_ptr) 796 { 797 png_debug(1, "in png_read_end"); 798 799 if (png_ptr == NULL) 800 return; 801 802 png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ 803 804 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 805 /* Report invalid palette index; added at libng-1.5.10 */ 806 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 807 png_ptr->num_palette_max > png_ptr->num_palette) 808 png_benign_error(png_ptr, "Read palette index exceeding num_palette"); 809 #endif 810 811 do 812 { 813 png_uint_32 length = png_read_chunk_header(png_ptr); 814 png_uint_32 chunk_name = png_ptr->chunk_name; 815 816 if (chunk_name == png_IHDR) 817 png_handle_IHDR(png_ptr, info_ptr, length); 818 819 else if (chunk_name == png_IEND) 820 png_handle_IEND(png_ptr, info_ptr, length); 821 822 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 823 else if (png_chunk_unknown_handling(png_ptr, chunk_name) != 824 PNG_HANDLE_CHUNK_AS_DEFAULT) 825 { 826 if (chunk_name == png_IDAT) 827 { 828 if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 829 png_benign_error(png_ptr, "Too many IDATs found"); 830 } 831 png_handle_unknown(png_ptr, info_ptr, length); 832 if (chunk_name == png_PLTE) 833 png_ptr->mode |= PNG_HAVE_PLTE; 834 } 835 #endif 836 837 else if (chunk_name == png_IDAT) 838 { 839 /* Zero length IDATs are legal after the last IDAT has been 840 * read, but not after other chunks have been read. 841 */ 842 if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 843 png_benign_error(png_ptr, "Too many IDATs found"); 844 845 png_crc_finish(png_ptr, length); 846 } 847 else if (chunk_name == png_PLTE) 848 png_handle_PLTE(png_ptr, info_ptr, length); 849 850 #ifdef PNG_READ_bKGD_SUPPORTED 851 else if (chunk_name == png_bKGD) 852 png_handle_bKGD(png_ptr, info_ptr, length); 853 #endif 854 855 #ifdef PNG_READ_cHRM_SUPPORTED 856 else if (chunk_name == png_cHRM) 857 png_handle_cHRM(png_ptr, info_ptr, length); 858 #endif 859 860 #ifdef PNG_READ_gAMA_SUPPORTED 861 else if (chunk_name == png_gAMA) 862 png_handle_gAMA(png_ptr, info_ptr, length); 863 #endif 864 865 #ifdef PNG_READ_hIST_SUPPORTED 866 else if (chunk_name == png_hIST) 867 png_handle_hIST(png_ptr, info_ptr, length); 868 #endif 869 870 #ifdef PNG_READ_oFFs_SUPPORTED 871 else if (chunk_name == png_oFFs) 872 png_handle_oFFs(png_ptr, info_ptr, length); 873 #endif 874 875 #ifdef PNG_READ_pCAL_SUPPORTED 876 else if (chunk_name == png_pCAL) 877 png_handle_pCAL(png_ptr, info_ptr, length); 878 #endif 879 880 #ifdef PNG_READ_sCAL_SUPPORTED 881 else if (chunk_name == png_sCAL) 882 png_handle_sCAL(png_ptr, info_ptr, length); 883 #endif 884 885 #ifdef PNG_READ_pHYs_SUPPORTED 886 else if (chunk_name == png_pHYs) 887 png_handle_pHYs(png_ptr, info_ptr, length); 888 #endif 889 890 #ifdef PNG_READ_sBIT_SUPPORTED 891 else if (chunk_name == png_sBIT) 892 png_handle_sBIT(png_ptr, info_ptr, length); 893 #endif 894 895 #ifdef PNG_READ_sRGB_SUPPORTED 896 else if (chunk_name == png_sRGB) 897 png_handle_sRGB(png_ptr, info_ptr, length); 898 #endif 899 900 #ifdef PNG_READ_iCCP_SUPPORTED 901 else if (chunk_name == png_iCCP) 902 png_handle_iCCP(png_ptr, info_ptr, length); 903 #endif 904 905 #ifdef PNG_READ_sPLT_SUPPORTED 906 else if (chunk_name == png_sPLT) 907 png_handle_sPLT(png_ptr, info_ptr, length); 908 #endif 909 910 #ifdef PNG_READ_tEXt_SUPPORTED 911 else if (chunk_name == png_tEXt) 912 png_handle_tEXt(png_ptr, info_ptr, length); 913 #endif 914 915 #ifdef PNG_READ_tIME_SUPPORTED 916 else if (chunk_name == png_tIME) 917 png_handle_tIME(png_ptr, info_ptr, length); 918 #endif 919 920 #ifdef PNG_READ_tRNS_SUPPORTED 921 else if (chunk_name == png_tRNS) 922 png_handle_tRNS(png_ptr, info_ptr, length); 923 #endif 924 925 #ifdef PNG_READ_zTXt_SUPPORTED 926 else if (chunk_name == png_zTXt) 927 png_handle_zTXt(png_ptr, info_ptr, length); 928 #endif 929 930 #ifdef PNG_READ_iTXt_SUPPORTED 931 else if (chunk_name == png_iTXt) 932 png_handle_iTXt(png_ptr, info_ptr, length); 933 #endif 934 935 else 936 png_handle_unknown(png_ptr, info_ptr, length); 937 } while (!(png_ptr->mode & PNG_HAVE_IEND)); 938 } 939 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 940 941 /* Free all memory used by the read */ 942 void PNGAPI 943 png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, 944 png_infopp end_info_ptr_ptr) 945 { 946 png_structp png_ptr = NULL; 947 png_infop info_ptr = NULL, end_info_ptr = NULL; 948 #ifdef PNG_USER_MEM_SUPPORTED 949 png_free_ptr free_fn = NULL; 950 png_voidp mem_ptr = NULL; 951 #endif 952 953 png_debug(1, "in png_destroy_read_struct"); 954 955 if (png_ptr_ptr != NULL) 956 png_ptr = *png_ptr_ptr; 957 if (png_ptr == NULL) 958 return; 959 960 #ifdef PNG_USER_MEM_SUPPORTED 961 free_fn = png_ptr->free_fn; 962 mem_ptr = png_ptr->mem_ptr; 963 #endif 964 965 if (info_ptr_ptr != NULL) 966 info_ptr = *info_ptr_ptr; 967 968 if (end_info_ptr_ptr != NULL) 969 end_info_ptr = *end_info_ptr_ptr; 970 971 png_read_destroy(png_ptr, info_ptr, end_info_ptr); 972 973 if (info_ptr != NULL) 974 { 975 #ifdef PNG_TEXT_SUPPORTED 976 png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); 977 #endif 978 979 #ifdef PNG_USER_MEM_SUPPORTED 980 png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, 981 (png_voidp)mem_ptr); 982 #else 983 png_destroy_struct((png_voidp)info_ptr); 984 #endif 985 *info_ptr_ptr = NULL; 986 } 987 988 if (end_info_ptr != NULL) 989 { 990 #ifdef PNG_READ_TEXT_SUPPORTED 991 png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); 992 #endif 993 #ifdef PNG_USER_MEM_SUPPORTED 994 png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, 995 (png_voidp)mem_ptr); 996 #else 997 png_destroy_struct((png_voidp)end_info_ptr); 998 #endif 999 *end_info_ptr_ptr = NULL; 1000 } 1001 1002 if (png_ptr != NULL) 1003 { 1004 #ifdef PNG_USER_MEM_SUPPORTED 1005 png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, 1006 (png_voidp)mem_ptr); 1007 #else 1008 png_destroy_struct((png_voidp)png_ptr); 1009 #endif 1010 *png_ptr_ptr = NULL; 1011 } 1012 } 1013 1014 /* Free all memory used by the read (old method) */ 1015 void /* PRIVATE */ 1016 png_read_destroy(png_structp png_ptr, png_infop info_ptr, 1017 png_infop end_info_ptr) 1018 { 1019 #ifdef PNG_SETJMP_SUPPORTED 1020 jmp_buf tmp_jmp; 1021 #endif 1022 png_error_ptr error_fn; 1023 #ifdef PNG_WARNINGS_SUPPORTED 1024 png_error_ptr warning_fn; 1025 #endif 1026 png_voidp error_ptr; 1027 #ifdef PNG_USER_MEM_SUPPORTED 1028 png_free_ptr free_fn; 1029 #endif 1030 1031 png_debug(1, "in png_read_destroy"); 1032 1033 if (info_ptr != NULL) 1034 png_info_destroy(png_ptr, info_ptr); 1035 1036 if (end_info_ptr != NULL) 1037 png_info_destroy(png_ptr, end_info_ptr); 1038 1039 #ifdef PNG_READ_GAMMA_SUPPORTED 1040 png_destroy_gamma_table(png_ptr); 1041 #endif 1042 1043 png_free(png_ptr, png_ptr->zbuf); 1044 png_free(png_ptr, png_ptr->big_row_buf); 1045 png_free(png_ptr, png_ptr->big_prev_row); 1046 png_free(png_ptr, png_ptr->chunkdata); 1047 1048 #ifdef PNG_READ_QUANTIZE_SUPPORTED 1049 png_free(png_ptr, png_ptr->palette_lookup); 1050 png_free(png_ptr, png_ptr->quantize_index); 1051 #endif 1052 1053 if (png_ptr->free_me & PNG_FREE_PLTE) 1054 png_zfree(png_ptr, png_ptr->palette); 1055 png_ptr->free_me &= ~PNG_FREE_PLTE; 1056 1057 #if defined(PNG_tRNS_SUPPORTED) || \ 1058 defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 1059 if (png_ptr->free_me & PNG_FREE_TRNS) 1060 png_free(png_ptr, png_ptr->trans_alpha); 1061 png_ptr->free_me &= ~PNG_FREE_TRNS; 1062 #endif 1063 1064 #ifdef PNG_READ_hIST_SUPPORTED 1065 if (png_ptr->free_me & PNG_FREE_HIST) 1066 png_free(png_ptr, png_ptr->hist); 1067 png_ptr->free_me &= ~PNG_FREE_HIST; 1068 #endif 1069 1070 inflateEnd(&png_ptr->zstream); 1071 1072 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED 1073 png_free(png_ptr, png_ptr->save_buffer); 1074 #endif 1075 1076 /* Save the important info out of the png_struct, in case it is 1077 * being used again. 1078 */ 1079 #ifdef PNG_SETJMP_SUPPORTED 1080 png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); 1081 #endif 1082 1083 error_fn = png_ptr->error_fn; 1084 #ifdef PNG_WARNINGS_SUPPORTED 1085 warning_fn = png_ptr->warning_fn; 1086 #endif 1087 error_ptr = png_ptr->error_ptr; 1088 #ifdef PNG_USER_MEM_SUPPORTED 1089 free_fn = png_ptr->free_fn; 1090 #endif 1091 1092 png_memset(png_ptr, 0, png_sizeof(png_struct)); 1093 1094 png_ptr->error_fn = error_fn; 1095 #ifdef PNG_WARNINGS_SUPPORTED 1096 png_ptr->warning_fn = warning_fn; 1097 #endif 1098 png_ptr->error_ptr = error_ptr; 1099 #ifdef PNG_USER_MEM_SUPPORTED 1100 png_ptr->free_fn = free_fn; 1101 #endif 1102 1103 #ifdef PNG_SETJMP_SUPPORTED 1104 png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); 1105 #endif 1106 1107 } 1108 1109 void PNGAPI 1110 png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) 1111 { 1112 if (png_ptr == NULL) 1113 return; 1114 1115 png_ptr->read_row_fn = read_row_fn; 1116 } 1117 1118 1119 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED 1120 #ifdef PNG_INFO_IMAGE_SUPPORTED 1121 void PNGAPI 1122 png_read_png(png_structp png_ptr, png_infop info_ptr, 1123 int transforms, 1124 voidp params) 1125 { 1126 int row; 1127 1128 if (png_ptr == NULL || info_ptr == NULL) 1129 return; 1130 1131 /* png_read_info() gives us all of the information from the 1132 * PNG file before the first IDAT (image data chunk). 1133 */ 1134 png_read_info(png_ptr, info_ptr); 1135 if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) 1136 png_error(png_ptr, "Image is too high to process with png_read_png()"); 1137 1138 /* -------------- image transformations start here ------------------- */ 1139 1140 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 1141 /* Tell libpng to strip 16-bit/color files down to 8 bits per color. 1142 */ 1143 if (transforms & PNG_TRANSFORM_SCALE_16) 1144 { 1145 /* Added at libpng-1.5.4. "strip_16" produces the same result that it 1146 * did in earlier versions, while "scale_16" is now more accurate. 1147 */ 1148 png_set_scale_16(png_ptr); 1149 } 1150 #endif 1151 1152 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 1153 /* If both SCALE and STRIP are required pngrtran will effectively cancel the 1154 * latter by doing SCALE first. This is ok and allows apps not to check for 1155 * which is supported to get the right answer. 1156 */ 1157 if (transforms & PNG_TRANSFORM_STRIP_16) 1158 png_set_strip_16(png_ptr); 1159 #endif 1160 1161 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 1162 /* Strip alpha bytes from the input data without combining with 1163 * the background (not recommended). 1164 */ 1165 if (transforms & PNG_TRANSFORM_STRIP_ALPHA) 1166 png_set_strip_alpha(png_ptr); 1167 #endif 1168 1169 #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) 1170 /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single 1171 * byte into separate bytes (useful for paletted and grayscale images). 1172 */ 1173 if (transforms & PNG_TRANSFORM_PACKING) 1174 png_set_packing(png_ptr); 1175 #endif 1176 1177 #ifdef PNG_READ_PACKSWAP_SUPPORTED 1178 /* Change the order of packed pixels to least significant bit first 1179 * (not useful if you are using png_set_packing). 1180 */ 1181 if (transforms & PNG_TRANSFORM_PACKSWAP) 1182 png_set_packswap(png_ptr); 1183 #endif 1184 1185 #ifdef PNG_READ_EXPAND_SUPPORTED 1186 /* Expand paletted colors into true RGB triplets 1187 * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel 1188 * Expand paletted or RGB images with transparency to full alpha 1189 * channels so the data will be available as RGBA quartets. 1190 */ 1191 if (transforms & PNG_TRANSFORM_EXPAND) 1192 if ((png_ptr->bit_depth < 8) || 1193 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || 1194 (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) 1195 png_set_expand(png_ptr); 1196 #endif 1197 1198 /* We don't handle background color or gamma transformation or quantizing. 1199 */ 1200 1201 #ifdef PNG_READ_INVERT_SUPPORTED 1202 /* Invert monochrome files to have 0 as white and 1 as black 1203 */ 1204 if (transforms & PNG_TRANSFORM_INVERT_MONO) 1205 png_set_invert_mono(png_ptr); 1206 #endif 1207 1208 #ifdef PNG_READ_SHIFT_SUPPORTED 1209 /* If you want to shift the pixel values from the range [0,255] or 1210 * [0,65535] to the original [0,7] or [0,31], or whatever range the 1211 * colors were originally in: 1212 */ 1213 if ((transforms & PNG_TRANSFORM_SHIFT) 1214 && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) 1215 { 1216 png_color_8p sig_bit; 1217 1218 png_get_sBIT(png_ptr, info_ptr, &sig_bit); 1219 png_set_shift(png_ptr, sig_bit); 1220 } 1221 #endif 1222 1223 #ifdef PNG_READ_BGR_SUPPORTED 1224 /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ 1225 if (transforms & PNG_TRANSFORM_BGR) 1226 png_set_bgr(png_ptr); 1227 #endif 1228 1229 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 1230 /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ 1231 if (transforms & PNG_TRANSFORM_SWAP_ALPHA) 1232 png_set_swap_alpha(png_ptr); 1233 #endif 1234 1235 #ifdef PNG_READ_SWAP_SUPPORTED 1236 /* Swap bytes of 16-bit files to least significant byte first */ 1237 if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) 1238 png_set_swap(png_ptr); 1239 #endif 1240 1241 /* Added at libpng-1.2.41 */ 1242 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 1243 /* Invert the alpha channel from opacity to transparency */ 1244 if (transforms & PNG_TRANSFORM_INVERT_ALPHA) 1245 png_set_invert_alpha(png_ptr); 1246 #endif 1247 1248 /* Added at libpng-1.2.41 */ 1249 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 1250 /* Expand grayscale image to RGB */ 1251 if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) 1252 png_set_gray_to_rgb(png_ptr); 1253 #endif 1254 1255 /* Added at libpng-1.5.4 */ 1256 #ifdef PNG_READ_EXPAND_16_SUPPORTED 1257 if (transforms & PNG_TRANSFORM_EXPAND_16) 1258 png_set_expand_16(png_ptr); 1259 #endif 1260 1261 /* We don't handle adding filler bytes */ 1262 1263 /* We use png_read_image and rely on that for interlace handling, but we also 1264 * call png_read_update_info therefore must turn on interlace handling now: 1265 */ 1266 (void)png_set_interlace_handling(png_ptr); 1267 1268 /* Optional call to gamma correct and add the background to the palette 1269 * and update info structure. REQUIRED if you are expecting libpng to 1270 * update the palette for you (i.e., you selected such a transform above). 1271 */ 1272 png_read_update_info(png_ptr, info_ptr); 1273 1274 /* -------------- image transformations end here ------------------- */ 1275 1276 png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); 1277 if (info_ptr->row_pointers == NULL) 1278 { 1279 png_uint_32 iptr; 1280 1281 info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, 1282 info_ptr->height * png_sizeof(png_bytep)); 1283 for (iptr=0; iptr<info_ptr->height; iptr++) 1284 info_ptr->row_pointers[iptr] = NULL; 1285 1286 info_ptr->free_me |= PNG_FREE_ROWS; 1287 1288 for (row = 0; row < (int)info_ptr->height; row++) 1289 info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, 1290 png_get_rowbytes(png_ptr, info_ptr)); 1291 } 1292 1293 png_read_image(png_ptr, info_ptr->row_pointers); 1294 info_ptr->valid |= PNG_INFO_IDAT; 1295 1296 /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ 1297 png_read_end(png_ptr, info_ptr); 1298 1299 PNG_UNUSED(transforms) /* Quiet compiler warnings */ 1300 PNG_UNUSED(params) 1301 1302 } 1303 #endif /* PNG_INFO_IMAGE_SUPPORTED */ 1304 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 1305 #endif /* PNG_READ_SUPPORTED */ 1306