1/* pngread.c - read a PNG file 2 * 3 * Last changed in libpng 1.6.1 [March 28, 2013] 4 * Copyright (c) 1998-2013 Glenn Randers-Pehrson 5 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 6 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 7 * 8 * This code is released under the libpng license. 9 * For conditions of distribution and use, see the disclaimer 10 * and license in png.h 11 * 12 * This file contains routines that an application calls directly to 13 * read a PNG file or stream. 14 */ 15 16#include "pngpriv.h" 17#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) 18# include <errno.h> 19#endif 20 21#ifdef PNG_READ_SUPPORTED 22 23/* Create a PNG structure for reading, and allocate any memory needed. */ 24PNG_FUNCTION(png_structp,PNGAPI 25png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, 26 png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) 27{ 28#ifndef PNG_USER_MEM_SUPPORTED 29 png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, 30 error_fn, warn_fn, NULL, NULL, NULL); 31#else 32 return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, 33 warn_fn, NULL, NULL, NULL); 34} 35 36/* Alternate create PNG structure for reading, and allocate any memory 37 * needed. 38 */ 39PNG_FUNCTION(png_structp,PNGAPI 40png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, 41 png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, 42 png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) 43{ 44 png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, 45 error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); 46#endif /* PNG_USER_MEM_SUPPORTED */ 47 48 if (png_ptr != NULL) 49 { 50 png_ptr->mode = PNG_IS_READ_STRUCT; 51 52 /* Added in libpng-1.6.0; this can be used to detect a read structure if 53 * required (it will be zero in a write structure.) 54 */ 55# ifdef PNG_SEQUENTIAL_READ_SUPPORTED 56 png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; 57# endif 58 59# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED 60 png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; 61 62 /* In stable builds only warn if an application error can be completely 63 * handled. 64 */ 65# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC 66 png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; 67# endif 68# endif 69 70 /* TODO: delay this, it can be done in png_init_io (if the app doesn't 71 * do it itself) avoiding setting the default function if it is not 72 * required. 73 */ 74 png_set_read_fn(png_ptr, NULL, NULL); 75 } 76 77 return png_ptr; 78} 79 80 81#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 82/* Read the information before the actual image data. This has been 83 * changed in v0.90 to allow reading a file that already has the magic 84 * bytes read from the stream. You can tell libpng how many bytes have 85 * been read from the beginning of the stream (up to the maximum of 8) 86 * via png_set_sig_bytes(), and we will only check the remaining bytes 87 * here. The application can then have access to the signature bytes we 88 * read if it is determined that this isn't a valid PNG file. 89 */ 90void PNGAPI 91png_read_info(png_structrp png_ptr, png_inforp info_ptr) 92{ 93#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 94 int keep; 95#endif 96 97 png_debug(1, "in png_read_info"); 98 99 if (png_ptr == NULL || info_ptr == NULL) 100 return; 101 102 /* Read and check the PNG file signature. */ 103 png_read_sig(png_ptr, info_ptr); 104 105 for (;;) 106 { 107 png_uint_32 length = png_read_chunk_header(png_ptr); 108 png_uint_32 chunk_name = png_ptr->chunk_name; 109 110 /* IDAT logic needs to happen here to simplify getting the two flags 111 * right. 112 */ 113 if (chunk_name == png_IDAT) 114 { 115 if (!(png_ptr->mode & PNG_HAVE_IHDR)) 116 png_chunk_error(png_ptr, "Missing IHDR before IDAT"); 117 118 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 119 !(png_ptr->mode & PNG_HAVE_PLTE)) 120 png_chunk_error(png_ptr, "Missing PLTE before IDAT"); 121 122 else if (png_ptr->mode & PNG_AFTER_IDAT) 123 png_chunk_benign_error(png_ptr, "Too many IDATs found"); 124 125 png_ptr->mode |= PNG_HAVE_IDAT; 126 } 127 128 else if (png_ptr->mode & PNG_HAVE_IDAT) 129 png_ptr->mode |= PNG_AFTER_IDAT; 130 131 /* This should be a binary subdivision search or a hash for 132 * matching the chunk name rather than a linear search. 133 */ 134 if (chunk_name == png_IHDR) 135 png_handle_IHDR(png_ptr, info_ptr, length); 136 137 else if (chunk_name == png_IEND) 138 png_handle_IEND(png_ptr, info_ptr, length); 139 140#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 141 else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 142 { 143 png_handle_unknown(png_ptr, info_ptr, length, keep); 144 145 if (chunk_name == png_PLTE) 146 png_ptr->mode |= PNG_HAVE_PLTE; 147 148 else if (chunk_name == png_IDAT) 149 { 150 png_ptr->idat_size = 0; /* It has been consumed */ 151 break; 152 } 153 } 154#endif 155 else if (chunk_name == png_PLTE) 156 png_handle_PLTE(png_ptr, info_ptr, length); 157 158 else if (chunk_name == png_IDAT) 159 { 160 png_ptr->idat_size = length; 161 break; 162 } 163 164#ifdef PNG_READ_bKGD_SUPPORTED 165 else if (chunk_name == png_bKGD) 166 png_handle_bKGD(png_ptr, info_ptr, length); 167#endif 168 169#ifdef PNG_READ_cHRM_SUPPORTED 170 else if (chunk_name == png_cHRM) 171 png_handle_cHRM(png_ptr, info_ptr, length); 172#endif 173 174#ifdef PNG_READ_gAMA_SUPPORTED 175 else if (chunk_name == png_gAMA) 176 png_handle_gAMA(png_ptr, info_ptr, length); 177#endif 178 179#ifdef PNG_READ_hIST_SUPPORTED 180 else if (chunk_name == png_hIST) 181 png_handle_hIST(png_ptr, info_ptr, length); 182#endif 183 184#ifdef PNG_READ_oFFs_SUPPORTED 185 else if (chunk_name == png_oFFs) 186 png_handle_oFFs(png_ptr, info_ptr, length); 187#endif 188 189#ifdef PNG_READ_pCAL_SUPPORTED 190 else if (chunk_name == png_pCAL) 191 png_handle_pCAL(png_ptr, info_ptr, length); 192#endif 193 194#ifdef PNG_READ_sCAL_SUPPORTED 195 else if (chunk_name == png_sCAL) 196 png_handle_sCAL(png_ptr, info_ptr, length); 197#endif 198 199#ifdef PNG_READ_pHYs_SUPPORTED 200 else if (chunk_name == png_pHYs) 201 png_handle_pHYs(png_ptr, info_ptr, length); 202#endif 203 204#ifdef PNG_READ_sBIT_SUPPORTED 205 else if (chunk_name == png_sBIT) 206 png_handle_sBIT(png_ptr, info_ptr, length); 207#endif 208 209#ifdef PNG_READ_sRGB_SUPPORTED 210 else if (chunk_name == png_sRGB) 211 png_handle_sRGB(png_ptr, info_ptr, length); 212#endif 213 214#ifdef PNG_READ_iCCP_SUPPORTED 215 else if (chunk_name == png_iCCP) 216 png_handle_iCCP(png_ptr, info_ptr, length); 217#endif 218 219#ifdef PNG_READ_sPLT_SUPPORTED 220 else if (chunk_name == png_sPLT) 221 png_handle_sPLT(png_ptr, info_ptr, length); 222#endif 223 224#ifdef PNG_READ_tEXt_SUPPORTED 225 else if (chunk_name == png_tEXt) 226 png_handle_tEXt(png_ptr, info_ptr, length); 227#endif 228 229#ifdef PNG_READ_tIME_SUPPORTED 230 else if (chunk_name == png_tIME) 231 png_handle_tIME(png_ptr, info_ptr, length); 232#endif 233 234#ifdef PNG_READ_tRNS_SUPPORTED 235 else if (chunk_name == png_tRNS) 236 png_handle_tRNS(png_ptr, info_ptr, length); 237#endif 238 239#ifdef PNG_READ_zTXt_SUPPORTED 240 else if (chunk_name == png_zTXt) 241 png_handle_zTXt(png_ptr, info_ptr, length); 242#endif 243 244#ifdef PNG_READ_iTXt_SUPPORTED 245 else if (chunk_name == png_iTXt) 246 png_handle_iTXt(png_ptr, info_ptr, length); 247#endif 248 249 else 250 png_handle_unknown(png_ptr, info_ptr, length, 251 PNG_HANDLE_CHUNK_AS_DEFAULT); 252 } 253} 254#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 255 256/* Optional call to update the users info_ptr structure */ 257void PNGAPI 258png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) 259{ 260 png_debug(1, "in png_read_update_info"); 261 262 if (png_ptr != NULL) 263 { 264 if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 265 { 266 png_read_start_row(png_ptr); 267 268# ifdef PNG_READ_TRANSFORMS_SUPPORTED 269 png_read_transform_info(png_ptr, info_ptr); 270# else 271 PNG_UNUSED(info_ptr) 272# endif 273 } 274 275 /* New in 1.6.0 this avoids the bug of doing the initializations twice */ 276 else 277 png_app_error(png_ptr, 278 "png_read_update_info/png_start_read_image: duplicate call"); 279 } 280} 281 282#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 283/* Initialize palette, background, etc, after transformations 284 * are set, but before any reading takes place. This allows 285 * the user to obtain a gamma-corrected palette, for example. 286 * If the user doesn't call this, we will do it ourselves. 287 */ 288void PNGAPI 289png_start_read_image(png_structrp png_ptr) 290{ 291 png_debug(1, "in png_start_read_image"); 292 293 if (png_ptr != NULL) 294 { 295 if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 296 png_read_start_row(png_ptr); 297 298 /* New in 1.6.0 this avoids the bug of doing the initializations twice */ 299 else 300 png_app_error(png_ptr, 301 "png_start_read_image/png_read_update_info: duplicate call"); 302 } 303} 304#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 305 306#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 307void PNGAPI 308png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) 309{ 310 png_row_info row_info; 311 312 if (png_ptr == NULL) 313 return; 314 315 png_debug2(1, "in png_read_row (row %lu, pass %d)", 316 (unsigned long)png_ptr->row_number, png_ptr->pass); 317 318 /* png_read_start_row sets the information (in particular iwidth) for this 319 * interlace pass. 320 */ 321 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 322 png_read_start_row(png_ptr); 323 324 /* 1.5.6: row_info moved out of png_struct to a local here. */ 325 row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ 326 row_info.color_type = png_ptr->color_type; 327 row_info.bit_depth = png_ptr->bit_depth; 328 row_info.channels = png_ptr->channels; 329 row_info.pixel_depth = png_ptr->pixel_depth; 330 row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); 331 332 if (png_ptr->row_number == 0 && png_ptr->pass == 0) 333 { 334 /* Check for transforms that have been set but were defined out */ 335#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) 336 if (png_ptr->transformations & PNG_INVERT_MONO) 337 png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); 338#endif 339 340#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) 341 if (png_ptr->transformations & PNG_FILLER) 342 png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); 343#endif 344 345#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ 346 !defined(PNG_READ_PACKSWAP_SUPPORTED) 347 if (png_ptr->transformations & PNG_PACKSWAP) 348 png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); 349#endif 350 351#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) 352 if (png_ptr->transformations & PNG_PACK) 353 png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); 354#endif 355 356#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) 357 if (png_ptr->transformations & PNG_SHIFT) 358 png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); 359#endif 360 361#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) 362 if (png_ptr->transformations & PNG_BGR) 363 png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); 364#endif 365 366#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) 367 if (png_ptr->transformations & PNG_SWAP_BYTES) 368 png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); 369#endif 370 } 371 372#ifdef PNG_READ_INTERLACING_SUPPORTED 373 /* If interlaced and we do not need a new row, combine row and return. 374 * Notice that the pixels we have from previous rows have been transformed 375 * already; we can only combine like with like (transformed or 376 * untransformed) and, because of the libpng API for interlaced images, this 377 * means we must transform before de-interlacing. 378 */ 379 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) 380 { 381 switch (png_ptr->pass) 382 { 383 case 0: 384 if (png_ptr->row_number & 0x07) 385 { 386 if (dsp_row != NULL) 387 png_combine_row(png_ptr, dsp_row, 1/*display*/); 388 png_read_finish_row(png_ptr); 389 return; 390 } 391 break; 392 393 case 1: 394 if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) 395 { 396 if (dsp_row != NULL) 397 png_combine_row(png_ptr, dsp_row, 1/*display*/); 398 399 png_read_finish_row(png_ptr); 400 return; 401 } 402 break; 403 404 case 2: 405 if ((png_ptr->row_number & 0x07) != 4) 406 { 407 if (dsp_row != NULL && (png_ptr->row_number & 4)) 408 png_combine_row(png_ptr, dsp_row, 1/*display*/); 409 410 png_read_finish_row(png_ptr); 411 return; 412 } 413 break; 414 415 case 3: 416 if ((png_ptr->row_number & 3) || png_ptr->width < 3) 417 { 418 if (dsp_row != NULL) 419 png_combine_row(png_ptr, dsp_row, 1/*display*/); 420 421 png_read_finish_row(png_ptr); 422 return; 423 } 424 break; 425 426 case 4: 427 if ((png_ptr->row_number & 3) != 2) 428 { 429 if (dsp_row != NULL && (png_ptr->row_number & 2)) 430 png_combine_row(png_ptr, dsp_row, 1/*display*/); 431 432 png_read_finish_row(png_ptr); 433 return; 434 } 435 break; 436 437 case 5: 438 if ((png_ptr->row_number & 1) || png_ptr->width < 2) 439 { 440 if (dsp_row != NULL) 441 png_combine_row(png_ptr, dsp_row, 1/*display*/); 442 443 png_read_finish_row(png_ptr); 444 return; 445 } 446 break; 447 448 default: 449 case 6: 450 if (!(png_ptr->row_number & 1)) 451 { 452 png_read_finish_row(png_ptr); 453 return; 454 } 455 break; 456 } 457 } 458#endif 459 460 if (!(png_ptr->mode & PNG_HAVE_IDAT)) 461 png_error(png_ptr, "Invalid attempt to read row data"); 462 463 /* Fill the row with IDAT data: */ 464 png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); 465 466 if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) 467 { 468 if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) 469 png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, 470 png_ptr->prev_row + 1, png_ptr->row_buf[0]); 471 else 472 png_error(png_ptr, "bad adaptive filter value"); 473 } 474 475 /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before 476 * 1.5.6, while the buffer really is this big in current versions of libpng 477 * it may not be in the future, so this was changed just to copy the 478 * interlaced count: 479 */ 480 memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); 481 482#ifdef PNG_MNG_FEATURES_SUPPORTED 483 if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 484 (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) 485 { 486 /* Intrapixel differencing */ 487 png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); 488 } 489#endif 490 491 492#ifdef PNG_READ_TRANSFORMS_SUPPORTED 493 if (png_ptr->transformations) 494 png_do_read_transformations(png_ptr, &row_info); 495#endif 496 497 /* The transformed pixel depth should match the depth now in row_info. */ 498 if (png_ptr->transformed_pixel_depth == 0) 499 { 500 png_ptr->transformed_pixel_depth = row_info.pixel_depth; 501 if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) 502 png_error(png_ptr, "sequential row overflow"); 503 } 504 505 else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) 506 png_error(png_ptr, "internal sequential row size calculation error"); 507 508#ifdef PNG_READ_INTERLACING_SUPPORTED 509 /* Blow up interlaced rows to full size */ 510 if (png_ptr->interlaced && 511 (png_ptr->transformations & PNG_INTERLACE)) 512 { 513 if (png_ptr->pass < 6) 514 png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, 515 png_ptr->transformations); 516 517 if (dsp_row != NULL) 518 png_combine_row(png_ptr, dsp_row, 1/*display*/); 519 520 if (row != NULL) 521 png_combine_row(png_ptr, row, 0/*row*/); 522 } 523 524 else 525#endif 526 { 527 if (row != NULL) 528 png_combine_row(png_ptr, row, -1/*ignored*/); 529 530 if (dsp_row != NULL) 531 png_combine_row(png_ptr, dsp_row, -1/*ignored*/); 532 } 533 png_read_finish_row(png_ptr); 534 535 if (png_ptr->read_row_fn != NULL) 536 (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); 537 538} 539#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 540 541#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 542/* Read one or more rows of image data. If the image is interlaced, 543 * and png_set_interlace_handling() has been called, the rows need to 544 * contain the contents of the rows from the previous pass. If the 545 * image has alpha or transparency, and png_handle_alpha()[*] has been 546 * called, the rows contents must be initialized to the contents of the 547 * screen. 548 * 549 * "row" holds the actual image, and pixels are placed in it 550 * as they arrive. If the image is displayed after each pass, it will 551 * appear to "sparkle" in. "display_row" can be used to display a 552 * "chunky" progressive image, with finer detail added as it becomes 553 * available. If you do not want this "chunky" display, you may pass 554 * NULL for display_row. If you do not want the sparkle display, and 555 * you have not called png_handle_alpha(), you may pass NULL for rows. 556 * If you have called png_handle_alpha(), and the image has either an 557 * alpha channel or a transparency chunk, you must provide a buffer for 558 * rows. In this case, you do not have to provide a display_row buffer 559 * also, but you may. If the image is not interlaced, or if you have 560 * not called png_set_interlace_handling(), the display_row buffer will 561 * be ignored, so pass NULL to it. 562 * 563 * [*] png_handle_alpha() does not exist yet, as of this version of libpng 564 */ 565 566void PNGAPI 567png_read_rows(png_structrp png_ptr, png_bytepp row, 568 png_bytepp display_row, png_uint_32 num_rows) 569{ 570 png_uint_32 i; 571 png_bytepp rp; 572 png_bytepp dp; 573 574 png_debug(1, "in png_read_rows"); 575 576 if (png_ptr == NULL) 577 return; 578 579 rp = row; 580 dp = display_row; 581 if (rp != NULL && dp != NULL) 582 for (i = 0; i < num_rows; i++) 583 { 584 png_bytep rptr = *rp++; 585 png_bytep dptr = *dp++; 586 587 png_read_row(png_ptr, rptr, dptr); 588 } 589 590 else if (rp != NULL) 591 for (i = 0; i < num_rows; i++) 592 { 593 png_bytep rptr = *rp; 594 png_read_row(png_ptr, rptr, NULL); 595 rp++; 596 } 597 598 else if (dp != NULL) 599 for (i = 0; i < num_rows; i++) 600 { 601 png_bytep dptr = *dp; 602 png_read_row(png_ptr, NULL, dptr); 603 dp++; 604 } 605} 606#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 607 608#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 609/* Read the entire image. If the image has an alpha channel or a tRNS 610 * chunk, and you have called png_handle_alpha()[*], you will need to 611 * initialize the image to the current image that PNG will be overlaying. 612 * We set the num_rows again here, in case it was incorrectly set in 613 * png_read_start_row() by a call to png_read_update_info() or 614 * png_start_read_image() if png_set_interlace_handling() wasn't called 615 * prior to either of these functions like it should have been. You can 616 * only call this function once. If you desire to have an image for 617 * each pass of a interlaced image, use png_read_rows() instead. 618 * 619 * [*] png_handle_alpha() does not exist yet, as of this version of libpng 620 */ 621void PNGAPI 622png_read_image(png_structrp png_ptr, png_bytepp image) 623{ 624 png_uint_32 i, image_height; 625 int pass, j; 626 png_bytepp rp; 627 628 png_debug(1, "in png_read_image"); 629 630 if (png_ptr == NULL) 631 return; 632 633#ifdef PNG_READ_INTERLACING_SUPPORTED 634 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) 635 { 636 pass = png_set_interlace_handling(png_ptr); 637 /* And make sure transforms are initialized. */ 638 png_start_read_image(png_ptr); 639 } 640 else 641 { 642 if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) 643 { 644 /* Caller called png_start_read_image or png_read_update_info without 645 * first turning on the PNG_INTERLACE transform. We can fix this here, 646 * but the caller should do it! 647 */ 648 png_warning(png_ptr, "Interlace handling should be turned on when " 649 "using png_read_image"); 650 /* Make sure this is set correctly */ 651 png_ptr->num_rows = png_ptr->height; 652 } 653 654 /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in 655 * the above error case. 656 */ 657 pass = png_set_interlace_handling(png_ptr); 658 } 659#else 660 if (png_ptr->interlaced) 661 png_error(png_ptr, 662 "Cannot read interlaced image -- interlace handler disabled"); 663 664 pass = 1; 665#endif 666 667 image_height=png_ptr->height; 668 669 for (j = 0; j < pass; j++) 670 { 671 rp = image; 672 for (i = 0; i < image_height; i++) 673 { 674 png_read_row(png_ptr, *rp, NULL); 675 rp++; 676 } 677 } 678} 679#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 680 681#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 682/* Read the end of the PNG file. Will not read past the end of the 683 * file, will verify the end is accurate, and will read any comments 684 * or time information at the end of the file, if info is not NULL. 685 */ 686void PNGAPI 687png_read_end(png_structrp png_ptr, png_inforp info_ptr) 688{ 689#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 690 int keep; 691#endif 692 693 png_debug(1, "in png_read_end"); 694 695 if (png_ptr == NULL) 696 return; 697 698 /* If png_read_end is called in the middle of reading the rows there may 699 * still be pending IDAT data and an owned zstream. Deal with this here. 700 */ 701#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 702 if (!png_chunk_unknown_handling(png_ptr, png_IDAT)) 703#endif 704 png_read_finish_IDAT(png_ptr); 705 706#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 707 /* Report invalid palette index; added at libng-1.5.10 */ 708 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 709 png_ptr->num_palette_max > png_ptr->num_palette) 710 png_benign_error(png_ptr, "Read palette index exceeding num_palette"); 711#endif 712 713 do 714 { 715 png_uint_32 length = png_read_chunk_header(png_ptr); 716 png_uint_32 chunk_name = png_ptr->chunk_name; 717 718 if (chunk_name == png_IHDR) 719 png_handle_IHDR(png_ptr, info_ptr, length); 720 721 else if (chunk_name == png_IEND) 722 png_handle_IEND(png_ptr, info_ptr, length); 723 724#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 725 else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 726 { 727 if (chunk_name == png_IDAT) 728 { 729 if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 730 png_benign_error(png_ptr, "Too many IDATs found"); 731 } 732 png_handle_unknown(png_ptr, info_ptr, length, keep); 733 if (chunk_name == png_PLTE) 734 png_ptr->mode |= PNG_HAVE_PLTE; 735 } 736#endif 737 738 else if (chunk_name == png_IDAT) 739 { 740 /* Zero length IDATs are legal after the last IDAT has been 741 * read, but not after other chunks have been read. 742 */ 743 if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 744 png_benign_error(png_ptr, "Too many IDATs found"); 745 746 png_crc_finish(png_ptr, length); 747 } 748 else if (chunk_name == png_PLTE) 749 png_handle_PLTE(png_ptr, info_ptr, length); 750 751#ifdef PNG_READ_bKGD_SUPPORTED 752 else if (chunk_name == png_bKGD) 753 png_handle_bKGD(png_ptr, info_ptr, length); 754#endif 755 756#ifdef PNG_READ_cHRM_SUPPORTED 757 else if (chunk_name == png_cHRM) 758 png_handle_cHRM(png_ptr, info_ptr, length); 759#endif 760 761#ifdef PNG_READ_gAMA_SUPPORTED 762 else if (chunk_name == png_gAMA) 763 png_handle_gAMA(png_ptr, info_ptr, length); 764#endif 765 766#ifdef PNG_READ_hIST_SUPPORTED 767 else if (chunk_name == png_hIST) 768 png_handle_hIST(png_ptr, info_ptr, length); 769#endif 770 771#ifdef PNG_READ_oFFs_SUPPORTED 772 else if (chunk_name == png_oFFs) 773 png_handle_oFFs(png_ptr, info_ptr, length); 774#endif 775 776#ifdef PNG_READ_pCAL_SUPPORTED 777 else if (chunk_name == png_pCAL) 778 png_handle_pCAL(png_ptr, info_ptr, length); 779#endif 780 781#ifdef PNG_READ_sCAL_SUPPORTED 782 else if (chunk_name == png_sCAL) 783 png_handle_sCAL(png_ptr, info_ptr, length); 784#endif 785 786#ifdef PNG_READ_pHYs_SUPPORTED 787 else if (chunk_name == png_pHYs) 788 png_handle_pHYs(png_ptr, info_ptr, length); 789#endif 790 791#ifdef PNG_READ_sBIT_SUPPORTED 792 else if (chunk_name == png_sBIT) 793 png_handle_sBIT(png_ptr, info_ptr, length); 794#endif 795 796#ifdef PNG_READ_sRGB_SUPPORTED 797 else if (chunk_name == png_sRGB) 798 png_handle_sRGB(png_ptr, info_ptr, length); 799#endif 800 801#ifdef PNG_READ_iCCP_SUPPORTED 802 else if (chunk_name == png_iCCP) 803 png_handle_iCCP(png_ptr, info_ptr, length); 804#endif 805 806#ifdef PNG_READ_sPLT_SUPPORTED 807 else if (chunk_name == png_sPLT) 808 png_handle_sPLT(png_ptr, info_ptr, length); 809#endif 810 811#ifdef PNG_READ_tEXt_SUPPORTED 812 else if (chunk_name == png_tEXt) 813 png_handle_tEXt(png_ptr, info_ptr, length); 814#endif 815 816#ifdef PNG_READ_tIME_SUPPORTED 817 else if (chunk_name == png_tIME) 818 png_handle_tIME(png_ptr, info_ptr, length); 819#endif 820 821#ifdef PNG_READ_tRNS_SUPPORTED 822 else if (chunk_name == png_tRNS) 823 png_handle_tRNS(png_ptr, info_ptr, length); 824#endif 825 826#ifdef PNG_READ_zTXt_SUPPORTED 827 else if (chunk_name == png_zTXt) 828 png_handle_zTXt(png_ptr, info_ptr, length); 829#endif 830 831#ifdef PNG_READ_iTXt_SUPPORTED 832 else if (chunk_name == png_iTXt) 833 png_handle_iTXt(png_ptr, info_ptr, length); 834#endif 835 836 else 837 png_handle_unknown(png_ptr, info_ptr, length, 838 PNG_HANDLE_CHUNK_AS_DEFAULT); 839 } while (!(png_ptr->mode & PNG_HAVE_IEND)); 840} 841#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 842 843/* Free all memory used in the read struct */ 844static void 845png_read_destroy(png_structrp png_ptr) 846{ 847 png_debug(1, "in png_read_destroy"); 848 849#ifdef PNG_READ_GAMMA_SUPPORTED 850 png_destroy_gamma_table(png_ptr); 851#endif 852 853 png_free(png_ptr, png_ptr->big_row_buf); 854 png_free(png_ptr, png_ptr->big_prev_row); 855 png_free(png_ptr, png_ptr->read_buffer); 856 857#ifdef PNG_READ_QUANTIZE_SUPPORTED 858 png_free(png_ptr, png_ptr->palette_lookup); 859 png_free(png_ptr, png_ptr->quantize_index); 860#endif 861 862 if (png_ptr->free_me & PNG_FREE_PLTE) 863 png_zfree(png_ptr, png_ptr->palette); 864 png_ptr->free_me &= ~PNG_FREE_PLTE; 865 866#if defined(PNG_tRNS_SUPPORTED) || \ 867 defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 868 if (png_ptr->free_me & PNG_FREE_TRNS) 869 png_free(png_ptr, png_ptr->trans_alpha); 870 png_ptr->free_me &= ~PNG_FREE_TRNS; 871#endif 872 873 inflateEnd(&png_ptr->zstream); 874 875#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 876 png_free(png_ptr, png_ptr->save_buffer); 877#endif 878 879#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) &&\ 880 defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 881 png_free(png_ptr, png_ptr->unknown_chunk.data); 882#endif 883 884#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED 885 png_free(png_ptr, png_ptr->chunk_list); 886#endif 887 888 /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error 889 * callbacks are still set at this point. They are required to complete the 890 * destruction of the png_struct itself. 891 */ 892} 893 894/* Free all memory used by the read */ 895void PNGAPI 896png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, 897 png_infopp end_info_ptr_ptr) 898{ 899 png_structrp png_ptr = NULL; 900 901 png_debug(1, "in png_destroy_read_struct"); 902 903 if (png_ptr_ptr != NULL) 904 png_ptr = *png_ptr_ptr; 905 906 if (png_ptr == NULL) 907 return; 908 909 /* libpng 1.6.0: use the API to destroy info structs to ensure consistent 910 * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. 911 * The extra was, apparently, unnecessary yet this hides memory leak bugs. 912 */ 913 png_destroy_info_struct(png_ptr, end_info_ptr_ptr); 914 png_destroy_info_struct(png_ptr, info_ptr_ptr); 915 916 *png_ptr_ptr = NULL; 917 png_read_destroy(png_ptr); 918 png_destroy_png_struct(png_ptr); 919} 920 921void PNGAPI 922png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) 923{ 924 if (png_ptr == NULL) 925 return; 926 927 png_ptr->read_row_fn = read_row_fn; 928} 929 930 931#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 932#ifdef PNG_INFO_IMAGE_SUPPORTED 933void PNGAPI 934png_read_png(png_structrp png_ptr, png_inforp info_ptr, 935 int transforms, 936 voidp params) 937{ 938 int row; 939 940 if (png_ptr == NULL || info_ptr == NULL) 941 return; 942 943 /* png_read_info() gives us all of the information from the 944 * PNG file before the first IDAT (image data chunk). 945 */ 946 png_read_info(png_ptr, info_ptr); 947 if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep))) 948 png_error(png_ptr, "Image is too high to process with png_read_png()"); 949 950 /* -------------- image transformations start here ------------------- */ 951 952#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 953 /* Tell libpng to strip 16-bit/color files down to 8 bits per color. 954 */ 955 if (transforms & PNG_TRANSFORM_SCALE_16) 956 { 957 /* Added at libpng-1.5.4. "strip_16" produces the same result that it 958 * did in earlier versions, while "scale_16" is now more accurate. 959 */ 960 png_set_scale_16(png_ptr); 961 } 962#endif 963 964#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 965 /* If both SCALE and STRIP are required pngrtran will effectively cancel the 966 * latter by doing SCALE first. This is ok and allows apps not to check for 967 * which is supported to get the right answer. 968 */ 969 if (transforms & PNG_TRANSFORM_STRIP_16) 970 png_set_strip_16(png_ptr); 971#endif 972 973#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 974 /* Strip alpha bytes from the input data without combining with 975 * the background (not recommended). 976 */ 977 if (transforms & PNG_TRANSFORM_STRIP_ALPHA) 978 png_set_strip_alpha(png_ptr); 979#endif 980 981#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) 982 /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single 983 * byte into separate bytes (useful for paletted and grayscale images). 984 */ 985 if (transforms & PNG_TRANSFORM_PACKING) 986 png_set_packing(png_ptr); 987#endif 988 989#ifdef PNG_READ_PACKSWAP_SUPPORTED 990 /* Change the order of packed pixels to least significant bit first 991 * (not useful if you are using png_set_packing). 992 */ 993 if (transforms & PNG_TRANSFORM_PACKSWAP) 994 png_set_packswap(png_ptr); 995#endif 996 997#ifdef PNG_READ_EXPAND_SUPPORTED 998 /* Expand paletted colors into true RGB triplets 999 * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel 1000 * Expand paletted or RGB images with transparency to full alpha 1001 * channels so the data will be available as RGBA quartets. 1002 */ 1003 if (transforms & PNG_TRANSFORM_EXPAND) 1004 if ((png_ptr->bit_depth < 8) || 1005 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || 1006 (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) 1007 png_set_expand(png_ptr); 1008#endif 1009 1010 /* We don't handle background color or gamma transformation or quantizing. 1011 */ 1012 1013#ifdef PNG_READ_INVERT_SUPPORTED 1014 /* Invert monochrome files to have 0 as white and 1 as black 1015 */ 1016 if (transforms & PNG_TRANSFORM_INVERT_MONO) 1017 png_set_invert_mono(png_ptr); 1018#endif 1019 1020#ifdef PNG_READ_SHIFT_SUPPORTED 1021 /* If you want to shift the pixel values from the range [0,255] or 1022 * [0,65535] to the original [0,7] or [0,31], or whatever range the 1023 * colors were originally in: 1024 */ 1025 if ((transforms & PNG_TRANSFORM_SHIFT) 1026 && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) 1027 { 1028 png_color_8p sig_bit; 1029 1030 png_get_sBIT(png_ptr, info_ptr, &sig_bit); 1031 png_set_shift(png_ptr, sig_bit); 1032 } 1033#endif 1034 1035#ifdef PNG_READ_BGR_SUPPORTED 1036 /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ 1037 if (transforms & PNG_TRANSFORM_BGR) 1038 png_set_bgr(png_ptr); 1039#endif 1040 1041#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 1042 /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ 1043 if (transforms & PNG_TRANSFORM_SWAP_ALPHA) 1044 png_set_swap_alpha(png_ptr); 1045#endif 1046 1047#ifdef PNG_READ_SWAP_SUPPORTED 1048 /* Swap bytes of 16-bit files to least significant byte first */ 1049 if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) 1050 png_set_swap(png_ptr); 1051#endif 1052 1053/* Added at libpng-1.2.41 */ 1054#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 1055 /* Invert the alpha channel from opacity to transparency */ 1056 if (transforms & PNG_TRANSFORM_INVERT_ALPHA) 1057 png_set_invert_alpha(png_ptr); 1058#endif 1059 1060/* Added at libpng-1.2.41 */ 1061#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 1062 /* Expand grayscale image to RGB */ 1063 if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) 1064 png_set_gray_to_rgb(png_ptr); 1065#endif 1066 1067/* Added at libpng-1.5.4 */ 1068#ifdef PNG_READ_EXPAND_16_SUPPORTED 1069 if (transforms & PNG_TRANSFORM_EXPAND_16) 1070 png_set_expand_16(png_ptr); 1071#endif 1072 1073 /* We don't handle adding filler bytes */ 1074 1075 /* We use png_read_image and rely on that for interlace handling, but we also 1076 * call png_read_update_info therefore must turn on interlace handling now: 1077 */ 1078 (void)png_set_interlace_handling(png_ptr); 1079 1080 /* Optional call to gamma correct and add the background to the palette 1081 * and update info structure. REQUIRED if you are expecting libpng to 1082 * update the palette for you (i.e., you selected such a transform above). 1083 */ 1084 png_read_update_info(png_ptr, info_ptr); 1085 1086 /* -------------- image transformations end here ------------------- */ 1087 1088 png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); 1089 if (info_ptr->row_pointers == NULL) 1090 { 1091 png_uint_32 iptr; 1092 1093 info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, 1094 info_ptr->height * (sizeof (png_bytep))); 1095 for (iptr=0; iptr<info_ptr->height; iptr++) 1096 info_ptr->row_pointers[iptr] = NULL; 1097 1098 info_ptr->free_me |= PNG_FREE_ROWS; 1099 1100 for (row = 0; row < (int)info_ptr->height; row++) 1101 info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, 1102 png_get_rowbytes(png_ptr, info_ptr)); 1103 } 1104 1105 png_read_image(png_ptr, info_ptr->row_pointers); 1106 info_ptr->valid |= PNG_INFO_IDAT; 1107 1108 /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ 1109 png_read_end(png_ptr, info_ptr); 1110 1111 PNG_UNUSED(transforms) /* Quiet compiler warnings */ 1112 PNG_UNUSED(params) 1113 1114} 1115#endif /* PNG_INFO_IMAGE_SUPPORTED */ 1116#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 1117 1118#ifdef PNG_SIMPLIFIED_READ_SUPPORTED 1119/* SIMPLIFIED READ 1120 * 1121 * This code currently relies on the sequential reader, though it could easily 1122 * be made to work with the progressive one. 1123 */ 1124/* Arguments to png_image_finish_read: */ 1125 1126/* Encoding of PNG data (used by the color-map code) */ 1127/* TODO: change these, dang, ANSI-C reserves the 'E' namespace. */ 1128# define E_NOTSET 0 /* File encoding not yet known */ 1129# define E_sRGB 1 /* 8-bit encoded to sRGB gamma */ 1130# define E_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ 1131# define E_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ 1132# define E_LINEAR8 4 /* 8-bit linear: only from a file value */ 1133 1134/* Color-map processing: after libpng has run on the PNG image further 1135 * processing may be needed to conver the data to color-map indicies. 1136 */ 1137#define PNG_CMAP_NONE 0 1138#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ 1139#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ 1140#define PNG_CMAP_RGB 3 /* Process RGB data */ 1141#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ 1142 1143/* The following document where the background is for each processing case. */ 1144#define PNG_CMAP_NONE_BACKGROUND 256 1145#define PNG_CMAP_GA_BACKGROUND 231 1146#define PNG_CMAP_TRANS_BACKGROUND 254 1147#define PNG_CMAP_RGB_BACKGROUND 256 1148#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 1149 1150typedef struct 1151{ 1152 /* Arguments: */ 1153 png_imagep image; 1154 png_voidp buffer; 1155 png_int_32 row_stride; 1156 png_voidp colormap; 1157 png_const_colorp background; 1158 /* Local variables: */ 1159 png_voidp local_row; 1160 png_voidp first_row; 1161 ptrdiff_t row_bytes; /* step between rows */ 1162 int file_encoding; /* E_ values above */ 1163 png_fixed_point gamma_to_linear; /* For E_FILE, reciprocal of gamma */ 1164 int colormap_processing; /* PNG_CMAP_ values above */ 1165} png_image_read_control; 1166 1167/* Do all the *safe* initialization - 'safe' means that png_error won't be 1168 * called, so setting up the jmp_buf is not required. This means that anything 1169 * called from here must *not* call png_malloc - it has to call png_malloc_warn 1170 * instead so that control is returned safely back to this routine. 1171 */ 1172static int 1173png_image_read_init(png_imagep image) 1174{ 1175 if (image->opaque == NULL) 1176 { 1177 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, 1178 png_safe_error, png_safe_warning); 1179 1180 /* And set the rest of the structure to NULL to ensure that the various 1181 * fields are consistent. 1182 */ 1183 memset(image, 0, (sizeof *image)); 1184 image->version = PNG_IMAGE_VERSION; 1185 1186 if (png_ptr != NULL) 1187 { 1188 png_infop info_ptr = png_create_info_struct(png_ptr); 1189 1190 if (info_ptr != NULL) 1191 { 1192 png_controlp control = png_voidcast(png_controlp, 1193 png_malloc_warn(png_ptr, (sizeof *control))); 1194 1195 if (control != NULL) 1196 { 1197 memset(control, 0, (sizeof *control)); 1198 1199 control->png_ptr = png_ptr; 1200 control->info_ptr = info_ptr; 1201 control->for_write = 0; 1202 1203 image->opaque = control; 1204 return 1; 1205 } 1206 1207 /* Error clean up */ 1208 png_destroy_info_struct(png_ptr, &info_ptr); 1209 } 1210 1211 png_destroy_read_struct(&png_ptr, NULL, NULL); 1212 } 1213 1214 return png_image_error(image, "png_image_read: out of memory"); 1215 } 1216 1217 return png_image_error(image, "png_image_read: opaque pointer not NULL"); 1218} 1219 1220/* Utility to find the base format of a PNG file from a png_struct. */ 1221static png_uint_32 1222png_image_format(png_structrp png_ptr) 1223{ 1224 png_uint_32 format = 0; 1225 1226 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1227 format |= PNG_FORMAT_FLAG_COLOR; 1228 1229 if (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) 1230 format |= PNG_FORMAT_FLAG_ALPHA; 1231 1232 /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS 1233 * sets the png_struct fields; that's all we are interested in here. The 1234 * precise interaction with an app call to png_set_tRNS and PNG file reading 1235 * is unclear. 1236 */ 1237 else if (png_ptr->num_trans > 0) 1238 format |= PNG_FORMAT_FLAG_ALPHA; 1239 1240 if (png_ptr->bit_depth == 16) 1241 format |= PNG_FORMAT_FLAG_LINEAR; 1242 1243 if (png_ptr->color_type & PNG_COLOR_MASK_PALETTE) 1244 format |= PNG_FORMAT_FLAG_COLORMAP; 1245 1246 return format; 1247} 1248 1249/* Is the given gamma significantly different from sRGB? The test is the same 1250 * one used in pngrtran.c when deciding whether to do gamma correction. The 1251 * arithmetic optimizes the division by using the fact that the inverse of the 1252 * file sRGB gamma is 2.2 1253 */ 1254static int 1255png_gamma_not_sRGB(png_fixed_point g) 1256{ 1257 if (g < PNG_FP_1) 1258 { 1259 /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ 1260 if (g == 0) 1261 return 0; 1262 1263 return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); 1264 } 1265 1266 return 1; 1267} 1268 1269/* Do the main body of a 'png_image_begin_read' function; read the PNG file 1270 * header and fill in all the information. This is executed in a safe context, 1271 * unlike the init routine above. 1272 */ 1273static int 1274png_image_read_header(png_voidp argument) 1275{ 1276 png_imagep image = png_voidcast(png_imagep, argument); 1277 png_structrp png_ptr = image->opaque->png_ptr; 1278 png_inforp info_ptr = image->opaque->info_ptr; 1279 1280 png_set_benign_errors(png_ptr, 1/*warn*/); 1281 png_read_info(png_ptr, info_ptr); 1282 1283 /* Do this the fast way; just read directly out of png_struct. */ 1284 image->width = png_ptr->width; 1285 image->height = png_ptr->height; 1286 1287 { 1288 png_uint_32 format = png_image_format(png_ptr); 1289 1290 image->format = format; 1291 1292#ifdef PNG_COLORSPACE_SUPPORTED 1293 /* Does the colorspace match sRGB? If there is no color endpoint 1294 * (colorant) information assume yes, otherwise require the 1295 * 'ENDPOINTS_MATCHE_sRGB' colorspace flag to have been set. If the 1296 * colorspace has been determined to be invalid ignore it. 1297 */ 1298 if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags 1299 & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| 1300 PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) 1301 image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; 1302#endif 1303 } 1304 1305 /* We need the maximum number of entries regardless of the format the 1306 * application sets here. 1307 */ 1308 { 1309 png_uint_32 cmap_entries; 1310 1311 switch (png_ptr->color_type) 1312 { 1313 case PNG_COLOR_TYPE_GRAY: 1314 cmap_entries = 1U << png_ptr->bit_depth; 1315 break; 1316 1317 case PNG_COLOR_TYPE_PALETTE: 1318 cmap_entries = png_ptr->num_palette; 1319 break; 1320 1321 default: 1322 cmap_entries = 256; 1323 break; 1324 } 1325 1326 if (cmap_entries > 256) 1327 cmap_entries = 256; 1328 1329 image->colormap_entries = cmap_entries; 1330 } 1331 1332 return 1; 1333} 1334 1335#ifdef PNG_STDIO_SUPPORTED 1336int PNGAPI 1337png_image_begin_read_from_stdio(png_imagep image, FILE* file) 1338{ 1339 if (image != NULL && image->version == PNG_IMAGE_VERSION) 1340 { 1341 if (file != NULL) 1342 { 1343 if (png_image_read_init(image)) 1344 { 1345 /* This is slightly evil, but png_init_io doesn't do anything other 1346 * than this and we haven't changed the standard IO functions so 1347 * this saves a 'safe' function. 1348 */ 1349 image->opaque->png_ptr->io_ptr = file; 1350 return png_safe_execute(image, png_image_read_header, image); 1351 } 1352 } 1353 1354 else 1355 return png_image_error(image, 1356 "png_image_begin_read_from_stdio: invalid argument"); 1357 } 1358 1359 else if (image != NULL) 1360 return png_image_error(image, 1361 "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); 1362 1363 return 0; 1364} 1365 1366int PNGAPI 1367png_image_begin_read_from_file(png_imagep image, const char *file_name) 1368{ 1369 if (image != NULL && image->version == PNG_IMAGE_VERSION) 1370 { 1371 if (file_name != NULL) 1372 { 1373 FILE *fp = fopen(file_name, "rb"); 1374 1375 if (fp != NULL) 1376 { 1377 if (png_image_read_init(image)) 1378 { 1379 image->opaque->png_ptr->io_ptr = fp; 1380 image->opaque->owned_file = 1; 1381 return png_safe_execute(image, png_image_read_header, image); 1382 } 1383 1384 /* Clean up: just the opened file. */ 1385 (void)fclose(fp); 1386 } 1387 1388 else 1389 return png_image_error(image, strerror(errno)); 1390 } 1391 1392 else 1393 return png_image_error(image, 1394 "png_image_begin_read_from_file: invalid argument"); 1395 } 1396 1397 else if (image != NULL) 1398 return png_image_error(image, 1399 "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); 1400 1401 return 0; 1402} 1403#endif /* PNG_STDIO_SUPPORTED */ 1404 1405static void PNGCBAPI 1406png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) 1407{ 1408 if (png_ptr != NULL) 1409 { 1410 png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); 1411 if (image != NULL) 1412 { 1413 png_controlp cp = image->opaque; 1414 if (cp != NULL) 1415 { 1416 png_const_bytep memory = cp->memory; 1417 png_size_t size = cp->size; 1418 1419 if (memory != NULL && size >= need) 1420 { 1421 memcpy(out, memory, need); 1422 cp->memory = memory + need; 1423 cp->size = size - need; 1424 return; 1425 } 1426 1427 png_error(png_ptr, "read beyond end of data"); 1428 } 1429 } 1430 1431 png_error(png_ptr, "invalid memory read"); 1432 } 1433} 1434 1435int PNGAPI png_image_begin_read_from_memory(png_imagep image, 1436 png_const_voidp memory, png_size_t size) 1437{ 1438 if (image != NULL && image->version == PNG_IMAGE_VERSION) 1439 { 1440 if (memory != NULL && size > 0) 1441 { 1442 if (png_image_read_init(image)) 1443 { 1444 /* Now set the IO functions to read from the memory buffer and 1445 * store it into io_ptr. Again do this in-place to avoid calling a 1446 * libpng function that requires error handling. 1447 */ 1448 image->opaque->memory = png_voidcast(png_const_bytep, memory); 1449 image->opaque->size = size; 1450 image->opaque->png_ptr->io_ptr = image; 1451 image->opaque->png_ptr->read_data_fn = png_image_memory_read; 1452 1453 return png_safe_execute(image, png_image_read_header, image); 1454 } 1455 } 1456 1457 else 1458 return png_image_error(image, 1459 "png_image_begin_read_from_memory: invalid argument"); 1460 } 1461 1462 else if (image != NULL) 1463 return png_image_error(image, 1464 "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); 1465 1466 return 0; 1467} 1468 1469/* Utility function to skip chunks that are not used by the simplified image 1470 * read functions and an appropriate macro to call it. 1471 */ 1472#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 1473static void 1474png_image_skip_unused_chunks(png_structrp png_ptr) 1475{ 1476 /* Prepare the reader to ignore all recognized chunks whose data will not 1477 * be used, i.e., all chunks recognized by libpng except for those 1478 * involved in basic image reading: 1479 * 1480 * IHDR, PLTE, IDAT, IEND 1481 * 1482 * Or image data handling: 1483 * 1484 * tRNS, bKGD, gAMA, cHRM, sRGB, iCCP and sBIT. 1485 * 1486 * This provides a small performance improvement and eliminates any 1487 * potential vulnerability to security problems in the unused chunks. 1488 */ 1489 { 1490 static PNG_CONST png_byte chunks_to_process[] = { 1491 98, 75, 71, 68, '\0', /* bKGD */ 1492 99, 72, 82, 77, '\0', /* cHRM */ 1493 103, 65, 77, 65, '\0', /* gAMA */ 1494 105, 67, 67, 80, '\0', /* iCCP */ 1495 115, 66, 73, 84, '\0', /* sBIT */ 1496 115, 82, 71, 66, '\0', /* sRGB */ 1497 }; 1498 1499 /* Ignore unknown chunks and all other chunks except for the 1500 * IHDR, PLTE, tRNS, IDAT, and IEND chunks. 1501 */ 1502 png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, 1503 NULL, -1); 1504 1505 /* But do not ignore image data handling chunks */ 1506 png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, 1507 chunks_to_process, (sizeof chunks_to_process)/5); 1508 } 1509} 1510 1511# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) 1512#else 1513# define PNG_SKIP_CHUNKS(p) ((void)0) 1514#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */ 1515 1516/* The following macro gives the exact rounded answer for all values in the 1517 * range 0..255 (it actually divides by 51.2, but the rounding still generates 1518 * the correct numbers 0..5 1519 */ 1520#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) 1521 1522/* Utility functions to make particular color-maps */ 1523static void 1524set_file_encoding(png_image_read_control *display) 1525{ 1526 png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; 1527 if (png_gamma_significant(g)) 1528 { 1529 if (png_gamma_not_sRGB(g)) 1530 { 1531 display->file_encoding = E_FILE; 1532 display->gamma_to_linear = png_reciprocal(g); 1533 } 1534 1535 else 1536 display->file_encoding = E_sRGB; 1537 } 1538 1539 else 1540 display->file_encoding = E_LINEAR8; 1541} 1542 1543static unsigned int 1544decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) 1545{ 1546 if (encoding == E_FILE) /* double check */ 1547 encoding = display->file_encoding; 1548 1549 if (encoding == E_NOTSET) /* must be the file encoding */ 1550 { 1551 set_file_encoding(display); 1552 encoding = display->file_encoding; 1553 } 1554 1555 switch (encoding) 1556 { 1557 case E_FILE: 1558 value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); 1559 break; 1560 1561 case E_sRGB: 1562 value = png_sRGB_table[value]; 1563 break; 1564 1565 case E_LINEAR: 1566 break; 1567 1568 case E_LINEAR8: 1569 value *= 257; 1570 break; 1571 1572 default: 1573 png_error(display->image->opaque->png_ptr, 1574 "unexpected encoding (internal error)"); 1575 break; 1576 } 1577 1578 return value; 1579} 1580 1581static png_uint_32 1582png_colormap_compose(png_image_read_control *display, 1583 png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, 1584 png_uint_32 background, int encoding) 1585{ 1586 /* The file value is composed on the background, the background has the given 1587 * encoding and so does the result, the file is encoded with E_FILE and the 1588 * file and alpha are 8-bit values. The (output) encoding will always be 1589 * E_LINEAR or E_sRGB. 1590 */ 1591 png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); 1592 png_uint_32 b = decode_gamma(display, background, encoding); 1593 1594 /* The alpha is always an 8-bit value (it comes from the palette), the value 1595 * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. 1596 */ 1597 f = f * alpha + b * (255-alpha); 1598 1599 if (encoding == E_LINEAR) 1600 { 1601 /* Scale to 65535; divide by 255, approximately (in fact this is extremely 1602 * accurate, it divides by 255.00000005937181414556, with no overflow.) 1603 */ 1604 f *= 257; /* Now scaled by 65535 */ 1605 f += f >> 16; 1606 f = (f+32768) >> 16; 1607 } 1608 1609 else /* E_sRGB */ 1610 f = PNG_sRGB_FROM_LINEAR(f); 1611 1612 return f; 1613} 1614 1615/* NOTE: E_LINEAR values to this routine must be 16-bit, but E_FILE values must 1616 * be 8-bit. 1617 */ 1618static void 1619png_create_colormap_entry(png_image_read_control *display, 1620 png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, 1621 png_uint_32 alpha, int encoding) 1622{ 1623 png_imagep image = display->image; 1624 const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) ? 1625 E_LINEAR : E_sRGB; 1626 const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && 1627 (red != green || green != blue); 1628 1629 if (ip > 255) 1630 png_error(image->opaque->png_ptr, "color-map index out of range"); 1631 1632 /* Update the cache with whether the file gamma is significantly different 1633 * from sRGB. 1634 */ 1635 if (encoding == E_FILE) 1636 { 1637 if (display->file_encoding == E_NOTSET) 1638 set_file_encoding(display); 1639 1640 /* Note that the cached value may be E_FILE too, but if it is then the 1641 * gamma_to_linear member has been set. 1642 */ 1643 encoding = display->file_encoding; 1644 } 1645 1646 if (encoding == E_FILE) 1647 { 1648 png_fixed_point g = display->gamma_to_linear; 1649 1650 red = png_gamma_16bit_correct(red*257, g); 1651 green = png_gamma_16bit_correct(green*257, g); 1652 blue = png_gamma_16bit_correct(blue*257, g); 1653 1654 if (convert_to_Y || output_encoding == E_LINEAR) 1655 { 1656 alpha *= 257; 1657 encoding = E_LINEAR; 1658 } 1659 1660 else 1661 { 1662 red = PNG_sRGB_FROM_LINEAR(red * 255); 1663 green = PNG_sRGB_FROM_LINEAR(green * 255); 1664 blue = PNG_sRGB_FROM_LINEAR(blue * 255); 1665 encoding = E_sRGB; 1666 } 1667 } 1668 1669 else if (encoding == E_LINEAR8) 1670 { 1671 /* This encoding occurs quite frequently in test cases because PngSuite 1672 * includes a gAMA 1.0 chunk with most images. 1673 */ 1674 red *= 257; 1675 green *= 257; 1676 blue *= 257; 1677 alpha *= 257; 1678 encoding = E_LINEAR; 1679 } 1680 1681 else if (encoding == E_sRGB && (convert_to_Y || output_encoding == E_LINEAR)) 1682 { 1683 /* The values are 8-bit sRGB values, but must be converted to 16-bit 1684 * linear. 1685 */ 1686 red = png_sRGB_table[red]; 1687 green = png_sRGB_table[green]; 1688 blue = png_sRGB_table[blue]; 1689 alpha *= 257; 1690 encoding = E_LINEAR; 1691 } 1692 1693 /* This is set if the color isn't gray but the output is. */ 1694 if (encoding == E_LINEAR) 1695 { 1696 if (convert_to_Y) 1697 { 1698 /* NOTE: these values are copied from png_do_rgb_to_gray */ 1699 png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + 1700 (png_uint_32)2366 * blue; 1701 1702 if (output_encoding == E_LINEAR) 1703 y = (y + 16384) >> 15; 1704 1705 else 1706 { 1707 /* y is scaled by 32768, we need it scaled by 255: */ 1708 y = (y + 128) >> 8; 1709 y *= 255; 1710 y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); 1711 encoding = E_sRGB; 1712 } 1713 1714 blue = red = green = y; 1715 } 1716 1717 else if (output_encoding == E_sRGB) 1718 { 1719 red = PNG_sRGB_FROM_LINEAR(red * 255); 1720 green = PNG_sRGB_FROM_LINEAR(green * 255); 1721 blue = PNG_sRGB_FROM_LINEAR(blue * 255); 1722 alpha = PNG_DIV257(alpha); 1723 encoding = E_sRGB; 1724 } 1725 } 1726 1727 if (encoding != output_encoding) 1728 png_error(image->opaque->png_ptr, "bad encoding (internal error)"); 1729 1730 /* Store the value. */ 1731 { 1732# ifdef PNG_FORMAT_BGR_SUPPORTED 1733 const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && 1734 (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; 1735# else 1736# define afirst 0 1737# endif 1738# ifdef PNG_FORMAT_BGR_SUPPORTED 1739 const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) ? 2 : 0; 1740# else 1741# define bgr 0 1742# endif 1743 1744 if (output_encoding == E_LINEAR) 1745 { 1746 png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); 1747 1748 entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); 1749 1750 /* The linear 16-bit values must be pre-multiplied by the alpha channel 1751 * value, if less than 65535 (this is, effectively, composite on black 1752 * if the alpha channel is removed.) 1753 */ 1754 switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) 1755 { 1756 case 4: 1757 entry[afirst ? 0 : 3] = (png_uint_16)alpha; 1758 /* FALL THROUGH */ 1759 1760 case 3: 1761 if (alpha < 65535) 1762 { 1763 if (alpha > 0) 1764 { 1765 blue = (blue * alpha + 32767U)/65535U; 1766 green = (green * alpha + 32767U)/65535U; 1767 red = (red * alpha + 32767U)/65535U; 1768 } 1769 1770 else 1771 red = green = blue = 0; 1772 } 1773 entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; 1774 entry[afirst + 1] = (png_uint_16)green; 1775 entry[afirst + bgr] = (png_uint_16)red; 1776 break; 1777 1778 case 2: 1779 entry[1 ^ afirst] = (png_uint_16)alpha; 1780 /* FALL THROUGH */ 1781 1782 case 1: 1783 if (alpha < 65535) 1784 { 1785 if (alpha > 0) 1786 green = (green * alpha + 32767U)/65535U; 1787 1788 else 1789 green = 0; 1790 } 1791 entry[afirst] = (png_uint_16)green; 1792 break; 1793 1794 default: 1795 break; 1796 } 1797 } 1798 1799 else /* output encoding is E_sRGB */ 1800 { 1801 png_bytep entry = png_voidcast(png_bytep, display->colormap); 1802 1803 entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); 1804 1805 switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) 1806 { 1807 case 4: 1808 entry[afirst ? 0 : 3] = (png_byte)alpha; 1809 case 3: 1810 entry[afirst + (2 ^ bgr)] = (png_byte)blue; 1811 entry[afirst + 1] = (png_byte)green; 1812 entry[afirst + bgr] = (png_byte)red; 1813 break; 1814 1815 case 2: 1816 entry[1 ^ afirst] = (png_byte)alpha; 1817 case 1: 1818 entry[afirst] = (png_byte)green; 1819 break; 1820 1821 default: 1822 break; 1823 } 1824 } 1825 1826# ifdef afirst 1827# undef afirst 1828# endif 1829# ifdef bgr 1830# undef bgr 1831# endif 1832 } 1833} 1834 1835static int 1836make_gray_file_colormap(png_image_read_control *display) 1837{ 1838 unsigned int i; 1839 1840 for (i=0; i<256; ++i) 1841 png_create_colormap_entry(display, i, i, i, i, 255, E_FILE); 1842 1843 return i; 1844} 1845 1846static int 1847make_gray_colormap(png_image_read_control *display) 1848{ 1849 unsigned int i; 1850 1851 for (i=0; i<256; ++i) 1852 png_create_colormap_entry(display, i, i, i, i, 255, E_sRGB); 1853 1854 return i; 1855} 1856#define PNG_GRAY_COLORMAP_ENTRIES 256 1857 1858static int 1859make_ga_colormap(png_image_read_control *display) 1860{ 1861 unsigned int i, a; 1862 1863 /* Alpha is retained, the output will be a color-map with entries 1864 * selected by six levels of alpha. One transparent entry, 6 gray 1865 * levels for all the intermediate alpha values, leaving 230 entries 1866 * for the opaque grays. The color-map entries are the six values 1867 * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the 1868 * relevant entry. 1869 * 1870 * if (alpha > 229) // opaque 1871 * { 1872 * // The 231 entries are selected to make the math below work: 1873 * base = 0; 1874 * entry = (231 * gray + 128) >> 8; 1875 * } 1876 * else if (alpha < 26) // transparent 1877 * { 1878 * base = 231; 1879 * entry = 0; 1880 * } 1881 * else // partially opaque 1882 * { 1883 * base = 226 + 6 * PNG_DIV51(alpha); 1884 * entry = PNG_DIV51(gray); 1885 * } 1886 */ 1887 i = 0; 1888 while (i < 231) 1889 { 1890 unsigned int gray = (i * 256 + 115) / 231; 1891 png_create_colormap_entry(display, i++, gray, gray, gray, 255, E_sRGB); 1892 } 1893 1894 /* 255 is used here for the component values for consistency with the code 1895 * that undoes premultiplication in pngwrite.c. 1896 */ 1897 png_create_colormap_entry(display, i++, 255, 255, 255, 0, E_sRGB); 1898 1899 for (a=1; a<5; ++a) 1900 { 1901 unsigned int g; 1902 1903 for (g=0; g<6; ++g) 1904 png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, 1905 E_sRGB); 1906 } 1907 1908 return i; 1909} 1910 1911#define PNG_GA_COLORMAP_ENTRIES 256 1912 1913static int 1914make_rgb_colormap(png_image_read_control *display) 1915{ 1916 unsigned int i, r; 1917 1918 /* Build a 6x6x6 opaque RGB cube */ 1919 for (i=r=0; r<6; ++r) 1920 { 1921 unsigned int g; 1922 1923 for (g=0; g<6; ++g) 1924 { 1925 unsigned int b; 1926 1927 for (b=0; b<6; ++b) 1928 png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, 1929 E_sRGB); 1930 } 1931 } 1932 1933 return i; 1934} 1935 1936#define PNG_RGB_COLORMAP_ENTRIES 216 1937 1938/* Return a palette index to the above palette given three 8-bit sRGB values. */ 1939#define PNG_RGB_INDEX(r,g,b) \ 1940 ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) 1941 1942static int 1943png_image_read_colormap(png_voidp argument) 1944{ 1945 png_image_read_control *display = 1946 png_voidcast(png_image_read_control*, argument); 1947 const png_imagep image = display->image; 1948 1949 const png_structrp png_ptr = image->opaque->png_ptr; 1950 const png_uint_32 output_format = image->format; 1951 const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) ? 1952 E_LINEAR : E_sRGB; 1953 1954 unsigned int cmap_entries; 1955 unsigned int output_processing; /* Output processing option */ 1956 unsigned int data_encoding = E_NOTSET; /* Encoding libpng must produce */ 1957 1958 /* Background information; the background color and the index of this color 1959 * in the color-map if it exists (else 256). 1960 */ 1961 unsigned int background_index = 256; 1962 png_uint_32 back_r, back_g, back_b; 1963 1964 /* Flags to accumulate things that need to be done to the input. */ 1965 int expand_tRNS = 0; 1966 1967 /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is 1968 * very difficult to do, the results look awful, and it is difficult to see 1969 * what possible use it is because the application can't control the 1970 * color-map. 1971 */ 1972 if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || 1973 png_ptr->num_trans > 0) /* alpha in input */ && 1974 ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) 1975 { 1976 if (output_encoding == E_LINEAR) /* compose on black */ 1977 back_b = back_g = back_r = 0; 1978 1979 else if (display->background == NULL /* no way to remove it */) 1980 png_error(png_ptr, 1981 "a background color must be supplied to remove alpha/transparency"); 1982 1983 /* Get a copy of the background color (this avoids repeating the checks 1984 * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the 1985 * output format. 1986 */ 1987 else 1988 { 1989 back_g = display->background->green; 1990 if (output_format & PNG_FORMAT_FLAG_COLOR) 1991 { 1992 back_r = display->background->red; 1993 back_b = display->background->blue; 1994 } 1995 else 1996 back_b = back_r = back_g; 1997 } 1998 } 1999 2000 else if (output_encoding == E_LINEAR) 2001 back_b = back_r = back_g = 65535; 2002 2003 else 2004 back_b = back_r = back_g = 255; 2005 2006 /* Default the input file gamma if required - this is necessary because 2007 * libpng assumes that if no gamma information is present the data is in the 2008 * output format, but the simplified API deduces the gamma from the input 2009 * format. 2010 */ 2011 if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) 2012 { 2013 /* Do this directly, not using the png_colorspace functions, to ensure 2014 * that it happens even if the colorspace is invalid (though probably if 2015 * it is the setting will be ignored) Note that the same thing can be 2016 * achieved at the application interface with png_set_gAMA. 2017 */ 2018 if (png_ptr->bit_depth == 16 && 2019 (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) 2020 png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; 2021 2022 else 2023 png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; 2024 2025 png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 2026 } 2027 2028 /* Decide what to do based on the PNG color type of the input data. The 2029 * utility function png_create_colormap_entry deals with most aspects of the 2030 * output transformations; this code works out how to produce bytes of 2031 * color-map entries from the original format. 2032 */ 2033 switch (png_ptr->color_type) 2034 { 2035 case PNG_COLOR_TYPE_GRAY: 2036 if (png_ptr->bit_depth <= 8) 2037 { 2038 /* There at most 256 colors in the output, regardless of 2039 * transparency. 2040 */ 2041 unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; 2042 2043 cmap_entries = 1U << png_ptr->bit_depth; 2044 if (cmap_entries > image->colormap_entries) 2045 png_error(png_ptr, "gray[8] color-map: too few entries"); 2046 2047 step = 255 / (cmap_entries - 1); 2048 output_processing = PNG_CMAP_NONE; 2049 2050 /* If there is a tRNS chunk then this either selects a transparent 2051 * value or, if the output has no alpha, the background color. 2052 */ 2053 if (png_ptr->num_trans > 0) 2054 { 2055 trans = png_ptr->trans_color.gray; 2056 2057 if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) 2058 back_alpha = output_encoding == E_LINEAR ? 65535 : 255; 2059 } 2060 2061 /* png_create_colormap_entry just takes an RGBA and writes the 2062 * corresponding color-map entry using the format from 'image', 2063 * including the required conversion to sRGB or linear as 2064 * appropriate. The input values are always either sRGB (if the 2065 * gamma correction flag is 0) or 0..255 scaled file encoded values 2066 * (if the function must gamma correct them). 2067 */ 2068 for (i=val=0; i<cmap_entries; ++i, val += step) 2069 { 2070 /* 'i' is a file value. While this will result in duplicated 2071 * entries for 8-bit non-sRGB encoded files it is necessary to 2072 * have non-gamma corrected values to do tRNS handling. 2073 */ 2074 if (i != trans) 2075 png_create_colormap_entry(display, i, val, val, val, 255, 2076 E_FILE/*8-bit with file gamma*/); 2077 2078 /* Else this entry is transparent. The colors don't matter if 2079 * there is an alpha channel (back_alpha == 0), but it does no 2080 * harm to pass them in; the values are not set above so this 2081 * passes in white. 2082 * 2083 * NOTE: this preserves the full precision of the application 2084 * supplied background color when it is used. 2085 */ 2086 else 2087 png_create_colormap_entry(display, i, back_r, back_g, back_b, 2088 back_alpha, output_encoding); 2089 } 2090 2091 /* We need libpng to preserve the original encoding. */ 2092 data_encoding = E_FILE; 2093 2094 /* The rows from libpng, while technically gray values, are now also 2095 * color-map indicies; however, they may need to be expanded to 1 2096 * byte per pixel. This is what png_set_packing does (i.e., it 2097 * unpacks the bit values into bytes.) 2098 */ 2099 if (png_ptr->bit_depth < 8) 2100 png_set_packing(png_ptr); 2101 } 2102 2103 else /* bit depth is 16 */ 2104 { 2105 /* The 16-bit input values can be converted directly to 8-bit gamma 2106 * encoded values; however, if a tRNS chunk is present 257 color-map 2107 * entries are required. This means that the extra entry requires 2108 * special processing; add an alpha channel, sacrifice gray level 2109 * 254 and convert transparent (alpha==0) entries to that. 2110 * 2111 * Use libpng to chop the data to 8 bits. Convert it to sRGB at the 2112 * same time to minimize quality loss. If a tRNS chunk is present 2113 * this means libpng must handle it too; otherwise it is impossible 2114 * to do the exact match on the 16-bit value. 2115 * 2116 * If the output has no alpha channel *and* the background color is 2117 * gray then it is possible to let libpng handle the substitution by 2118 * ensuring that the corresponding gray level matches the background 2119 * color exactly. 2120 */ 2121 data_encoding = E_sRGB; 2122 2123 if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) 2124 png_error(png_ptr, "gray[16] color-map: too few entries"); 2125 2126 cmap_entries = make_gray_colormap(display); 2127 2128 if (png_ptr->num_trans > 0) 2129 { 2130 unsigned int back_alpha; 2131 2132 if (output_format & PNG_FORMAT_FLAG_ALPHA) 2133 back_alpha = 0; 2134 2135 else 2136 { 2137 if (back_r == back_g && back_g == back_b) 2138 { 2139 /* Background is gray; no special processing will be 2140 * required. 2141 */ 2142 png_color_16 c; 2143 png_uint_32 gray = back_g; 2144 2145 if (output_encoding == E_LINEAR) 2146 { 2147 gray = PNG_sRGB_FROM_LINEAR(gray * 255); 2148 2149 /* And make sure the corresponding palette entry 2150 * matches. 2151 */ 2152 png_create_colormap_entry(display, gray, back_g, back_g, 2153 back_g, 65535, E_LINEAR); 2154 } 2155 2156 /* The background passed to libpng, however, must be the 2157 * sRGB value. 2158 */ 2159 c.index = 0; /*unused*/ 2160 c.gray = c.red = c.green = c.blue = (png_uint_16)gray; 2161 2162 /* NOTE: does this work without expanding tRNS to alpha? 2163 * It should be the color->gray case below apparently 2164 * doesn't. 2165 */ 2166 png_set_background_fixed(png_ptr, &c, 2167 PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 2168 0/*gamma: not used*/); 2169 2170 output_processing = PNG_CMAP_NONE; 2171 break; 2172 } 2173 2174 back_alpha = output_encoding == E_LINEAR ? 65535 : 255; 2175 } 2176 2177 /* output_processing means that the libpng-processed row will be 2178 * 8-bit GA and it has to be processing to single byte color-map 2179 * values. Entry 254 is replaced by either a completely 2180 * transparent entry or by the background color at full 2181 * precision (and the background color is not a simple gray leve 2182 * in this case.) 2183 */ 2184 expand_tRNS = 1; 2185 output_processing = PNG_CMAP_TRANS; 2186 background_index = 254; 2187 2188 /* And set (overwrite) color-map entry 254 to the actual 2189 * background color at full precision. 2190 */ 2191 png_create_colormap_entry(display, 254, back_r, back_g, back_b, 2192 back_alpha, output_encoding); 2193 } 2194 2195 else 2196 output_processing = PNG_CMAP_NONE; 2197 } 2198 break; 2199 2200 case PNG_COLOR_TYPE_GRAY_ALPHA: 2201 /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum 2202 * of 65536 combinations. If, however, the alpha channel is to be 2203 * removed there are only 256 possibilities if the background is gray. 2204 * (Otherwise there is a subset of the 65536 possibilities defined by 2205 * the triangle between black, white and the background color.) 2206 * 2207 * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to 2208 * worry about tRNS matching - tRNS is ignored if there is an alpha 2209 * channel. 2210 */ 2211 data_encoding = E_sRGB; 2212 2213 if (output_format & PNG_FORMAT_FLAG_ALPHA) 2214 { 2215 if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) 2216 png_error(png_ptr, "gray+alpha color-map: too few entries"); 2217 2218 cmap_entries = make_ga_colormap(display); 2219 2220 background_index = PNG_CMAP_GA_BACKGROUND; 2221 output_processing = PNG_CMAP_GA; 2222 } 2223 2224 else /* alpha is removed */ 2225 { 2226 /* Alpha must be removed as the PNG data is processed when the 2227 * background is a color because the G and A channels are 2228 * independent and the vector addition (non-parallel vectors) is a 2229 * 2-D problem. 2230 * 2231 * This can be reduced to the same algorithm as above by making a 2232 * colormap containing gray levels (for the opaque grays), a 2233 * background entry (for a transparent pixel) and a set of four six 2234 * level color values, one set for each intermediate alpha value. 2235 * See the comments in make_ga_colormap for how this works in the 2236 * per-pixel processing. 2237 * 2238 * If the background is gray, however, we only need a 256 entry gray 2239 * level color map. It is sufficient to make the entry generated 2240 * for the background color be exactly the color specified. 2241 */ 2242 if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || 2243 (back_r == back_g && back_g == back_b)) 2244 { 2245 /* Background is gray; no special processing will be required. */ 2246 png_color_16 c; 2247 png_uint_32 gray = back_g; 2248 2249 if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) 2250 png_error(png_ptr, "gray-alpha color-map: too few entries"); 2251 2252 cmap_entries = make_gray_colormap(display); 2253 2254 if (output_encoding == E_LINEAR) 2255 { 2256 gray = PNG_sRGB_FROM_LINEAR(gray * 255); 2257 2258 /* And make sure the corresponding palette entry matches. */ 2259 png_create_colormap_entry(display, gray, back_g, back_g, 2260 back_g, 65535, E_LINEAR); 2261 } 2262 2263 /* The background passed to libpng, however, must be the sRGB 2264 * value. 2265 */ 2266 c.index = 0; /*unused*/ 2267 c.gray = c.red = c.green = c.blue = (png_uint_16)gray; 2268 2269 png_set_background_fixed(png_ptr, &c, 2270 PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 2271 0/*gamma: not used*/); 2272 2273 output_processing = PNG_CMAP_NONE; 2274 } 2275 2276 else 2277 { 2278 png_uint_32 i, a; 2279 2280 /* This is the same as png_make_ga_colormap, above, except that 2281 * the entries are all opaque. 2282 */ 2283 if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) 2284 png_error(png_ptr, "ga-alpha color-map: too few entries"); 2285 2286 i = 0; 2287 while (i < 231) 2288 { 2289 png_uint_32 gray = (i * 256 + 115) / 231; 2290 png_create_colormap_entry(display, i++, gray, gray, gray, 2291 255, E_sRGB); 2292 } 2293 2294 /* NOTE: this preserves the full precision of the application 2295 * background color. 2296 */ 2297 background_index = i; 2298 png_create_colormap_entry(display, i++, back_r, back_g, back_b, 2299 output_encoding == E_LINEAR ? 65535U : 255U, output_encoding); 2300 2301 /* For non-opaque input composite on the sRGB background - this 2302 * requires inverting the encoding for each component. The input 2303 * is still converted to the sRGB encoding because this is a 2304 * reasonable approximate to the logarithmic curve of human 2305 * visual sensitivity, at least over the narrow range which PNG 2306 * represents. Consequently 'G' is always sRGB encoded, while 2307 * 'A' is linear. We need the linear background colors. 2308 */ 2309 if (output_encoding == E_sRGB) /* else already linear */ 2310 { 2311 /* This may produce a value not exactly matching the 2312 * background, but that's ok because these numbers are only 2313 * used when alpha != 0 2314 */ 2315 back_r = png_sRGB_table[back_r]; 2316 back_g = png_sRGB_table[back_g]; 2317 back_b = png_sRGB_table[back_b]; 2318 } 2319 2320 for (a=1; a<5; ++a) 2321 { 2322 unsigned int g; 2323 2324 /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled 2325 * by an 8-bit alpha value (0..255). 2326 */ 2327 png_uint_32 alpha = 51 * a; 2328 png_uint_32 back_rx = (255-alpha) * back_r; 2329 png_uint_32 back_gx = (255-alpha) * back_g; 2330 png_uint_32 back_bx = (255-alpha) * back_b; 2331 2332 for (g=0; g<6; ++g) 2333 { 2334 png_uint_32 gray = png_sRGB_table[g*51] * alpha; 2335 2336 png_create_colormap_entry(display, i++, 2337 PNG_sRGB_FROM_LINEAR(gray + back_rx), 2338 PNG_sRGB_FROM_LINEAR(gray + back_gx), 2339 PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, E_sRGB); 2340 } 2341 } 2342 2343 cmap_entries = i; 2344 output_processing = PNG_CMAP_GA; 2345 } 2346 } 2347 break; 2348 2349 case PNG_COLOR_TYPE_RGB: 2350 case PNG_COLOR_TYPE_RGB_ALPHA: 2351 /* Exclude the case where the output is gray; we can always handle this 2352 * with the cases above. 2353 */ 2354 if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) 2355 { 2356 /* The color-map will be grayscale, so we may as well convert the 2357 * input RGB values to a simple grayscale and use the grayscale 2358 * code above. 2359 * 2360 * NOTE: calling this apparently damages the recognition of the 2361 * transparent color in background color handling; call 2362 * png_set_tRNS_to_alpha before png_set_background_fixed. 2363 */ 2364 png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, 2365 -1); 2366 data_encoding = E_sRGB; 2367 2368 /* The output will now be one or two 8-bit gray or gray+alpha 2369 * channels. The more complex case arises when the input has alpha. 2370 */ 2371 if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 2372 png_ptr->num_trans > 0) && 2373 (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) 2374 { 2375 /* Both input and output have an alpha channel, so no background 2376 * processing is required; just map the GA bytes to the right 2377 * color-map entry. 2378 */ 2379 expand_tRNS = 1; 2380 2381 if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) 2382 png_error(png_ptr, "rgb[ga] color-map: too few entries"); 2383 2384 cmap_entries = make_ga_colormap(display); 2385 background_index = PNG_CMAP_GA_BACKGROUND; 2386 output_processing = PNG_CMAP_GA; 2387 } 2388 2389 else 2390 { 2391 /* Either the input or the output has no alpha channel, so there 2392 * will be no non-opaque pixels in the color-map; it will just be 2393 * grayscale. 2394 */ 2395 if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) 2396 png_error(png_ptr, "rgb[gray] color-map: too few entries"); 2397 2398 /* Ideally this code would use libpng to do the gamma correction, 2399 * but if an input alpha channel is to be removed we will hit the 2400 * libpng bug in gamma+compose+rgb-to-gray (the double gamma 2401 * correction bug). Fix this by dropping the gamma correction in 2402 * this case and doing it in the palette; this will result in 2403 * duplicate palette entries, but that's better than the 2404 * alternative of double gamma correction. 2405 */ 2406 if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 2407 png_ptr->num_trans > 0) && 2408 png_gamma_not_sRGB(png_ptr->colorspace.gamma)) 2409 { 2410 cmap_entries = make_gray_file_colormap(display); 2411 data_encoding = E_FILE; 2412 } 2413 2414 else 2415 cmap_entries = make_gray_colormap(display); 2416 2417 /* But if the input has alpha or transparency it must be removed 2418 */ 2419 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 2420 png_ptr->num_trans > 0) 2421 { 2422 png_color_16 c; 2423 png_uint_32 gray = back_g; 2424 2425 /* We need to ensure that the application background exists in 2426 * the colormap and that completely transparent pixels map to 2427 * it. Achieve this simply by ensuring that the entry 2428 * selected for the background really is the background color. 2429 */ 2430 if (data_encoding == E_FILE) /* from the fixup above */ 2431 { 2432 /* The app supplied a gray which is in output_encoding, we 2433 * need to convert it to a value of the input (E_FILE) 2434 * encoding then set this palette entry to the required 2435 * output encoding. 2436 */ 2437 if (output_encoding == E_sRGB) 2438 gray = png_sRGB_table[gray]; /* now E_LINEAR */ 2439 2440 gray = PNG_DIV257(png_gamma_16bit_correct(gray, 2441 png_ptr->colorspace.gamma)); /* now E_FILE */ 2442 2443 /* And make sure the corresponding palette entry contains 2444 * exactly the required sRGB value. 2445 */ 2446 png_create_colormap_entry(display, gray, back_g, back_g, 2447 back_g, 0/*unused*/, output_encoding); 2448 } 2449 2450 else if (output_encoding == E_LINEAR) 2451 { 2452 gray = PNG_sRGB_FROM_LINEAR(gray * 255); 2453 2454 /* And make sure the corresponding palette entry matches. 2455 */ 2456 png_create_colormap_entry(display, gray, back_g, back_g, 2457 back_g, 0/*unused*/, E_LINEAR); 2458 } 2459 2460 /* The background passed to libpng, however, must be the 2461 * output (normally sRGB) value. 2462 */ 2463 c.index = 0; /*unused*/ 2464 c.gray = c.red = c.green = c.blue = (png_uint_16)gray; 2465 2466 /* NOTE: the following is apparently a bug in libpng. Without 2467 * it the transparent color recognition in 2468 * png_set_background_fixed seems to go wrong. 2469 */ 2470 expand_tRNS = 1; 2471 png_set_background_fixed(png_ptr, &c, 2472 PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 2473 0/*gamma: not used*/); 2474 } 2475 2476 output_processing = PNG_CMAP_NONE; 2477 } 2478 } 2479 2480 else /* output is color */ 2481 { 2482 /* We could use png_quantize here so long as there is no transparent 2483 * color or alpha; png_quantize ignores alpha. Easier overall just 2484 * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. 2485 * Consequently we always want libpng to produce sRGB data. 2486 */ 2487 data_encoding = E_sRGB; 2488 2489 /* Is there any transparency or alpha? */ 2490 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 2491 png_ptr->num_trans > 0) 2492 { 2493 /* Is there alpha in the output too? If so all four channels are 2494 * processed into a special RGB cube with alpha support. 2495 */ 2496 if (output_format & PNG_FORMAT_FLAG_ALPHA) 2497 { 2498 png_uint_32 r; 2499 2500 if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) 2501 png_error(png_ptr, "rgb+alpha color-map: too few entries"); 2502 2503 cmap_entries = make_rgb_colormap(display); 2504 2505 /* Add a transparent entry. */ 2506 png_create_colormap_entry(display, cmap_entries, 255, 255, 2507 255, 0, E_sRGB); 2508 2509 /* This is stored as the background index for the processing 2510 * algorithm. 2511 */ 2512 background_index = cmap_entries++; 2513 2514 /* Add 27 r,g,b entries each with alpha 0.5. */ 2515 for (r=0; r<256; r = (r << 1) | 0x7f) 2516 { 2517 png_uint_32 g; 2518 2519 for (g=0; g<256; g = (g << 1) | 0x7f) 2520 { 2521 png_uint_32 b; 2522 2523 /* This generates components with the values 0, 127 and 2524 * 255 2525 */ 2526 for (b=0; b<256; b = (b << 1) | 0x7f) 2527 png_create_colormap_entry(display, cmap_entries++, 2528 r, g, b, 128, E_sRGB); 2529 } 2530 } 2531 2532 expand_tRNS = 1; 2533 output_processing = PNG_CMAP_RGB_ALPHA; 2534 } 2535 2536 else 2537 { 2538 /* Alpha/transparency must be removed. The background must 2539 * exist in the color map (achieved by setting adding it after 2540 * the 666 color-map). If the standard processing code will 2541 * pick up this entry automatically that's all that is 2542 * required; libpng can be called to do the background 2543 * processing. 2544 */ 2545 unsigned int sample_size = 2546 PNG_IMAGE_SAMPLE_SIZE(output_format); 2547 png_uint_32 r, g, b; /* sRGB background */ 2548 2549 if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) 2550 png_error(png_ptr, "rgb-alpha color-map: too few entries"); 2551 2552 cmap_entries = make_rgb_colormap(display); 2553 2554 png_create_colormap_entry(display, cmap_entries, back_r, 2555 back_g, back_b, 0/*unused*/, output_encoding); 2556 2557 if (output_encoding == E_LINEAR) 2558 { 2559 r = PNG_sRGB_FROM_LINEAR(back_r * 255); 2560 g = PNG_sRGB_FROM_LINEAR(back_g * 255); 2561 b = PNG_sRGB_FROM_LINEAR(back_b * 255); 2562 } 2563 2564 else 2565 { 2566 r = back_r; 2567 g = back_g; 2568 b = back_g; 2569 } 2570 2571 /* Compare the newly-created color-map entry with the one the 2572 * PNG_CMAP_RGB algorithm will use. If the two entries don't 2573 * match, add the new one and set this as the background 2574 * index. 2575 */ 2576 if (memcmp((png_const_bytep)display->colormap + 2577 sample_size * cmap_entries, 2578 (png_const_bytep)display->colormap + 2579 sample_size * PNG_RGB_INDEX(r,g,b), 2580 sample_size) != 0) 2581 { 2582 /* The background color must be added. */ 2583 background_index = cmap_entries++; 2584 2585 /* Add 27 r,g,b entries each with created by composing with 2586 * the background at alpha 0.5. 2587 */ 2588 for (r=0; r<256; r = (r << 1) | 0x7f) 2589 { 2590 for (g=0; g<256; g = (g << 1) | 0x7f) 2591 { 2592 /* This generates components with the values 0, 127 2593 * and 255 2594 */ 2595 for (b=0; b<256; b = (b << 1) | 0x7f) 2596 png_create_colormap_entry(display, cmap_entries++, 2597 png_colormap_compose(display, r, E_sRGB, 128, 2598 back_r, output_encoding), 2599 png_colormap_compose(display, g, E_sRGB, 128, 2600 back_g, output_encoding), 2601 png_colormap_compose(display, b, E_sRGB, 128, 2602 back_b, output_encoding), 2603 0/*unused*/, output_encoding); 2604 } 2605 } 2606 2607 expand_tRNS = 1; 2608 output_processing = PNG_CMAP_RGB_ALPHA; 2609 } 2610 2611 else /* background color is in the standard color-map */ 2612 { 2613 png_color_16 c; 2614 2615 c.index = 0; /*unused*/ 2616 c.red = (png_uint_16)back_r; 2617 c.gray = c.green = (png_uint_16)back_g; 2618 c.blue = (png_uint_16)back_b; 2619 2620 png_set_background_fixed(png_ptr, &c, 2621 PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 2622 0/*gamma: not used*/); 2623 2624 output_processing = PNG_CMAP_RGB; 2625 } 2626 } 2627 } 2628 2629 else /* no alpha or transparency in the input */ 2630 { 2631 /* Alpha in the output is irrelevant, simply map the opaque input 2632 * pixels to the 6x6x6 color-map. 2633 */ 2634 if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) 2635 png_error(png_ptr, "rgb color-map: too few entries"); 2636 2637 cmap_entries = make_rgb_colormap(display); 2638 output_processing = PNG_CMAP_RGB; 2639 } 2640 } 2641 break; 2642 2643 case PNG_COLOR_TYPE_PALETTE: 2644 /* It's already got a color-map. It may be necessary to eliminate the 2645 * tRNS entries though. 2646 */ 2647 { 2648 unsigned int num_trans = png_ptr->num_trans; 2649 png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; 2650 png_const_colorp colormap = png_ptr->palette; 2651 const int do_background = trans != NULL && 2652 (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; 2653 unsigned int i; 2654 2655 /* Just in case: */ 2656 if (trans == NULL) 2657 num_trans = 0; 2658 2659 output_processing = PNG_CMAP_NONE; 2660 data_encoding = E_FILE; /* Don't change from color-map indicies */ 2661 cmap_entries = png_ptr->num_palette; 2662 if (cmap_entries > 256) 2663 cmap_entries = 256; 2664 2665 if (cmap_entries > image->colormap_entries) 2666 png_error(png_ptr, "palette color-map: too few entries"); 2667 2668 for (i=0; i < cmap_entries; ++i) 2669 { 2670 if (do_background && i < num_trans && trans[i] < 255) 2671 { 2672 if (trans[i] == 0) 2673 png_create_colormap_entry(display, i, back_r, back_g, 2674 back_b, 0, output_encoding); 2675 2676 else 2677 { 2678 /* Must compose the PNG file color in the color-map entry 2679 * on the sRGB color in 'back'. 2680 */ 2681 png_create_colormap_entry(display, i, 2682 png_colormap_compose(display, colormap[i].red, E_FILE, 2683 trans[i], back_r, output_encoding), 2684 png_colormap_compose(display, colormap[i].green, E_FILE, 2685 trans[i], back_g, output_encoding), 2686 png_colormap_compose(display, colormap[i].blue, E_FILE, 2687 trans[i], back_b, output_encoding), 2688 output_encoding == E_LINEAR ? trans[i] * 257U : 2689 trans[i], 2690 output_encoding); 2691 } 2692 } 2693 2694 else 2695 png_create_colormap_entry(display, i, colormap[i].red, 2696 colormap[i].green, colormap[i].blue, 2697 i < num_trans ? trans[i] : 255U, E_FILE/*8-bit*/); 2698 } 2699 2700 /* The PNG data may have indicies packed in fewer than 8 bits, it 2701 * must be expanded if so. 2702 */ 2703 if (png_ptr->bit_depth < 8) 2704 png_set_packing(png_ptr); 2705 } 2706 break; 2707 2708 default: 2709 png_error(png_ptr, "invalid PNG color type"); 2710 /*NOT REACHED*/ 2711 break; 2712 } 2713 2714 /* Now deal with the output processing */ 2715 if (expand_tRNS && png_ptr->num_trans > 0 && 2716 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) 2717 png_set_tRNS_to_alpha(png_ptr); 2718 2719 switch (data_encoding) 2720 { 2721 default: 2722 png_error(png_ptr, "bad data option (internal error)"); 2723 break; 2724 2725 case E_sRGB: 2726 /* Change to 8-bit sRGB */ 2727 png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); 2728 /* FALL THROUGH */ 2729 2730 case E_FILE: 2731 if (png_ptr->bit_depth > 8) 2732 png_set_scale_16(png_ptr); 2733 break; 2734 } 2735 2736 if (cmap_entries > 256 || cmap_entries > image->colormap_entries) 2737 png_error(png_ptr, "color map overflow (BAD internal error)"); 2738 2739 image->colormap_entries = cmap_entries; 2740 2741 /* Double check using the recorded background index */ 2742 switch (output_processing) 2743 { 2744 case PNG_CMAP_NONE: 2745 if (background_index != PNG_CMAP_NONE_BACKGROUND) 2746 goto bad_background; 2747 break; 2748 2749 case PNG_CMAP_GA: 2750 if (background_index != PNG_CMAP_GA_BACKGROUND) 2751 goto bad_background; 2752 break; 2753 2754 case PNG_CMAP_TRANS: 2755 if (background_index >= cmap_entries || 2756 background_index != PNG_CMAP_TRANS_BACKGROUND) 2757 goto bad_background; 2758 break; 2759 2760 case PNG_CMAP_RGB: 2761 if (background_index != PNG_CMAP_RGB_BACKGROUND) 2762 goto bad_background; 2763 break; 2764 2765 case PNG_CMAP_RGB_ALPHA: 2766 if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) 2767 goto bad_background; 2768 break; 2769 2770 default: 2771 png_error(png_ptr, "bad processing option (internal error)"); 2772 2773 bad_background: 2774 png_error(png_ptr, "bad background index (internal error)"); 2775 } 2776 2777 display->colormap_processing = output_processing; 2778 2779 return 1/*ok*/; 2780} 2781 2782/* The final part of the color-map read called from png_image_finish_read. */ 2783static int 2784png_image_read_and_map(png_voidp argument) 2785{ 2786 png_image_read_control *display = png_voidcast(png_image_read_control*, 2787 argument); 2788 png_imagep image = display->image; 2789 png_structrp png_ptr = image->opaque->png_ptr; 2790 int passes; 2791 2792 /* Called when the libpng data must be transformed into the color-mapped 2793 * form. There is a local row buffer in display->local and this routine must 2794 * do the interlace handling. 2795 */ 2796 switch (png_ptr->interlaced) 2797 { 2798 case PNG_INTERLACE_NONE: 2799 passes = 1; 2800 break; 2801 2802 case PNG_INTERLACE_ADAM7: 2803 passes = PNG_INTERLACE_ADAM7_PASSES; 2804 break; 2805 2806 default: 2807 passes = 0; 2808 png_error(png_ptr, "unknown interlace type"); 2809 } 2810 2811 { 2812 png_uint_32 height = image->height; 2813 png_uint_32 width = image->width; 2814 int proc = display->colormap_processing; 2815 png_bytep first_row = png_voidcast(png_bytep, display->first_row); 2816 ptrdiff_t step_row = display->row_bytes; 2817 int pass; 2818 2819 for (pass = 0; pass < passes; ++pass) 2820 { 2821 unsigned int startx, stepx, stepy; 2822 png_uint_32 y; 2823 2824 if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 2825 { 2826 /* The row may be empty for a short image: */ 2827 if (PNG_PASS_COLS(width, pass) == 0) 2828 continue; 2829 2830 startx = PNG_PASS_START_COL(pass); 2831 stepx = PNG_PASS_COL_OFFSET(pass); 2832 y = PNG_PASS_START_ROW(pass); 2833 stepy = PNG_PASS_ROW_OFFSET(pass); 2834 } 2835 2836 else 2837 { 2838 y = 0; 2839 startx = 0; 2840 stepx = stepy = 1; 2841 } 2842 2843 for (; y<height; y += stepy) 2844 { 2845 png_bytep inrow = png_voidcast(png_bytep, display->local_row); 2846 png_bytep outrow = first_row + y * step_row; 2847 png_const_bytep end_row = outrow + width; 2848 2849 /* Read read the libpng data into the temporary buffer. */ 2850 png_read_row(png_ptr, inrow, NULL); 2851 2852 /* Now process the row according to the processing option, note 2853 * that the caller verifies that the format of the libpng output 2854 * data is as required. 2855 */ 2856 outrow += startx; 2857 switch (proc) 2858 { 2859 case PNG_CMAP_GA: 2860 for (; outrow < end_row; outrow += stepx) 2861 { 2862 /* The data is always in the PNG order */ 2863 unsigned int gray = *inrow++; 2864 unsigned int alpha = *inrow++; 2865 unsigned int entry; 2866 2867 /* NOTE: this code is copied as a comment in 2868 * make_ga_colormap above. Please update the 2869 * comment if you change this code! 2870 */ 2871 if (alpha > 229) /* opaque */ 2872 { 2873 entry = (231 * gray + 128) >> 8; 2874 } 2875 else if (alpha < 26) /* transparent */ 2876 { 2877 entry = 231; 2878 } 2879 else /* partially opaque */ 2880 { 2881 entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); 2882 } 2883 2884 *outrow = (png_byte)entry; 2885 } 2886 break; 2887 2888 case PNG_CMAP_TRANS: 2889 for (; outrow < end_row; outrow += stepx) 2890 { 2891 png_byte gray = *inrow++; 2892 png_byte alpha = *inrow++; 2893 2894 if (alpha == 0) 2895 *outrow = PNG_CMAP_TRANS_BACKGROUND; 2896 2897 else if (gray != PNG_CMAP_TRANS_BACKGROUND) 2898 *outrow = gray; 2899 2900 else 2901 *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); 2902 } 2903 break; 2904 2905 case PNG_CMAP_RGB: 2906 for (; outrow < end_row; outrow += stepx) 2907 { 2908 *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); 2909 inrow += 3; 2910 } 2911 break; 2912 2913 case PNG_CMAP_RGB_ALPHA: 2914 for (; outrow < end_row; outrow += stepx) 2915 { 2916 unsigned int alpha = inrow[3]; 2917 2918 /* Because the alpha entries only hold alpha==0.5 values 2919 * split the processing at alpha==0.25 (64) and 0.75 2920 * (196). 2921 */ 2922 2923 if (alpha >= 196) 2924 *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], 2925 inrow[2]); 2926 2927 else if (alpha < 64) 2928 *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; 2929 2930 else 2931 { 2932 /* Likewise there are three entries for each of r, g 2933 * and b. We could select the entry by popcount on 2934 * the top two bits on those architectures that 2935 * support it, this is what the code below does, 2936 * crudely. 2937 */ 2938 unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; 2939 2940 /* Here are how the values map: 2941 * 2942 * 0x00 .. 0x3f -> 0 2943 * 0x40 .. 0xbf -> 1 2944 * 0xc0 .. 0xff -> 2 2945 * 2946 * So, as above with the explicit alpha checks, the 2947 * breakpoints are at 64 and 196. 2948 */ 2949 if (inrow[0] & 0x80) back_i += 9; /* red */ 2950 if (inrow[0] & 0x40) back_i += 9; 2951 if (inrow[0] & 0x80) back_i += 3; /* green */ 2952 if (inrow[0] & 0x40) back_i += 3; 2953 if (inrow[0] & 0x80) back_i += 1; /* blue */ 2954 if (inrow[0] & 0x40) back_i += 1; 2955 2956 *outrow = (png_byte)back_i; 2957 } 2958 2959 inrow += 4; 2960 } 2961 break; 2962 2963 default: 2964 break; 2965 } 2966 } 2967 } 2968 } 2969 2970 return 1; 2971} 2972 2973static int 2974png_image_read_colormapped(png_voidp argument) 2975{ 2976 png_image_read_control *display = png_voidcast(png_image_read_control*, 2977 argument); 2978 png_imagep image = display->image; 2979 png_controlp control = image->opaque; 2980 png_structrp png_ptr = control->png_ptr; 2981 png_inforp info_ptr = control->info_ptr; 2982 2983 int passes = 0; /* As a flag */ 2984 2985 PNG_SKIP_CHUNKS(png_ptr); 2986 2987 /* Update the 'info' structure and make sure the result is as required; first 2988 * make sure to turn on the interlace handling if it will be required 2989 * (because it can't be turned on *after* the call to png_read_update_info!) 2990 */ 2991 if (display->colormap_processing == PNG_CMAP_NONE) 2992 passes = png_set_interlace_handling(png_ptr); 2993 2994 png_read_update_info(png_ptr, info_ptr); 2995 2996 /* The expected output can be deduced from the colormap_processing option. */ 2997 switch (display->colormap_processing) 2998 { 2999 case PNG_CMAP_NONE: 3000 /* Output must be one channel and one byte per pixel, the output 3001 * encoding can be anything. 3002 */ 3003 if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || 3004 info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && 3005 info_ptr->bit_depth == 8) 3006 break; 3007 3008 goto bad_output; 3009 3010 case PNG_CMAP_TRANS: 3011 case PNG_CMAP_GA: 3012 /* Output must be two channels and the 'G' one must be sRGB, the latter 3013 * can be checked with an exact number because it should have been set 3014 * to this number above! 3015 */ 3016 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && 3017 info_ptr->bit_depth == 8 && 3018 png_ptr->screen_gamma == PNG_GAMMA_sRGB && 3019 image->colormap_entries == 256) 3020 break; 3021 3022 goto bad_output; 3023 3024 case PNG_CMAP_RGB: 3025 /* Output must be 8-bit sRGB encoded RGB */ 3026 if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && 3027 info_ptr->bit_depth == 8 && 3028 png_ptr->screen_gamma == PNG_GAMMA_sRGB && 3029 image->colormap_entries == 216) 3030 break; 3031 3032 goto bad_output; 3033 3034 case PNG_CMAP_RGB_ALPHA: 3035 /* Output must be 8-bit sRGB encoded RGBA */ 3036 if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 3037 info_ptr->bit_depth == 8 && 3038 png_ptr->screen_gamma == PNG_GAMMA_sRGB && 3039 image->colormap_entries == 244 /* 216 + 1 + 27 */) 3040 break; 3041 3042 /* goto bad_output; */ 3043 /* FALL THROUGH */ 3044 3045 default: 3046 bad_output: 3047 png_error(png_ptr, "bad color-map processing (internal error)"); 3048 } 3049 3050 /* Now read the rows. Do this here if it is possible to read directly into 3051 * the output buffer, otherwise allocate a local row buffer of the maximum 3052 * size libpng requires and call the relevant processing routine safely. 3053 */ 3054 { 3055 png_voidp first_row = display->buffer; 3056 ptrdiff_t row_bytes = display->row_stride; 3057 3058 /* The following expression is designed to work correctly whether it gives 3059 * a signed or an unsigned result. 3060 */ 3061 if (row_bytes < 0) 3062 { 3063 char *ptr = png_voidcast(char*, first_row); 3064 ptr += (image->height-1) * (-row_bytes); 3065 first_row = png_voidcast(png_voidp, ptr); 3066 } 3067 3068 display->first_row = first_row; 3069 display->row_bytes = row_bytes; 3070 } 3071 3072 if (passes == 0) 3073 { 3074 int result; 3075 png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); 3076 3077 display->local_row = row; 3078 result = png_safe_execute(image, png_image_read_and_map, display); 3079 display->local_row = NULL; 3080 png_free(png_ptr, row); 3081 3082 return result; 3083 } 3084 3085 else 3086 { 3087 png_alloc_size_t row_bytes = display->row_bytes; 3088 3089 while (--passes >= 0) 3090 { 3091 png_uint_32 y = image->height; 3092 png_bytep row = png_voidcast(png_bytep, display->first_row); 3093 3094 while (y-- > 0) 3095 { 3096 png_read_row(png_ptr, row, NULL); 3097 row += row_bytes; 3098 } 3099 } 3100 3101 return 1; 3102 } 3103} 3104 3105/* Just the row reading part of png_image_read. */ 3106static int 3107png_image_read_composite(png_voidp argument) 3108{ 3109 png_image_read_control *display = png_voidcast(png_image_read_control*, 3110 argument); 3111 png_imagep image = display->image; 3112 png_structrp png_ptr = image->opaque->png_ptr; 3113 int passes; 3114 3115 switch (png_ptr->interlaced) 3116 { 3117 case PNG_INTERLACE_NONE: 3118 passes = 1; 3119 break; 3120 3121 case PNG_INTERLACE_ADAM7: 3122 passes = PNG_INTERLACE_ADAM7_PASSES; 3123 break; 3124 3125 default: 3126 passes = 0; 3127 png_error(png_ptr, "unknown interlace type"); 3128 } 3129 3130 { 3131 png_uint_32 height = image->height; 3132 png_uint_32 width = image->width; 3133 ptrdiff_t step_row = display->row_bytes; 3134 unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1; 3135 int pass; 3136 3137 for (pass = 0; pass < passes; ++pass) 3138 { 3139 unsigned int startx, stepx, stepy; 3140 png_uint_32 y; 3141 3142 if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 3143 { 3144 /* The row may be empty for a short image: */ 3145 if (PNG_PASS_COLS(width, pass) == 0) 3146 continue; 3147 3148 startx = PNG_PASS_START_COL(pass) * channels; 3149 stepx = PNG_PASS_COL_OFFSET(pass) * channels; 3150 y = PNG_PASS_START_ROW(pass); 3151 stepy = PNG_PASS_ROW_OFFSET(pass); 3152 } 3153 3154 else 3155 { 3156 y = 0; 3157 startx = 0; 3158 stepx = channels; 3159 stepy = 1; 3160 } 3161 3162 for (; y<height; y += stepy) 3163 { 3164 png_bytep inrow = png_voidcast(png_bytep, display->local_row); 3165 png_bytep outrow; 3166 png_const_bytep end_row; 3167 3168 /* Read the row, which is packed: */ 3169 png_read_row(png_ptr, inrow, NULL); 3170 3171 outrow = png_voidcast(png_bytep, display->first_row); 3172 outrow += y * step_row; 3173 end_row = outrow + width * channels; 3174 3175 /* Now do the composition on each pixel in this row. */ 3176 outrow += startx; 3177 for (; outrow < end_row; outrow += stepx) 3178 { 3179 png_byte alpha = inrow[channels]; 3180 3181 if (alpha > 0) /* else no change to the output */ 3182 { 3183 unsigned int c; 3184 3185 for (c=0; c<channels; ++c) 3186 { 3187 png_uint_32 component = inrow[c]; 3188 3189 if (alpha < 255) /* else just use component */ 3190 { 3191 /* This is PNG_OPTIMIZED_ALPHA, the component value 3192 * is a linear 8-bit value. Combine this with the 3193 * current outrow[c] value which is sRGB encoded. 3194 * Arithmetic here is 16-bits to preserve the output 3195 * values correctly. 3196 */ 3197 component *= 257*255; /* =65535 */ 3198 component += (255-alpha)*png_sRGB_table[outrow[c]]; 3199 3200 /* So 'component' is scaled by 255*65535 and is 3201 * therefore appropriate for the sRGB to linear 3202 * conversion table. 3203 */ 3204 component = PNG_sRGB_FROM_LINEAR(component); 3205 } 3206 3207 outrow[c] = (png_byte)component; 3208 } 3209 } 3210 3211 inrow += channels+1; /* components and alpha channel */ 3212 } 3213 } 3214 } 3215 } 3216 3217 return 1; 3218} 3219 3220/* The do_local_background case; called when all the following transforms are to 3221 * be done: 3222 * 3223 * PNG_RGB_TO_GRAY 3224 * PNG_COMPOSITE 3225 * PNG_GAMMA 3226 * 3227 * This is a work-round for the fact that both the PNG_RGB_TO_GRAY and 3228 * PNG_COMPOSITE code performs gamma correction, so we get double gamma 3229 * correction. The fix-up is to prevent the PNG_COMPOSITE operation happening 3230 * inside libpng, so this routine sees an 8 or 16-bit gray+alpha row and handles 3231 * the removal or pre-multiplication of the alpha channel. 3232 */ 3233static int 3234png_image_read_background(png_voidp argument) 3235{ 3236 png_image_read_control *display = png_voidcast(png_image_read_control*, 3237 argument); 3238 png_imagep image = display->image; 3239 png_structrp png_ptr = image->opaque->png_ptr; 3240 png_inforp info_ptr = image->opaque->info_ptr; 3241 png_uint_32 height = image->height; 3242 png_uint_32 width = image->width; 3243 int pass, passes; 3244 3245 /* Double check the convoluted logic below. We expect to get here with 3246 * libpng doing rgb to gray and gamma correction but background processing 3247 * left to the png_image_read_background function. The rows libpng produce 3248 * might be 8 or 16-bit but should always have two channels; gray plus alpha. 3249 */ 3250 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) 3251 png_error(png_ptr, "lost rgb to gray"); 3252 3253 if ((png_ptr->transformations & PNG_COMPOSE) != 0) 3254 png_error(png_ptr, "unexpected compose"); 3255 3256 if (png_get_channels(png_ptr, info_ptr) != 2) 3257 png_error(png_ptr, "lost/gained channels"); 3258 3259 /* Expect the 8-bit case to always remove the alpha channel */ 3260 if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && 3261 (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) 3262 png_error(png_ptr, "unexpected 8-bit transformation"); 3263 3264 switch (png_ptr->interlaced) 3265 { 3266 case PNG_INTERLACE_NONE: 3267 passes = 1; 3268 break; 3269 3270 case PNG_INTERLACE_ADAM7: 3271 passes = PNG_INTERLACE_ADAM7_PASSES; 3272 break; 3273 3274 default: 3275 passes = 0; 3276 png_error(png_ptr, "unknown interlace type"); 3277 } 3278 3279 switch (png_get_bit_depth(png_ptr, info_ptr)) 3280 { 3281 default: 3282 png_error(png_ptr, "unexpected bit depth"); 3283 break; 3284 3285 case 8: 3286 /* 8-bit sRGB gray values with an alpha channel; the alpha channel is 3287 * to be removed by composing on a backgroundi: either the row if 3288 * display->background is NULL or display->background->green if not. 3289 * Unlike the code above ALPHA_OPTIMIZED has *not* been done. 3290 */ 3291 { 3292 png_bytep first_row = png_voidcast(png_bytep, display->first_row); 3293 ptrdiff_t step_row = display->row_bytes; 3294 3295 for (pass = 0; pass < passes; ++pass) 3296 { 3297 png_bytep row = png_voidcast(png_bytep, 3298 display->first_row); 3299 unsigned int startx, stepx, stepy; 3300 png_uint_32 y; 3301 3302 if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 3303 { 3304 /* The row may be empty for a short image: */ 3305 if (PNG_PASS_COLS(width, pass) == 0) 3306 continue; 3307 3308 startx = PNG_PASS_START_COL(pass); 3309 stepx = PNG_PASS_COL_OFFSET(pass); 3310 y = PNG_PASS_START_ROW(pass); 3311 stepy = PNG_PASS_ROW_OFFSET(pass); 3312 } 3313 3314 else 3315 { 3316 y = 0; 3317 startx = 0; 3318 stepx = stepy = 1; 3319 } 3320 3321 if (display->background == NULL) 3322 { 3323 for (; y<height; y += stepy) 3324 { 3325 png_bytep inrow = png_voidcast(png_bytep, 3326 display->local_row); 3327 png_bytep outrow = first_row + y * step_row; 3328 png_const_bytep end_row = outrow + width; 3329 3330 /* Read the row, which is packed: */ 3331 png_read_row(png_ptr, inrow, NULL); 3332 3333 /* Now do the composition on each pixel in this row. */ 3334 outrow += startx; 3335 for (; outrow < end_row; outrow += stepx) 3336 { 3337 png_byte alpha = inrow[1]; 3338 3339 if (alpha > 0) /* else no change to the output */ 3340 { 3341 png_uint_32 component = inrow[0]; 3342 3343 if (alpha < 255) /* else just use component */ 3344 { 3345 /* Since PNG_OPTIMIZED_ALPHA was not set it is 3346 * necessary to invert the sRGB transfer 3347 * function and multiply the alpha out. 3348 */ 3349 component = png_sRGB_table[component] * alpha; 3350 component += png_sRGB_table[outrow[0]] * 3351 (255-alpha); 3352 component = PNG_sRGB_FROM_LINEAR(component); 3353 } 3354 3355 outrow[0] = (png_byte)component; 3356 } 3357 3358 inrow += 2; /* gray and alpha channel */ 3359 } 3360 } 3361 } 3362 3363 else /* constant background value */ 3364 { 3365 png_byte background8 = display->background->green; 3366 png_uint_16 background = png_sRGB_table[background8]; 3367 3368 for (; y<height; y += stepy) 3369 { 3370 png_bytep inrow = png_voidcast(png_bytep, 3371 display->local_row); 3372 png_bytep outrow = first_row + y * step_row; 3373 png_const_bytep end_row = outrow + width; 3374 3375 /* Read the row, which is packed: */ 3376 png_read_row(png_ptr, inrow, NULL); 3377 3378 /* Now do the composition on each pixel in this row. */ 3379 outrow += startx; 3380 for (; outrow < end_row; outrow += stepx) 3381 { 3382 png_byte alpha = inrow[1]; 3383 3384 if (alpha > 0) /* else use background */ 3385 { 3386 png_uint_32 component = inrow[0]; 3387 3388 if (alpha < 255) /* else just use component */ 3389 { 3390 component = png_sRGB_table[component] * alpha; 3391 component += background * (255-alpha); 3392 component = PNG_sRGB_FROM_LINEAR(component); 3393 } 3394 3395 outrow[0] = (png_byte)component; 3396 } 3397 3398 else 3399 outrow[0] = background8; 3400 3401 inrow += 2; /* gray and alpha channel */ 3402 } 3403 3404 row += display->row_bytes; 3405 } 3406 } 3407 } 3408 } 3409 break; 3410 3411 case 16: 3412 /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must 3413 * still be done and, maybe, the alpha channel removed. This code also 3414 * handles the alpha-first option. 3415 */ 3416 { 3417 png_uint_16p first_row = png_voidcast(png_uint_16p, 3418 display->first_row); 3419 /* The division by two is safe because the caller passed in a 3420 * stride which was multiplied by 2 (below) to get row_bytes. 3421 */ 3422 ptrdiff_t step_row = display->row_bytes / 2; 3423 int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; 3424 unsigned int outchannels = 1+preserve_alpha; 3425 int swap_alpha = 0; 3426 3427 if (preserve_alpha && (image->format & PNG_FORMAT_FLAG_AFIRST)) 3428 swap_alpha = 1; 3429 3430 for (pass = 0; pass < passes; ++pass) 3431 { 3432 unsigned int startx, stepx, stepy; 3433 png_uint_32 y; 3434 3435 /* The 'x' start and step are adjusted to output components here. 3436 */ 3437 if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 3438 { 3439 /* The row may be empty for a short image: */ 3440 if (PNG_PASS_COLS(width, pass) == 0) 3441 continue; 3442 3443 startx = PNG_PASS_START_COL(pass) * outchannels; 3444 stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; 3445 y = PNG_PASS_START_ROW(pass); 3446 stepy = PNG_PASS_ROW_OFFSET(pass); 3447 } 3448 3449 else 3450 { 3451 y = 0; 3452 startx = 0; 3453 stepx = outchannels; 3454 stepy = 1; 3455 } 3456 3457 for (; y<height; y += stepy) 3458 { 3459 png_const_uint_16p inrow; 3460 png_uint_16p outrow = first_row + y*step_row; 3461 png_uint_16p end_row = outrow + width * outchannels; 3462 3463 /* Read the row, which is packed: */ 3464 png_read_row(png_ptr, png_voidcast(png_bytep, 3465 display->local_row), NULL); 3466 inrow = png_voidcast(png_const_uint_16p, display->local_row); 3467 3468 /* Now do the pre-multiplication on each pixel in this row. 3469 */ 3470 outrow += startx; 3471 for (; outrow < end_row; outrow += stepx) 3472 { 3473 png_uint_32 component = inrow[0]; 3474 png_uint_16 alpha = inrow[1]; 3475 3476 if (alpha > 0) /* else 0 */ 3477 { 3478 if (alpha < 65535) /* else just use component */ 3479 { 3480 component *= alpha; 3481 component += 32767; 3482 component /= 65535; 3483 } 3484 } 3485 3486 else 3487 component = 0; 3488 3489 outrow[swap_alpha] = (png_uint_16)component; 3490 if (preserve_alpha) 3491 outrow[1 ^ swap_alpha] = alpha; 3492 3493 inrow += 2; /* components and alpha channel */ 3494 } 3495 } 3496 } 3497 } 3498 break; 3499 } 3500 3501 return 1; 3502} 3503 3504/* The guts of png_image_finish_read as a png_safe_execute callback. */ 3505static int 3506png_image_read_direct(png_voidp argument) 3507{ 3508 png_image_read_control *display = png_voidcast(png_image_read_control*, 3509 argument); 3510 png_imagep image = display->image; 3511 png_structrp png_ptr = image->opaque->png_ptr; 3512 png_inforp info_ptr = image->opaque->info_ptr; 3513 3514 png_uint_32 format = image->format; 3515 int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; 3516 int do_local_compose = 0; 3517 int do_local_background = 0; /* to avoid double gamma correction bug */ 3518 int passes = 0; 3519 3520 /* Add transforms to ensure the correct output format is produced then check 3521 * that the required implementation support is there. Always expand; always 3522 * need 8 bits minimum, no palette and expanded tRNS. 3523 */ 3524 png_set_expand(png_ptr); 3525 3526 /* Now check the format to see if it was modified. */ 3527 { 3528 png_uint_32 base_format = png_image_format(png_ptr) & 3529 ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; 3530 png_uint_32 change = format ^ base_format; 3531 png_fixed_point output_gamma; 3532 int mode; /* alpha mode */ 3533 3534 /* Do this first so that we have a record if rgb to gray is happening. */ 3535 if (change & PNG_FORMAT_FLAG_COLOR) 3536 { 3537 /* gray<->color transformation required. */ 3538 if (format & PNG_FORMAT_FLAG_COLOR) 3539 png_set_gray_to_rgb(png_ptr); 3540 3541 else 3542 { 3543 /* libpng can't do both rgb to gray and 3544 * background/pre-multiplication if there is also significant gamma 3545 * correction, because both operations require linear colors and 3546 * the code only supports one transform doing the gamma correction. 3547 * Handle this by doing the pre-multiplication or background 3548 * operation in this code, if necessary. 3549 * 3550 * TODO: fix this by rewriting pngrtran.c (!) 3551 * 3552 * For the moment (given that fixing this in pngrtran.c is an 3553 * enormous change) 'do_local_background' is used to indicate that 3554 * the problem exists. 3555 */ 3556 if (base_format & PNG_FORMAT_FLAG_ALPHA) 3557 do_local_background = 1/*maybe*/; 3558 3559 png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, 3560 PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); 3561 } 3562 3563 change &= ~PNG_FORMAT_FLAG_COLOR; 3564 } 3565 3566 /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. 3567 */ 3568 { 3569 png_fixed_point input_gamma_default; 3570 3571 if ((base_format & PNG_FORMAT_FLAG_LINEAR) && 3572 (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) 3573 input_gamma_default = PNG_GAMMA_LINEAR; 3574 else 3575 input_gamma_default = PNG_DEFAULT_sRGB; 3576 3577 /* Call png_set_alpha_mode to set the default for the input gamma; the 3578 * output gamma is set by a second call below. 3579 */ 3580 png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); 3581 } 3582 3583 if (linear) 3584 { 3585 /* If there *is* an alpha channel in the input it must be multiplied 3586 * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. 3587 */ 3588 if (base_format & PNG_FORMAT_FLAG_ALPHA) 3589 mode = PNG_ALPHA_STANDARD; /* associated alpha */ 3590 3591 else 3592 mode = PNG_ALPHA_PNG; 3593 3594 output_gamma = PNG_GAMMA_LINEAR; 3595 } 3596 3597 else 3598 { 3599 mode = PNG_ALPHA_PNG; 3600 output_gamma = PNG_DEFAULT_sRGB; 3601 } 3602 3603 /* If 'do_local_background' is set check for the presence of gamma 3604 * correction; this is part of the work-round for the libpng bug 3605 * described above. 3606 * 3607 * TODO: fix libpng and remove this. 3608 */ 3609 if (do_local_background) 3610 { 3611 png_fixed_point gtest; 3612 3613 /* This is 'png_gamma_threshold' from pngrtran.c; the test used for 3614 * gamma correction, the screen gamma hasn't been set on png_struct 3615 * yet; it's set below. png_struct::gamma, however, is set to the 3616 * final value. 3617 */ 3618 if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, 3619 PNG_FP_1) && !png_gamma_significant(gtest)) 3620 do_local_background = 0; 3621 3622 else if (mode == PNG_ALPHA_STANDARD) 3623 { 3624 do_local_background = 2/*required*/; 3625 mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ 3626 } 3627 3628 /* else leave as 1 for the checks below */ 3629 } 3630 3631 /* If the bit-depth changes then handle that here. */ 3632 if (change & PNG_FORMAT_FLAG_LINEAR) 3633 { 3634 if (linear /*16-bit output*/) 3635 png_set_expand_16(png_ptr); 3636 3637 else /* 8-bit output */ 3638 png_set_scale_16(png_ptr); 3639 3640 change &= ~PNG_FORMAT_FLAG_LINEAR; 3641 } 3642 3643 /* Now the background/alpha channel changes. */ 3644 if (change & PNG_FORMAT_FLAG_ALPHA) 3645 { 3646 /* Removing an alpha channel requires composition for the 8-bit 3647 * formats; for the 16-bit it is already done, above, by the 3648 * pre-multiplication and the channel just needs to be stripped. 3649 */ 3650 if (base_format & PNG_FORMAT_FLAG_ALPHA) 3651 { 3652 /* If RGB->gray is happening the alpha channel must be left and the 3653 * operation completed locally. 3654 * 3655 * TODO: fix libpng and remove this. 3656 */ 3657 if (do_local_background) 3658 do_local_background = 2/*required*/; 3659 3660 /* 16-bit output: just remove the channel */ 3661 else if (linear) /* compose on black (well, pre-multiply) */ 3662 png_set_strip_alpha(png_ptr); 3663 3664 /* 8-bit output: do an appropriate compose */ 3665 else if (display->background != NULL) 3666 { 3667 png_color_16 c; 3668 3669 c.index = 0; /*unused*/ 3670 c.red = display->background->red; 3671 c.green = display->background->green; 3672 c.blue = display->background->blue; 3673 c.gray = display->background->green; 3674 3675 /* This is always an 8-bit sRGB value, using the 'green' channel 3676 * for gray is much better than calculating the luminance here; 3677 * we can get off-by-one errors in that calculation relative to 3678 * the app expectations and that will show up in transparent 3679 * pixels. 3680 */ 3681 png_set_background_fixed(png_ptr, &c, 3682 PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 3683 0/*gamma: not used*/); 3684 } 3685 3686 else /* compose on row: implemented below. */ 3687 { 3688 do_local_compose = 1; 3689 /* This leaves the alpha channel in the output, so it has to be 3690 * removed by the code below. Set the encoding to the 'OPTIMIZE' 3691 * one so the code only has to hack on the pixels that require 3692 * composition. 3693 */ 3694 mode = PNG_ALPHA_OPTIMIZED; 3695 } 3696 } 3697 3698 else /* output needs an alpha channel */ 3699 { 3700 /* This is tricky because it happens before the swap operation has 3701 * been accomplished; however, the swap does *not* swap the added 3702 * alpha channel (weird API), so it must be added in the correct 3703 * place. 3704 */ 3705 png_uint_32 filler; /* opaque filler */ 3706 int where; 3707 3708 if (linear) 3709 filler = 65535; 3710 3711 else 3712 filler = 255; 3713 3714# ifdef PNG_FORMAT_AFIRST_SUPPORTED 3715 if (format & PNG_FORMAT_FLAG_AFIRST) 3716 { 3717 where = PNG_FILLER_BEFORE; 3718 change &= ~PNG_FORMAT_FLAG_AFIRST; 3719 } 3720 3721 else 3722# endif 3723 where = PNG_FILLER_AFTER; 3724 3725 png_set_add_alpha(png_ptr, filler, where); 3726 } 3727 3728 /* This stops the (irrelevant) call to swap_alpha below. */ 3729 change &= ~PNG_FORMAT_FLAG_ALPHA; 3730 } 3731 3732 /* Now set the alpha mode correctly; this is always done, even if there is 3733 * no alpha channel in either the input or the output because it correctly 3734 * sets the output gamma. 3735 */ 3736 png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); 3737 3738# ifdef PNG_FORMAT_BGR_SUPPORTED 3739 if (change & PNG_FORMAT_FLAG_BGR) 3740 { 3741 /* Check only the output format; PNG is never BGR; don't do this if 3742 * the output is gray, but fix up the 'format' value in that case. 3743 */ 3744 if (format & PNG_FORMAT_FLAG_COLOR) 3745 png_set_bgr(png_ptr); 3746 3747 else 3748 format &= ~PNG_FORMAT_FLAG_BGR; 3749 3750 change &= ~PNG_FORMAT_FLAG_BGR; 3751 } 3752# endif 3753 3754# ifdef PNG_FORMAT_AFIRST_SUPPORTED 3755 if (change & PNG_FORMAT_FLAG_AFIRST) 3756 { 3757 /* Only relevant if there is an alpha channel - it's particularly 3758 * important to handle this correctly because do_local_compose may 3759 * be set above and then libpng will keep the alpha channel for this 3760 * code to remove. 3761 */ 3762 if (format & PNG_FORMAT_FLAG_ALPHA) 3763 { 3764 /* Disable this if doing a local background, 3765 * TODO: remove this when local background is no longer required. 3766 */ 3767 if (do_local_background != 2) 3768 png_set_swap_alpha(png_ptr); 3769 } 3770 3771 else 3772 format &= ~PNG_FORMAT_FLAG_AFIRST; 3773 3774 change &= ~PNG_FORMAT_FLAG_AFIRST; 3775 } 3776# endif 3777 3778 /* If the *output* is 16-bit then we need to check for a byte-swap on this 3779 * architecture. 3780 */ 3781 if (linear) 3782 { 3783 PNG_CONST png_uint_16 le = 0x0001; 3784 3785 if (*(png_const_bytep)&le) 3786 png_set_swap(png_ptr); 3787 } 3788 3789 /* If change is not now 0 some transformation is missing - error out. */ 3790 if (change) 3791 png_error(png_ptr, "png_read_image: unsupported transformation"); 3792 } 3793 3794 PNG_SKIP_CHUNKS(png_ptr); 3795 3796 /* Update the 'info' structure and make sure the result is as required; first 3797 * make sure to turn on the interlace handling if it will be required 3798 * (because it can't be turned on *after* the call to png_read_update_info!) 3799 * 3800 * TODO: remove the do_local_background fixup below. 3801 */ 3802 if (!do_local_compose && do_local_background != 2) 3803 passes = png_set_interlace_handling(png_ptr); 3804 3805 png_read_update_info(png_ptr, info_ptr); 3806 3807 { 3808 png_uint_32 info_format = 0; 3809 3810 if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) 3811 info_format |= PNG_FORMAT_FLAG_COLOR; 3812 3813 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) 3814 { 3815 /* do_local_compose removes this channel below. */ 3816 if (!do_local_compose) 3817 { 3818 /* do_local_background does the same if required. */ 3819 if (do_local_background != 2 || 3820 (format & PNG_FORMAT_FLAG_ALPHA) != 0) 3821 info_format |= PNG_FORMAT_FLAG_ALPHA; 3822 } 3823 } 3824 3825 else if (do_local_compose) /* internal error */ 3826 png_error(png_ptr, "png_image_read: alpha channel lost"); 3827 3828 if (info_ptr->bit_depth == 16) 3829 info_format |= PNG_FORMAT_FLAG_LINEAR; 3830 3831# ifdef PNG_FORMAT_BGR_SUPPORTED 3832 if (png_ptr->transformations & PNG_BGR) 3833 info_format |= PNG_FORMAT_FLAG_BGR; 3834# endif 3835 3836# ifdef PNG_FORMAT_AFIRST_SUPPORTED 3837 if (do_local_background == 2) 3838 { 3839 if (format & PNG_FORMAT_FLAG_AFIRST) 3840 info_format |= PNG_FORMAT_FLAG_AFIRST; 3841 } 3842 3843 if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || 3844 ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && 3845 (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) 3846 { 3847 if (do_local_background == 2) 3848 png_error(png_ptr, "unexpected alpha swap transformation"); 3849 3850 info_format |= PNG_FORMAT_FLAG_AFIRST; 3851 } 3852# endif 3853 3854 /* This is actually an internal error. */ 3855 if (info_format != format) 3856 png_error(png_ptr, "png_read_image: invalid transformations"); 3857 } 3858 3859 /* Now read the rows. If do_local_compose is set then it is necessary to use 3860 * a local row buffer. The output will be GA, RGBA or BGRA and must be 3861 * converted to G, RGB or BGR as appropriate. The 'local_row' member of the 3862 * display acts as a flag. 3863 */ 3864 { 3865 png_voidp first_row = display->buffer; 3866 ptrdiff_t row_bytes = display->row_stride; 3867 3868 if (linear) 3869 row_bytes *= 2; 3870 3871 /* The following expression is designed to work correctly whether it gives 3872 * a signed or an unsigned result. 3873 */ 3874 if (row_bytes < 0) 3875 { 3876 char *ptr = png_voidcast(char*, first_row); 3877 ptr += (image->height-1) * (-row_bytes); 3878 first_row = png_voidcast(png_voidp, ptr); 3879 } 3880 3881 display->first_row = first_row; 3882 display->row_bytes = row_bytes; 3883 } 3884 3885 if (do_local_compose) 3886 { 3887 int result; 3888 png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); 3889 3890 display->local_row = row; 3891 result = png_safe_execute(image, png_image_read_composite, display); 3892 display->local_row = NULL; 3893 png_free(png_ptr, row); 3894 3895 return result; 3896 } 3897 3898 else if (do_local_background == 2) 3899 { 3900 int result; 3901 png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); 3902 3903 display->local_row = row; 3904 result = png_safe_execute(image, png_image_read_background, display); 3905 display->local_row = NULL; 3906 png_free(png_ptr, row); 3907 3908 return result; 3909 } 3910 3911 else 3912 { 3913 png_alloc_size_t row_bytes = display->row_bytes; 3914 3915 while (--passes >= 0) 3916 { 3917 png_uint_32 y = image->height; 3918 png_bytep row = png_voidcast(png_bytep, display->first_row); 3919 3920 while (y-- > 0) 3921 { 3922 png_read_row(png_ptr, row, NULL); 3923 row += row_bytes; 3924 } 3925 } 3926 3927 return 1; 3928 } 3929} 3930 3931int PNGAPI 3932png_image_finish_read(png_imagep image, png_const_colorp background, 3933 void *buffer, png_int_32 row_stride, void *colormap) 3934{ 3935 if (image != NULL && image->version == PNG_IMAGE_VERSION) 3936 { 3937 png_uint_32 check; 3938 3939 if (row_stride == 0) 3940 row_stride = PNG_IMAGE_ROW_STRIDE(*image); 3941 3942 if (row_stride < 0) 3943 check = -row_stride; 3944 3945 else 3946 check = row_stride; 3947 3948 if (image->opaque != NULL && buffer != NULL && 3949 check >= PNG_IMAGE_ROW_STRIDE(*image)) 3950 { 3951 if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || 3952 (image->colormap_entries > 0 && colormap != NULL)) 3953 { 3954 int result; 3955 png_image_read_control display; 3956 3957 memset(&display, 0, (sizeof display)); 3958 display.image = image; 3959 display.buffer = buffer; 3960 display.row_stride = row_stride; 3961 display.colormap = colormap; 3962 display.background = background; 3963 display.local_row = NULL; 3964 3965 /* Choose the correct 'end' routine; for the color-map case all the 3966 * setup has already been done. 3967 */ 3968 if (image->format & PNG_FORMAT_FLAG_COLORMAP) 3969 result = 3970 png_safe_execute(image, png_image_read_colormap, &display) && 3971 png_safe_execute(image, png_image_read_colormapped, &display); 3972 3973 else 3974 result = 3975 png_safe_execute(image, png_image_read_direct, &display); 3976 3977 png_image_free(image); 3978 return result; 3979 } 3980 3981 else 3982 return png_image_error(image, 3983 "png_image_finish_read[color-map]: no color-map"); 3984 } 3985 3986 else 3987 return png_image_error(image, 3988 "png_image_finish_read: invalid argument"); 3989 } 3990 3991 else if (image != NULL) 3992 return png_image_error(image, 3993 "png_image_finish_read: damaged PNG_IMAGE_VERSION"); 3994 3995 return 0; 3996} 3997 3998#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */ 3999#endif /* PNG_READ_SUPPORTED */ 4000