/src/FreeImage/Source/LibPNG/pngrtran.c
C | 5023 lines | 3620 code | 639 blank | 764 comment | 777 complexity | ce6789b8366bc3c5861c3acda0174527 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1 2/* pngrtran.c - transforms the data in a row for PNG readers 3 * 4 * Last changed in libpng 1.5.7 [December 15, 2011] 5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 8 * 9 * This code is released under the libpng license. 10 * For conditions of distribution and use, see the disclaimer 11 * and license in png.h 12 * 13 * This file contains functions optionally called by an application 14 * in order to tell libpng how to handle data when reading a PNG. 15 * Transformations that are used in both reading and writing are 16 * in pngtrans.c. 17 */ 18 19#include "pngpriv.h" 20 21#ifdef PNG_READ_SUPPORTED 22 23/* Set the action on getting a CRC error for an ancillary or critical chunk. */ 24void PNGAPI 25png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) 26{ 27 png_debug(1, "in png_set_crc_action"); 28 29 if (png_ptr == NULL) 30 return; 31 32 /* Tell libpng how we react to CRC errors in critical chunks */ 33 switch (crit_action) 34 { 35 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ 36 break; 37 38 case PNG_CRC_WARN_USE: /* Warn/use data */ 39 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 40 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; 41 break; 42 43 case PNG_CRC_QUIET_USE: /* Quiet/use data */ 44 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 45 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | 46 PNG_FLAG_CRC_CRITICAL_IGNORE; 47 break; 48 49 case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ 50 png_warning(png_ptr, 51 "Can't discard critical data on CRC error"); 52 case PNG_CRC_ERROR_QUIT: /* Error/quit */ 53 54 case PNG_CRC_DEFAULT: 55 default: 56 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; 57 break; 58 } 59 60 /* Tell libpng how we react to CRC errors in ancillary chunks */ 61 switch (ancil_action) 62 { 63 case PNG_CRC_NO_CHANGE: /* Leave setting as is */ 64 break; 65 66 case PNG_CRC_WARN_USE: /* Warn/use data */ 67 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 68 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; 69 break; 70 71 case PNG_CRC_QUIET_USE: /* Quiet/use data */ 72 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 73 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | 74 PNG_FLAG_CRC_ANCILLARY_NOWARN; 75 break; 76 77 case PNG_CRC_ERROR_QUIT: /* Error/quit */ 78 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 79 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; 80 break; 81 82 case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ 83 84 case PNG_CRC_DEFAULT: 85 default: 86 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; 87 break; 88 } 89} 90 91#ifdef PNG_READ_BACKGROUND_SUPPORTED 92/* Handle alpha and tRNS via a background color */ 93void PNGFAPI 94png_set_background_fixed(png_structp png_ptr, 95 png_const_color_16p background_color, int background_gamma_code, 96 int need_expand, png_fixed_point background_gamma) 97{ 98 png_debug(1, "in png_set_background_fixed"); 99 100 if (png_ptr == NULL) 101 return; 102 103 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) 104 { 105 png_warning(png_ptr, "Application must supply a known background gamma"); 106 return; 107 } 108 109 png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; 110 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 111 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 112 113 png_memcpy(&(png_ptr->background), background_color, 114 png_sizeof(png_color_16)); 115 png_ptr->background_gamma = background_gamma; 116 png_ptr->background_gamma_type = (png_byte)(background_gamma_code); 117 if (need_expand) 118 png_ptr->transformations |= PNG_BACKGROUND_EXPAND; 119 else 120 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 121} 122 123# ifdef PNG_FLOATING_POINT_SUPPORTED 124void PNGAPI 125png_set_background(png_structp png_ptr, 126 png_const_color_16p background_color, int background_gamma_code, 127 int need_expand, double background_gamma) 128{ 129 png_set_background_fixed(png_ptr, background_color, background_gamma_code, 130 need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); 131} 132# endif /* FLOATING_POINT */ 133#endif /* READ_BACKGROUND */ 134 135/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the 136 * one that pngrtran does first (scale) happens. This is necessary to allow the 137 * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. 138 */ 139#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 140void PNGAPI 141png_set_scale_16(png_structp png_ptr) 142{ 143 png_debug(1, "in png_set_scale_16"); 144 145 if (png_ptr == NULL) 146 return; 147 148 png_ptr->transformations |= PNG_SCALE_16_TO_8; 149} 150#endif 151 152#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 153/* Chop 16-bit depth files to 8-bit depth */ 154void PNGAPI 155png_set_strip_16(png_structp png_ptr) 156{ 157 png_debug(1, "in png_set_strip_16"); 158 159 if (png_ptr == NULL) 160 return; 161 162 png_ptr->transformations |= PNG_16_TO_8; 163} 164#endif 165 166#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 167void PNGAPI 168png_set_strip_alpha(png_structp png_ptr) 169{ 170 png_debug(1, "in png_set_strip_alpha"); 171 172 if (png_ptr == NULL) 173 return; 174 175 png_ptr->transformations |= PNG_STRIP_ALPHA; 176} 177#endif 178 179#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) 180static png_fixed_point 181translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, 182 int is_screen) 183{ 184 /* Check for flag values. The main reason for having the old Mac value as a 185 * flag is that it is pretty near impossible to work out what the correct 186 * value is from Apple documentation - a working Mac system is needed to 187 * discover the value! 188 */ 189 if (output_gamma == PNG_DEFAULT_sRGB || 190 output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) 191 { 192 /* If there is no sRGB support this just sets the gamma to the standard 193 * sRGB value. (This is a side effect of using this function!) 194 */ 195# ifdef PNG_READ_sRGB_SUPPORTED 196 png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; 197# endif 198 if (is_screen) 199 output_gamma = PNG_GAMMA_sRGB; 200 else 201 output_gamma = PNG_GAMMA_sRGB_INVERSE; 202 } 203 204 else if (output_gamma == PNG_GAMMA_MAC_18 || 205 output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) 206 { 207 if (is_screen) 208 output_gamma = PNG_GAMMA_MAC_OLD; 209 else 210 output_gamma = PNG_GAMMA_MAC_INVERSE; 211 } 212 213 return output_gamma; 214} 215 216# ifdef PNG_FLOATING_POINT_SUPPORTED 217static png_fixed_point 218convert_gamma_value(png_structp png_ptr, double output_gamma) 219{ 220 /* The following silently ignores cases where fixed point (times 100,000) 221 * gamma values are passed to the floating point API. This is safe and it 222 * means the fixed point constants work just fine with the floating point 223 * API. The alternative would just lead to undetected errors and spurious 224 * bug reports. Negative values fail inside the _fixed API unless they 225 * correspond to the flag values. 226 */ 227 if (output_gamma > 0 && output_gamma < 128) 228 output_gamma *= PNG_FP_1; 229 230 /* This preserves -1 and -2 exactly: */ 231 output_gamma = floor(output_gamma + .5); 232 233 if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) 234 png_fixed_error(png_ptr, "gamma value"); 235 236 return (png_fixed_point)output_gamma; 237} 238# endif 239#endif /* READ_ALPHA_MODE || READ_GAMMA */ 240 241#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 242void PNGFAPI 243png_set_alpha_mode_fixed(png_structp png_ptr, int mode, 244 png_fixed_point output_gamma) 245{ 246 int compose = 0; 247 png_fixed_point file_gamma; 248 249 png_debug(1, "in png_set_alpha_mode"); 250 251 if (png_ptr == NULL) 252 return; 253 254 output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); 255 256 /* Validate the value to ensure it is in a reasonable range. The value 257 * is expected to be 1 or greater, but this range test allows for some 258 * viewing correction values. The intent is to weed out users of this API 259 * who use the inverse of the gamma value accidentally! Since some of these 260 * values are reasonable this may have to be changed. 261 */ 262 if (output_gamma < 70000 || output_gamma > 300000) 263 png_error(png_ptr, "output gamma out of expected range"); 264 265 /* The default file gamma is the inverse of the output gamma; the output 266 * gamma may be changed below so get the file value first: 267 */ 268 file_gamma = png_reciprocal(output_gamma); 269 270 /* There are really 8 possibilities here, composed of any combination 271 * of: 272 * 273 * premultiply the color channels 274 * do not encode non-opaque pixels 275 * encode the alpha as well as the color channels 276 * 277 * The differences disappear if the input/output ('screen') gamma is 1.0, 278 * because then the encoding is a no-op and there is only the choice of 279 * premultiplying the color channels or not. 280 * 281 * png_set_alpha_mode and png_set_background interact because both use 282 * png_compose to do the work. Calling both is only useful when 283 * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along 284 * with a default gamma value. Otherwise PNG_COMPOSE must not be set. 285 */ 286 switch (mode) 287 { 288 case PNG_ALPHA_PNG: /* default: png standard */ 289 /* No compose, but it may be set by png_set_background! */ 290 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 291 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 292 break; 293 294 case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ 295 compose = 1; 296 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 297 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 298 /* The output is linear: */ 299 output_gamma = PNG_FP_1; 300 break; 301 302 case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ 303 compose = 1; 304 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 305 png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; 306 /* output_gamma records the encoding of opaque pixels! */ 307 break; 308 309 case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ 310 compose = 1; 311 png_ptr->transformations |= PNG_ENCODE_ALPHA; 312 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 313 break; 314 315 default: 316 png_error(png_ptr, "invalid alpha mode"); 317 } 318 319 /* Only set the default gamma if the file gamma has not been set (this has 320 * the side effect that the gamma in a second call to png_set_alpha_mode will 321 * be ignored.) 322 */ 323 if (png_ptr->gamma == 0) 324 png_ptr->gamma = file_gamma; 325 326 /* But always set the output gamma: */ 327 png_ptr->screen_gamma = output_gamma; 328 329 /* Finally, if pre-multiplying, set the background fields to achieve the 330 * desired result. 331 */ 332 if (compose) 333 { 334 /* And obtain alpha pre-multiplication by composing on black: */ 335 png_memset(&png_ptr->background, 0, sizeof png_ptr->background); 336 png_ptr->background_gamma = png_ptr->gamma; /* just in case */ 337 png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; 338 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 339 340 if (png_ptr->transformations & PNG_COMPOSE) 341 png_error(png_ptr, 342 "conflicting calls to set alpha mode and background"); 343 344 png_ptr->transformations |= PNG_COMPOSE; 345 } 346 347 /* New API, make sure apps call the correct initializers: */ 348 png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; 349} 350 351# ifdef PNG_FLOATING_POINT_SUPPORTED 352void PNGAPI 353png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) 354{ 355 png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, 356 output_gamma)); 357} 358# endif 359#endif 360 361#ifdef PNG_READ_QUANTIZE_SUPPORTED 362/* Dither file to 8-bit. Supply a palette, the current number 363 * of elements in the palette, the maximum number of elements 364 * allowed, and a histogram if possible. If the current number 365 * of colors is greater then the maximum number, the palette will be 366 * modified to fit in the maximum number. "full_quantize" indicates 367 * whether we need a quantizing cube set up for RGB images, or if we 368 * simply are reducing the number of colors in a paletted image. 369 */ 370 371typedef struct png_dsort_struct 372{ 373 struct png_dsort_struct FAR * next; 374 png_byte left; 375 png_byte right; 376} png_dsort; 377typedef png_dsort FAR * png_dsortp; 378typedef png_dsort FAR * FAR * png_dsortpp; 379 380void PNGAPI 381png_set_quantize(png_structp png_ptr, png_colorp palette, 382 int num_palette, int maximum_colors, png_const_uint_16p histogram, 383 int full_quantize) 384{ 385 png_debug(1, "in png_set_quantize"); 386 387 if (png_ptr == NULL) 388 return; 389 390 png_ptr->transformations |= PNG_QUANTIZE; 391 392 if (!full_quantize) 393 { 394 int i; 395 396 png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, 397 (png_uint_32)(num_palette * png_sizeof(png_byte))); 398 for (i = 0; i < num_palette; i++) 399 png_ptr->quantize_index[i] = (png_byte)i; 400 } 401 402 if (num_palette > maximum_colors) 403 { 404 if (histogram != NULL) 405 { 406 /* This is easy enough, just throw out the least used colors. 407 * Perhaps not the best solution, but good enough. 408 */ 409 410 int i; 411 412 /* Initialize an array to sort colors */ 413 png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, 414 (png_uint_32)(num_palette * png_sizeof(png_byte))); 415 416 /* Initialize the quantize_sort array */ 417 for (i = 0; i < num_palette; i++) 418 png_ptr->quantize_sort[i] = (png_byte)i; 419 420 /* Find the least used palette entries by starting a 421 * bubble sort, and running it until we have sorted 422 * out enough colors. Note that we don't care about 423 * sorting all the colors, just finding which are 424 * least used. 425 */ 426 427 for (i = num_palette - 1; i >= maximum_colors; i--) 428 { 429 int done; /* To stop early if the list is pre-sorted */ 430 int j; 431 432 done = 1; 433 for (j = 0; j < i; j++) 434 { 435 if (histogram[png_ptr->quantize_sort[j]] 436 < histogram[png_ptr->quantize_sort[j + 1]]) 437 { 438 png_byte t; 439 440 t = png_ptr->quantize_sort[j]; 441 png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; 442 png_ptr->quantize_sort[j + 1] = t; 443 done = 0; 444 } 445 } 446 447 if (done) 448 break; 449 } 450 451 /* Swap the palette around, and set up a table, if necessary */ 452 if (full_quantize) 453 { 454 int j = num_palette; 455 456 /* Put all the useful colors within the max, but don't 457 * move the others. 458 */ 459 for (i = 0; i < maximum_colors; i++) 460 { 461 if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 462 { 463 do 464 j--; 465 while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 466 467 palette[i] = palette[j]; 468 } 469 } 470 } 471 else 472 { 473 int j = num_palette; 474 475 /* Move all the used colors inside the max limit, and 476 * develop a translation table. 477 */ 478 for (i = 0; i < maximum_colors; i++) 479 { 480 /* Only move the colors we need to */ 481 if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 482 { 483 png_color tmp_color; 484 485 do 486 j--; 487 while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 488 489 tmp_color = palette[j]; 490 palette[j] = palette[i]; 491 palette[i] = tmp_color; 492 /* Indicate where the color went */ 493 png_ptr->quantize_index[j] = (png_byte)i; 494 png_ptr->quantize_index[i] = (png_byte)j; 495 } 496 } 497 498 /* Find closest color for those colors we are not using */ 499 for (i = 0; i < num_palette; i++) 500 { 501 if ((int)png_ptr->quantize_index[i] >= maximum_colors) 502 { 503 int min_d, k, min_k, d_index; 504 505 /* Find the closest color to one we threw out */ 506 d_index = png_ptr->quantize_index[i]; 507 min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); 508 for (k = 1, min_k = 0; k < maximum_colors; k++) 509 { 510 int d; 511 512 d = PNG_COLOR_DIST(palette[d_index], palette[k]); 513 514 if (d < min_d) 515 { 516 min_d = d; 517 min_k = k; 518 } 519 } 520 /* Point to closest color */ 521 png_ptr->quantize_index[i] = (png_byte)min_k; 522 } 523 } 524 } 525 png_free(png_ptr, png_ptr->quantize_sort); 526 png_ptr->quantize_sort = NULL; 527 } 528 else 529 { 530 /* This is much harder to do simply (and quickly). Perhaps 531 * we need to go through a median cut routine, but those 532 * don't always behave themselves with only a few colors 533 * as input. So we will just find the closest two colors, 534 * and throw out one of them (chosen somewhat randomly). 535 * [We don't understand this at all, so if someone wants to 536 * work on improving it, be our guest - AED, GRP] 537 */ 538 int i; 539 int max_d; 540 int num_new_palette; 541 png_dsortp t; 542 png_dsortpp hash; 543 544 t = NULL; 545 546 /* Initialize palette index arrays */ 547 png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, 548 (png_uint_32)(num_palette * png_sizeof(png_byte))); 549 png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, 550 (png_uint_32)(num_palette * png_sizeof(png_byte))); 551 552 /* Initialize the sort array */ 553 for (i = 0; i < num_palette; i++) 554 { 555 png_ptr->index_to_palette[i] = (png_byte)i; 556 png_ptr->palette_to_index[i] = (png_byte)i; 557 } 558 559 hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * 560 png_sizeof(png_dsortp))); 561 562 num_new_palette = num_palette; 563 564 /* Initial wild guess at how far apart the farthest pixel 565 * pair we will be eliminating will be. Larger 566 * numbers mean more areas will be allocated, Smaller 567 * numbers run the risk of not saving enough data, and 568 * having to do this all over again. 569 * 570 * I have not done extensive checking on this number. 571 */ 572 max_d = 96; 573 574 while (num_new_palette > maximum_colors) 575 { 576 for (i = 0; i < num_new_palette - 1; i++) 577 { 578 int j; 579 580 for (j = i + 1; j < num_new_palette; j++) 581 { 582 int d; 583 584 d = PNG_COLOR_DIST(palette[i], palette[j]); 585 586 if (d <= max_d) 587 { 588 589 t = (png_dsortp)png_malloc_warn(png_ptr, 590 (png_uint_32)(png_sizeof(png_dsort))); 591 592 if (t == NULL) 593 break; 594 595 t->next = hash[d]; 596 t->left = (png_byte)i; 597 t->right = (png_byte)j; 598 hash[d] = t; 599 } 600 } 601 if (t == NULL) 602 break; 603 } 604 605 if (t != NULL) 606 for (i = 0; i <= max_d; i++) 607 { 608 if (hash[i] != NULL) 609 { 610 png_dsortp p; 611 612 for (p = hash[i]; p; p = p->next) 613 { 614 if ((int)png_ptr->index_to_palette[p->left] 615 < num_new_palette && 616 (int)png_ptr->index_to_palette[p->right] 617 < num_new_palette) 618 { 619 int j, next_j; 620 621 if (num_new_palette & 0x01) 622 { 623 j = p->left; 624 next_j = p->right; 625 } 626 else 627 { 628 j = p->right; 629 next_j = p->left; 630 } 631 632 num_new_palette--; 633 palette[png_ptr->index_to_palette[j]] 634 = palette[num_new_palette]; 635 if (!full_quantize) 636 { 637 int k; 638 639 for (k = 0; k < num_palette; k++) 640 { 641 if (png_ptr->quantize_index[k] == 642 png_ptr->index_to_palette[j]) 643 png_ptr->quantize_index[k] = 644 png_ptr->index_to_palette[next_j]; 645 646 if ((int)png_ptr->quantize_index[k] == 647 num_new_palette) 648 png_ptr->quantize_index[k] = 649 png_ptr->index_to_palette[j]; 650 } 651 } 652 653 png_ptr->index_to_palette[png_ptr->palette_to_index 654 [num_new_palette]] = png_ptr->index_to_palette[j]; 655 656 png_ptr->palette_to_index[png_ptr->index_to_palette[j]] 657 = png_ptr->palette_to_index[num_new_palette]; 658 659 png_ptr->index_to_palette[j] = 660 (png_byte)num_new_palette; 661 662 png_ptr->palette_to_index[num_new_palette] = 663 (png_byte)j; 664 } 665 if (num_new_palette <= maximum_colors) 666 break; 667 } 668 if (num_new_palette <= maximum_colors) 669 break; 670 } 671 } 672 673 for (i = 0; i < 769; i++) 674 { 675 if (hash[i] != NULL) 676 { 677 png_dsortp p = hash[i]; 678 while (p) 679 { 680 t = p->next; 681 png_free(png_ptr, p); 682 p = t; 683 } 684 } 685 hash[i] = 0; 686 } 687 max_d += 96; 688 } 689 png_free(png_ptr, hash); 690 png_free(png_ptr, png_ptr->palette_to_index); 691 png_free(png_ptr, png_ptr->index_to_palette); 692 png_ptr->palette_to_index = NULL; 693 png_ptr->index_to_palette = NULL; 694 } 695 num_palette = maximum_colors; 696 } 697 if (png_ptr->palette == NULL) 698 { 699 png_ptr->palette = palette; 700 } 701 png_ptr->num_palette = (png_uint_16)num_palette; 702 703 if (full_quantize) 704 { 705 int i; 706 png_bytep distance; 707 int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + 708 PNG_QUANTIZE_BLUE_BITS; 709 int num_red = (1 << PNG_QUANTIZE_RED_BITS); 710 int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); 711 int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); 712 png_size_t num_entries = ((png_size_t)1 << total_bits); 713 714 png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, 715 (png_uint_32)(num_entries * png_sizeof(png_byte))); 716 717 distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * 718 png_sizeof(png_byte))); 719 720 png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); 721 722 for (i = 0; i < num_palette; i++) 723 { 724 int ir, ig, ib; 725 int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); 726 int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); 727 int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); 728 729 for (ir = 0; ir < num_red; ir++) 730 { 731 /* int dr = abs(ir - r); */ 732 int dr = ((ir > r) ? ir - r : r - ir); 733 int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + 734 PNG_QUANTIZE_GREEN_BITS)); 735 736 for (ig = 0; ig < num_green; ig++) 737 { 738 /* int dg = abs(ig - g); */ 739 int dg = ((ig > g) ? ig - g : g - ig); 740 int dt = dr + dg; 741 int dm = ((dr > dg) ? dr : dg); 742 int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); 743 744 for (ib = 0; ib < num_blue; ib++) 745 { 746 int d_index = index_g | ib; 747 /* int db = abs(ib - b); */ 748 int db = ((ib > b) ? ib - b : b - ib); 749 int dmax = ((dm > db) ? dm : db); 750 int d = dmax + dt + db; 751 752 if (d < (int)distance[d_index]) 753 { 754 distance[d_index] = (png_byte)d; 755 png_ptr->palette_lookup[d_index] = (png_byte)i; 756 } 757 } 758 } 759 } 760 } 761 762 png_free(png_ptr, distance); 763 } 764} 765#endif /* PNG_READ_QUANTIZE_SUPPORTED */ 766 767#ifdef PNG_READ_GAMMA_SUPPORTED 768void PNGFAPI 769png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, 770 png_fixed_point file_gamma) 771{ 772 png_debug(1, "in png_set_gamma_fixed"); 773 774 if (png_ptr == NULL) 775 return; 776 777 /* New in libpng-1.5.4 - reserve particular negative values as flags. */ 778 scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); 779 file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); 780 781#if PNG_LIBPNG_VER >= 10600 782 /* Checking the gamma values for being >0 was added in 1.5.4 along with the 783 * premultiplied alpha support; this actually hides an undocumented feature 784 * of the previous implementation which allowed gamma processing to be 785 * disabled in background handling. There is no evidence (so far) that this 786 * was being used; however, png_set_background itself accepted and must still 787 * accept '0' for the gamma value it takes, because it isn't always used. 788 * 789 * Since this is an API change (albeit a very minor one that removes an 790 * undocumented API feature) it will not be made until libpng-1.6.0. 791 */ 792 if (file_gamma <= 0) 793 png_error(png_ptr, "invalid file gamma in png_set_gamma"); 794 795 if (scrn_gamma <= 0) 796 png_error(png_ptr, "invalid screen gamma in png_set_gamma"); 797#endif 798 799 /* Set the gamma values unconditionally - this overrides the value in the PNG 800 * file if a gAMA chunk was present. png_set_alpha_mode provides a 801 * different, easier, way to default the file gamma. 802 */ 803 png_ptr->gamma = file_gamma; 804 png_ptr->screen_gamma = scrn_gamma; 805} 806 807# ifdef PNG_FLOATING_POINT_SUPPORTED 808void PNGAPI 809png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) 810{ 811 png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), 812 convert_gamma_value(png_ptr, file_gamma)); 813} 814# endif /* FLOATING_POINT_SUPPORTED */ 815#endif /* READ_GAMMA */ 816 817#ifdef PNG_READ_EXPAND_SUPPORTED 818/* Expand paletted images to RGB, expand grayscale images of 819 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks 820 * to alpha channels. 821 */ 822void PNGAPI 823png_set_expand(png_structp png_ptr) 824{ 825 png_debug(1, "in png_set_expand"); 826 827 if (png_ptr == NULL) 828 return; 829 830 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 831 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 832} 833 834/* GRR 19990627: the following three functions currently are identical 835 * to png_set_expand(). However, it is entirely reasonable that someone 836 * might wish to expand an indexed image to RGB but *not* expand a single, 837 * fully transparent palette entry to a full alpha channel--perhaps instead 838 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace 839 * the transparent color with a particular RGB value, or drop tRNS entirely. 840 * IOW, a future version of the library may make the transformations flag 841 * a bit more fine-grained, with separate bits for each of these three 842 * functions. 843 * 844 * More to the point, these functions make it obvious what libpng will be 845 * doing, whereas "expand" can (and does) mean any number of things. 846 * 847 * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified 848 * to expand only the sample depth but not to expand the tRNS to alpha 849 * and its name was changed to png_set_expand_gray_1_2_4_to_8(). 850 */ 851 852/* Expand paletted images to RGB. */ 853void PNGAPI 854png_set_palette_to_rgb(png_structp png_ptr) 855{ 856 png_debug(1, "in png_set_palette_to_rgb"); 857 858 if (png_ptr == NULL) 859 return; 860 861 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 862 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 863} 864 865/* Expand grayscale images of less than 8-bit depth to 8 bits. */ 866void PNGAPI 867png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) 868{ 869 png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); 870 871 if (png_ptr == NULL) 872 return; 873 874 png_ptr->transformations |= PNG_EXPAND; 875 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 876} 877 878 879 880/* Expand tRNS chunks to alpha channels. */ 881void PNGAPI 882png_set_tRNS_to_alpha(png_structp png_ptr) 883{ 884 png_debug(1, "in png_set_tRNS_to_alpha"); 885 886 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 887 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 888} 889#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ 890 891#ifdef PNG_READ_EXPAND_16_SUPPORTED 892/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise 893 * it may not work correctly.) 894 */ 895void PNGAPI 896png_set_expand_16(png_structp png_ptr) 897{ 898 png_debug(1, "in png_set_expand_16"); 899 900 if (png_ptr == NULL) 901 return; 902 903 png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); 904 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 905 906 /* New API, make sure apps call the correct initializers: */ 907 png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; 908} 909#endif 910 911#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 912void PNGAPI 913png_set_gray_to_rgb(png_structp png_ptr) 914{ 915 png_debug(1, "in png_set_gray_to_rgb"); 916 917 if (png_ptr != NULL) 918 { 919 /* Because rgb must be 8 bits or more: */ 920 png_set_expand_gray_1_2_4_to_8(png_ptr); 921 png_ptr->transformations |= PNG_GRAY_TO_RGB; 922 png_ptr->flags &= ~PNG_FLAG_ROW_INIT; 923 } 924} 925#endif 926 927#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 928void PNGFAPI 929png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, 930 png_fixed_point red, png_fixed_point green) 931{ 932 png_debug(1, "in png_set_rgb_to_gray"); 933 934 if (png_ptr == NULL) 935 return; 936 937 switch(error_action) 938 { 939 case PNG_ERROR_ACTION_NONE: 940 png_ptr->transformations |= PNG_RGB_TO_GRAY; 941 break; 942 943 case PNG_ERROR_ACTION_WARN: 944 png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; 945 break; 946 947 case PNG_ERROR_ACTION_ERROR: 948 png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; 949 break; 950 951 default: 952 png_error(png_ptr, "invalid error action to rgb_to_gray"); 953 break; 954 } 955 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 956#ifdef PNG_READ_EXPAND_SUPPORTED 957 png_ptr->transformations |= PNG_EXPAND; 958#else 959 { 960 png_warning(png_ptr, 961 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); 962 963 png_ptr->transformations &= ~PNG_RGB_TO_GRAY; 964 } 965#endif 966 { 967 if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) 968 { 969 png_uint_16 red_int, green_int; 970 971 /* NOTE: this calculation does not round, but this behavior is retained 972 * for consistency, the inaccuracy is very small. The code here always 973 * overwrites the coefficients, regardless of whether they have been 974 * defaulted or set already. 975 */ 976 red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); 977 green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); 978 979 png_ptr->rgb_to_gray_red_coeff = red_int; 980 png_ptr->rgb_to_gray_green_coeff = green_int; 981 png_ptr->rgb_to_gray_coefficients_set = 1; 982 } 983 984 else 985 { 986 if (red >= 0 && green >= 0) 987 png_warning(png_ptr, 988 "ignoring out of range rgb_to_gray coefficients"); 989 990 /* Use the defaults, from the cHRM chunk if set, else the historical 991 * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See 992 * png_do_rgb_to_gray for more discussion of the values. In this case 993 * the coefficients are not marked as 'set' and are not overwritten if 994 * something has already provided a default. 995 */ 996 if (png_ptr->rgb_to_gray_red_coeff == 0 && 997 png_ptr->rgb_to_gray_green_coeff == 0) 998 { 999 png_ptr->rgb_to_gray_red_coeff = 6968; 1000 png_ptr->rgb_to_gray_green_coeff = 23434; 1001 /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ 1002 } 1003 } 1004 } 1005} 1006 1007#ifdef PNG_FLOATING_POINT_SUPPORTED 1008/* Convert a RGB image to a grayscale of the same width. This allows us, 1009 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. 1010 */ 1011 1012void PNGAPI 1013png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, 1014 double green) 1015{ 1016 if (png_ptr == NULL) 1017 return; 1018 1019 png_set_rgb_to_gray_fixed(png_ptr, error_action, 1020 png_fixed(png_ptr, red, "rgb to gray red coefficient"), 1021 png_fixed(png_ptr, green, "rgb to gray green coefficient")); 1022} 1023#endif /* FLOATING POINT */ 1024 1025#endif 1026 1027#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ 1028 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) 1029void PNGAPI 1030png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr 1031 read_user_transform_fn) 1032{ 1033 png_debug(1, "in png_set_read_user_transform_fn"); 1034 1035 if (png_ptr == NULL) 1036 return; 1037 1038#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 1039 png_ptr->transformations |= PNG_USER_TRANSFORM; 1040 png_ptr->read_user_transform_fn = read_user_transform_fn; 1041#endif 1042} 1043#endif 1044 1045#ifdef PNG_READ_TRANSFORMS_SUPPORTED 1046#ifdef PNG_READ_GAMMA_SUPPORTED 1047/* In the case of gamma transformations only do transformations on images where 1048 * the [file] gamma and screen_gamma are not close reciprocals, otherwise it 1049 * slows things down slightly, and also needlessly introduces small errors. 1050 */ 1051static int /* PRIVATE */ 1052png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) 1053{ 1054 /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma 1055 * correction as a difference of the overall transform from 1.0 1056 * 1057 * We want to compare the threshold with s*f - 1, if we get 1058 * overflow here it is because of wacky gamma values so we 1059 * turn on processing anyway. 1060 */ 1061 png_fixed_point gtest; 1062 return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || 1063 png_gamma_significant(gtest); 1064} 1065#endif 1066 1067/* Initialize everything needed for the read. This includes modifying 1068 * the palette. 1069 */ 1070 1071/*For the moment 'png_init_palette_transformations' and 1072 * 'png_init_rgb_transformations' only do some flag canceling optimizations. 1073 * The intent is that these two routines should have palette or rgb operations 1074 * extracted from 'png_init_read_transformations'. 1075 */ 1076static void /* PRIVATE */ 1077png_init_palette_transformations(png_structp png_ptr) 1078{ 1079 /* Called to handle the (input) palette case. In png_do_read_transformations 1080 * the first step is to expand the palette if requested, so this code must 1081 * take care to only make changes that are invariant with respect to the 1082 * palette expansion, or only do them if there is no expansion. 1083 * 1084 * STRIP_ALPHA has already been handled in the caller (by setting num_trans 1085 * to 0.) 1086 */ 1087 int input_has_alpha = 0; 1088 int input_has_transparency = 0; 1089 1090 if (png_ptr->num_trans > 0) 1091 { 1092 int i; 1093 1094 /* Ignore if all the entries are opaque (unlikely!) */ 1095 for (i=0; i<png_ptr->num_trans; ++i) 1096 if (png_ptr->trans_alpha[i] == 255) 1097 continue; 1098 else if (png_ptr->trans_alpha[i] == 0) 1099 input_has_transparency = 1; 1100 else 1101 input_has_alpha = 1; 1102 } 1103 1104 /* If no alpha we can optimize. */ 1105 if (!input_has_alpha) 1106 { 1107 /* Any alpha means background and associative alpha processing is 1108 * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA 1109 * and ENCODE_ALPHA are irrelevant. 1110 */ 1111 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1112 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1113 1114 if (!input_has_transparency) 1115 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1116 } 1117 1118#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1119 /* png_set_background handling - deals with the complexity of whether the 1120 * background color is in the file format or the screen format in the case 1121 * where an 'expand' will happen. 1122 */ 1123 1124 /* The following code cannot be entered in the alpha pre-multiplication case 1125 * because PNG_BACKGROUND_EXPAND is cancelled below. 1126 */ 1127 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1128 (png_ptr->transformations & PNG_EXPAND)) 1129 { 1130 { 1131 png_ptr->background.red = 1132 png_ptr->palette[png_ptr->background.index].red; 1133 png_ptr->background.green = 1134 png_ptr->palette[png_ptr->background.index].green; 1135 png_ptr->background.blue = 1136 png_ptr->palette[png_ptr->background.index].blue; 1137 1138#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 1139 if (png_ptr->transformations & PNG_INVERT_ALPHA) 1140 { 1141 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 1142 { 1143 /* Invert the alpha channel (in tRNS) unless the pixels are 1144 * going to be expanded, in which case leave it for later 1145 */ 1146 int i, istop = png_ptr->num_trans; 1147 1148 for (i=0; i<istop; i++) 1149 png_ptr->trans_alpha[i] = (png_byte)(255 - 1150 png_ptr->trans_alpha[i]); 1151 } 1152 } 1153#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ 1154 } 1155 } /* background expand and (therefore) no alpha association. */ 1156#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1157} 1158 1159static void /* PRIVATE */ 1160png_init_rgb_transformations(png_structp png_ptr) 1161{ 1162 /* Added to libpng-1.5.4: check the color type to determine whether there 1163 * is any alpha or transparency in the image and simply cancel the 1164 * background and alpha mode stuff if there isn't. 1165 */ 1166 int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; 1167 int input_has_transparency = png_ptr->num_trans > 0; 1168 1169 /* If no alpha we can optimize. */ 1170 if (!input_has_alpha) 1171 { 1172 /* Any alpha means background and associative alpha processing is 1173 * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA 1174 * and ENCODE_ALPHA are irrelevant. 1175 */ 1176# ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1177 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1178 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1179# endif 1180 1181 if (!input_has_transparency) 1182 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1183 } 1184 1185#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1186 /* png_set_background handling - deals with the complexity of whether the 1187 * background color is in the file format or the screen format in the case 1188 * where an 'expand' will happen. 1189 */ 1190 1191 /* The following code cannot be entered in the alpha pre-multiplication case 1192 * because PNG_BACKGROUND_EXPAND is cancelled below. 1193 */ 1194 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1195 (png_ptr->transformations & PNG_EXPAND) && 1196 !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) 1197 /* i.e., GRAY or GRAY_ALPHA */ 1198 { 1199 { 1200 /* Expand background and tRNS chunks */ 1201 int gray = png_ptr->background.gray; 1202 int trans_gray = png_ptr->trans_color.gray; 1203 1204 switch (png_ptr->bit_depth) 1205 { 1206 case 1: 1207 gray *= 0xff; 1208 trans_gray *= 0xff; 1209 break; 1210 1211 case 2: 1212 gray *= 0x55; 1213 trans_gray *= 0x55; 1214 break; 1215 1216 case 4: 1217 gray *= 0x11; 1218 trans_gray *= 0x11; 1219 break; 1220 1221 default: 1222 1223 case 8: 1224 /* Already 8 bits, fall through */ 1225 1226 case 16: 1227 /* Already a full 16 bits */ 1228 break; 1229 } 1230 1231 png_ptr->background.red = png_ptr->background.green = 1232 png_ptr->background.blue = (png_uint_16)gray; 1233 1234 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 1235 { 1236 png_ptr->trans_color.red = png_ptr->trans_color.green = 1237 png_ptr->trans_color.blue = (png_uint_16)trans_gray; 1238 } 1239 } 1240 } /* background expand and (therefore) no alpha association. */ 1241#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1242} 1243 1244void /* PRIVATE */ 1245png_init_read_transformations(png_structp png_ptr) 1246{ 1247 png_debug(1, "in png_init_read_transformations"); 1248 1249 /* This internal function is called from png_read_start_row in pngrutil.c 1250 * and it is called before the 'rowbytes' calculation is done, so the code 1251 * in here can change or update the transformations flags. 1252 * 1253 * First do updates that do not depend on the details of the PNG image data 1254 * being processed. 1255 */ 1256 1257#ifdef PNG_READ_GAMMA_SUPPORTED 1258 /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds 1259 * png_set_alpha_mode and this is another source for a default file gamma so 1260 * the test needs to be performed later - here. In addition prior to 1.5.4 1261 * the tests were repeated for the PALETTE color type here - this is no 1262 * longer necessary (and doesn't seem to have been necessary before.) 1263 */ 1264 { 1265 /* The following temporary indicates if overall gamma correction is 1266 * required. 1267 */ 1268 int gamma_correction = 0; 1269 1270 if (png_ptr->gamma != 0) /* has been set */ 1271 { 1272 if (png_ptr->screen_gamma != 0) /* screen set too */ 1273 gamma_correction = png_gamma_threshold(png_ptr->gamma, 1274 png_ptr->screen_gamma); 1275 1276 else 1277 /* Assume the output matches the input; a long time default behavior 1278 * of libpng, although the standard has nothing to say about this. 1279 */ 1280 png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma); 1281 } 1282 1283 else if (png_ptr->screen_gamma != 0) 1284 /* The converse - assume the file matches the screen, note that this 1285 * perhaps undesireable default can (from 1.5.4) be changed by calling 1286 * png_set_alpha_mode (even if the alpha handling mode isn't required 1287 * or isn't changed from the default.) 1288 */ 1289 png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma); 1290 1291 else /* neither are set */ 1292 /* Just in case the following prevents any processing - file and screen 1293 * are both assumed to be linear and there is no way to introduce a 1294 * third gamma value other than png_set_background with 'UNIQUE', and, 1295 * prior to 1.5.4 1296 */ 1297 png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1; 1298 1299 /* Now turn the gamma transformation on or off as appropriate. Notice 1300 * that PNG_GAMMA just refers to the file->screen correction. Alpha 1301 * composition may independently cause gamma correction because it needs 1302 * linear data (e.g. if the file has a gAMA chunk but the screen gamma 1303 * hasn't been specified.) In any case this flag may get turned off in 1304 * the code immediately below if the transform can be handled outside the 1305 * row loop. 1306 */ 1307 if (gamma_correction) 1308 png_ptr->transformations |= PNG_GAMMA; 1309 1310 else 1311 png_ptr->transformations &= ~PNG_GAMMA; 1312 } 1313#endif 1314 1315 /* Certain transformations have the effect of preventing other 1316 * transformations that happen afterward in png_do_read_transformations, 1317 * resolve the interdependencies here. From the code of 1318 * png_do_read_transformations the order is: 1319 * 1320 * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) 1321 * 2) PNG_STRIP_ALPHA (if no compose) 1322 * 3) PNG_RGB_TO_GRAY 1323 * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY 1324 * 5) PNG_COMPOSE 1325 * 6) PNG_GAMMA 1326 * 7) PNG_STRIP_ALPHA (if compose) 1327 * 8) PNG_ENCODE_ALPHA 1328 * 9) PNG_SCALE_16_TO_8 1329 * 10) PNG_16_TO_8 1330 * 11) PNG_QUANTIZE (converts to palette) 1331 * 12) PNG_EXPAND_16 1332 * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY 1333 * 14) PNG_INVERT_MONO 1334 * 15) PNG_SHIFT 1335 * 16) PNG_PACK 1336 * 17) PNG_BGR 1337 * 18) PNG_PACKSWAP 1338 * 19) PNG_FILLER (includes PNG_ADD_ALPHA) 1339 * 20) PNG_INVERT_ALPHA 1340 * 21) PNG_SWAP_ALPHA 1341 * 22) PNG_SWAP_BYTES 1342 * 23) PNG_USER_TRANSFORM [must be last] 1343 */ 1344#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 1345 if ((png_ptr->transformations & PNG_STRIP_ALPHA) && 1346 !(png_ptr->transformations & PNG_COMPOSE)) 1347 { 1348 /* Stripping the alpha channel happens immediately after the 'expand' 1349 * transformations, before all other transformation, so it cancels out 1350 * the alpha handling. It has the side effect negating the effect of 1351 * PNG_EXPAND_tRNS too: 1352 */ 1353 png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | 1354 PNG_EXPAND_tRNS); 1355 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1356 1357 /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen 1358 * so transparency information would remain just so long as it wasn't 1359 * expanded. This produces unexpected API changes if the set of things 1360 * that do PNG_EXPAND_tRNS changes (perfectly possible given the 1361 * documentation - which says ask for what you want, accept what you 1362 * get.) This makes the behavior consistent from 1.5.4: 1363 */ 1364 png_ptr->num_trans = 0; 1365 } 1366#endif /* STRIP_ALPHA supported, no COMPOSE */ 1367 1368#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1369 /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA 1370 * settings will have no effect. 1371 */ 1372 if (!png_gamma_significant(png_ptr->screen_gamma)) 1373 { 1374 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1375 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1376 } 1377#endif 1378 1379#if defined(PNG_READ_EXPAND_SUPPORTED) && \ 1380 defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1381 defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) 1382 /* Detect gray background and attempt to enable optimization for 1383 * gray --> RGB case. 1384 * 1385 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or 1386 * RGB_ALPHA (in which case need_expand is superfluous anyway), the 1387 * background color might actually be gray yet not be flagged as such. 1388 * This is not a problem for the current code, which uses 1389 * PNG_BACKGROUND_IS_GRAY only to decide when to do the 1390 * png_do_gray_to_rgb() transformation. 1391 * 1392 * TODO: this code needs to be revised to avoid the complexity and 1393 * interdependencies. The color type of the background should be recorded in 1394 * png_set_background, along with the bit depth, then the code has a record 1395 * of exactly what color space the background is currently in. 1396 */ 1397 if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) 1398 { 1399 /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if 1400 * the file was grayscale the background value is gray. 1401 */ 1402 if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) 1403 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1404 } 1405 1406 else if (png_ptr->transformations & PNG_COMPOSE) 1407 { 1408 /* PNG_COMPOSE: png_set_background was called with need_expand false, 1409 * so the color is in the color space of the output or png_set_alpha_mode 1410 * was called and the color is black. Ignore RGB_TO_GRAY because that 1411 * happens before GRAY_TO_RGB. 1412 */ 1413 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 1414 { 1415 if (png_ptr->background.red == png_ptr->background.green && 1416 png_ptr->background.red == png_ptr->background.blue) 1417 { 1418 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1419 png_ptr->background.gray = png_ptr->background.red; 1420 } 1421 } 1422 } 1423#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ 1424 1425 /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations 1426 * can be performed directly on the palette, and some (such as rgb to gray) 1427 * can be optimized inside the palette. This is particularly true of the 1428 * composite (background and alpha) stuff, which can be pretty much all done 1429 * in the palette even if the result is expanded to RGB or gray afterward. 1430 * 1431 * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and 1432 * earlier and the palette stuff is actually handled on the first row. This 1433 * leads to the reported bug that the palette returned by png_get_PLTE is not 1434 * updated. 1435 */ 1436 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1437 png_init_palette_transformations(png_ptr); 1438 1439 else 1440 png_init_rgb_transformations(png_ptr); 1441 1442#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1443 defined(PNG_READ_EXPAND_16_SUPPORTED) 1444 if ((png_ptr->transformations & PNG_EXPAND_16) && 1445 (png_ptr->transformations & PNG_COMPOSE) && 1446 !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1447 png_ptr->bit_depth != 16) 1448 { 1449 /* TODO: fix this. Because the expand_16 operation is after the compose 1450 * handling the background color must be 8, not 16, bits deep, but the 1451 * application will supply a 16-bit value so reduce it here. 1452 * 1453 * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at 1454 *…
Large files files are truncated, but you can click here to view the full file