pngrtran.c revision b50c217251b086440efcdb273c22f86a06c80cba
1 2/* pngrtran.c - transforms the data in a row for PNG readers 3 * 4 * Last changed in libpng 1.6.2 [April 25, 2013] 5 * Copyright (c) 1998-2013 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_structrp 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_TRANSFORMS_SUPPORTED 92/* Is it OK to set a transformation now? Only if png_start_read_image or 93 * png_read_update_info have not been called. It is not necessary for the IHDR 94 * to have been read in all cases, the parameter allows for this check too. 95 */ 96static int 97png_rtran_ok(png_structrp png_ptr, int need_IHDR) 98{ 99 if (png_ptr != NULL) 100 { 101 if (png_ptr->flags & PNG_FLAG_ROW_INIT) 102 png_app_error(png_ptr, 103 "invalid after png_start_read_image or png_read_update_info"); 104 105 else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) 106 png_app_error(png_ptr, "invalid before the PNG header has been read"); 107 108 else 109 { 110 /* Turn on failure to initialize correctly for all transforms. */ 111 png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; 112 113 return 1; /* Ok */ 114 } 115 } 116 117 return 0; /* no png_error possible! */ 118} 119#endif 120 121#ifdef PNG_READ_BACKGROUND_SUPPORTED 122/* Handle alpha and tRNS via a background color */ 123void PNGFAPI 124png_set_background_fixed(png_structrp png_ptr, 125 png_const_color_16p background_color, int background_gamma_code, 126 int need_expand, png_fixed_point background_gamma) 127{ 128 png_debug(1, "in png_set_background_fixed"); 129 130 if (!png_rtran_ok(png_ptr, 0) || background_color == NULL) 131 return; 132 133 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) 134 { 135 png_warning(png_ptr, "Application must supply a known background gamma"); 136 return; 137 } 138 139 png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; 140 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 141 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 142 143 png_ptr->background = *background_color; 144 png_ptr->background_gamma = background_gamma; 145 png_ptr->background_gamma_type = (png_byte)(background_gamma_code); 146 if (need_expand) 147 png_ptr->transformations |= PNG_BACKGROUND_EXPAND; 148 else 149 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 150} 151 152# ifdef PNG_FLOATING_POINT_SUPPORTED 153void PNGAPI 154png_set_background(png_structrp png_ptr, 155 png_const_color_16p background_color, int background_gamma_code, 156 int need_expand, double background_gamma) 157{ 158 png_set_background_fixed(png_ptr, background_color, background_gamma_code, 159 need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); 160} 161# endif /* FLOATING_POINT */ 162#endif /* READ_BACKGROUND */ 163 164/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the 165 * one that pngrtran does first (scale) happens. This is necessary to allow the 166 * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. 167 */ 168#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 169void PNGAPI 170png_set_scale_16(png_structrp png_ptr) 171{ 172 png_debug(1, "in png_set_scale_16"); 173 174 if (!png_rtran_ok(png_ptr, 0)) 175 return; 176 177 png_ptr->transformations |= PNG_SCALE_16_TO_8; 178} 179#endif 180 181#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 182/* Chop 16-bit depth files to 8-bit depth */ 183void PNGAPI 184png_set_strip_16(png_structrp png_ptr) 185{ 186 png_debug(1, "in png_set_strip_16"); 187 188 if (!png_rtran_ok(png_ptr, 0)) 189 return; 190 191 png_ptr->transformations |= PNG_16_TO_8; 192} 193#endif 194 195#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 196void PNGAPI 197png_set_strip_alpha(png_structrp png_ptr) 198{ 199 png_debug(1, "in png_set_strip_alpha"); 200 201 if (!png_rtran_ok(png_ptr, 0)) 202 return; 203 204 png_ptr->transformations |= PNG_STRIP_ALPHA; 205} 206#endif 207 208#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) 209static png_fixed_point 210translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, 211 int is_screen) 212{ 213 /* Check for flag values. The main reason for having the old Mac value as a 214 * flag is that it is pretty near impossible to work out what the correct 215 * value is from Apple documentation - a working Mac system is needed to 216 * discover the value! 217 */ 218 if (output_gamma == PNG_DEFAULT_sRGB || 219 output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) 220 { 221 /* If there is no sRGB support this just sets the gamma to the standard 222 * sRGB value. (This is a side effect of using this function!) 223 */ 224# ifdef PNG_READ_sRGB_SUPPORTED 225 png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; 226# else 227 PNG_UNUSED(png_ptr) 228# endif 229 if (is_screen) 230 output_gamma = PNG_GAMMA_sRGB; 231 else 232 output_gamma = PNG_GAMMA_sRGB_INVERSE; 233 } 234 235 else if (output_gamma == PNG_GAMMA_MAC_18 || 236 output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) 237 { 238 if (is_screen) 239 output_gamma = PNG_GAMMA_MAC_OLD; 240 else 241 output_gamma = PNG_GAMMA_MAC_INVERSE; 242 } 243 244 return output_gamma; 245} 246 247# ifdef PNG_FLOATING_POINT_SUPPORTED 248static png_fixed_point 249convert_gamma_value(png_structrp png_ptr, double output_gamma) 250{ 251 /* The following silently ignores cases where fixed point (times 100,000) 252 * gamma values are passed to the floating point API. This is safe and it 253 * means the fixed point constants work just fine with the floating point 254 * API. The alternative would just lead to undetected errors and spurious 255 * bug reports. Negative values fail inside the _fixed API unless they 256 * correspond to the flag values. 257 */ 258 if (output_gamma > 0 && output_gamma < 128) 259 output_gamma *= PNG_FP_1; 260 261 /* This preserves -1 and -2 exactly: */ 262 output_gamma = floor(output_gamma + .5); 263 264 if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) 265 png_fixed_error(png_ptr, "gamma value"); 266 267 return (png_fixed_point)output_gamma; 268} 269# endif 270#endif /* READ_ALPHA_MODE || READ_GAMMA */ 271 272#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 273void PNGFAPI 274png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, 275 png_fixed_point output_gamma) 276{ 277 int compose = 0; 278 png_fixed_point file_gamma; 279 280 png_debug(1, "in png_set_alpha_mode"); 281 282 if (!png_rtran_ok(png_ptr, 0)) 283 return; 284 285 output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); 286 287 /* Validate the value to ensure it is in a reasonable range. The value 288 * is expected to be 1 or greater, but this range test allows for some 289 * viewing correction values. The intent is to weed out users of this API 290 * who use the inverse of the gamma value accidentally! Since some of these 291 * values are reasonable this may have to be changed. 292 */ 293 if (output_gamma < 70000 || output_gamma > 300000) 294 png_error(png_ptr, "output gamma out of expected range"); 295 296 /* The default file gamma is the inverse of the output gamma; the output 297 * gamma may be changed below so get the file value first: 298 */ 299 file_gamma = png_reciprocal(output_gamma); 300 301 /* There are really 8 possibilities here, composed of any combination 302 * of: 303 * 304 * premultiply the color channels 305 * do not encode non-opaque pixels 306 * encode the alpha as well as the color channels 307 * 308 * The differences disappear if the input/output ('screen') gamma is 1.0, 309 * because then the encoding is a no-op and there is only the choice of 310 * premultiplying the color channels or not. 311 * 312 * png_set_alpha_mode and png_set_background interact because both use 313 * png_compose to do the work. Calling both is only useful when 314 * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along 315 * with a default gamma value. Otherwise PNG_COMPOSE must not be set. 316 */ 317 switch (mode) 318 { 319 case PNG_ALPHA_PNG: /* default: png standard */ 320 /* No compose, but it may be set by png_set_background! */ 321 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 322 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 323 break; 324 325 case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ 326 compose = 1; 327 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 328 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 329 /* The output is linear: */ 330 output_gamma = PNG_FP_1; 331 break; 332 333 case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ 334 compose = 1; 335 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 336 png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; 337 /* output_gamma records the encoding of opaque pixels! */ 338 break; 339 340 case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ 341 compose = 1; 342 png_ptr->transformations |= PNG_ENCODE_ALPHA; 343 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 344 break; 345 346 default: 347 png_error(png_ptr, "invalid alpha mode"); 348 } 349 350 /* Only set the default gamma if the file gamma has not been set (this has 351 * the side effect that the gamma in a second call to png_set_alpha_mode will 352 * be ignored.) 353 */ 354 if (png_ptr->colorspace.gamma == 0) 355 { 356 png_ptr->colorspace.gamma = file_gamma; 357 png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 358 } 359 360 /* But always set the output gamma: */ 361 png_ptr->screen_gamma = output_gamma; 362 363 /* Finally, if pre-multiplying, set the background fields to achieve the 364 * desired result. 365 */ 366 if (compose) 367 { 368 /* And obtain alpha pre-multiplication by composing on black: */ 369 memset(&png_ptr->background, 0, (sizeof png_ptr->background)); 370 png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ 371 png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; 372 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; 373 374 if (png_ptr->transformations & PNG_COMPOSE) 375 png_error(png_ptr, 376 "conflicting calls to set alpha mode and background"); 377 378 png_ptr->transformations |= PNG_COMPOSE; 379 } 380} 381 382# ifdef PNG_FLOATING_POINT_SUPPORTED 383void PNGAPI 384png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) 385{ 386 png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, 387 output_gamma)); 388} 389# endif 390#endif 391 392#ifdef PNG_READ_QUANTIZE_SUPPORTED 393/* Dither file to 8-bit. Supply a palette, the current number 394 * of elements in the palette, the maximum number of elements 395 * allowed, and a histogram if possible. If the current number 396 * of colors is greater then the maximum number, the palette will be 397 * modified to fit in the maximum number. "full_quantize" indicates 398 * whether we need a quantizing cube set up for RGB images, or if we 399 * simply are reducing the number of colors in a paletted image. 400 */ 401 402typedef struct png_dsort_struct 403{ 404 struct png_dsort_struct * next; 405 png_byte left; 406 png_byte right; 407} png_dsort; 408typedef png_dsort * png_dsortp; 409typedef png_dsort * * png_dsortpp; 410 411void PNGAPI 412png_set_quantize(png_structrp png_ptr, png_colorp palette, 413 int num_palette, int maximum_colors, png_const_uint_16p histogram, 414 int full_quantize) 415{ 416 png_debug(1, "in png_set_quantize"); 417 418 if (!png_rtran_ok(png_ptr, 0)) 419 return; 420 421 png_ptr->transformations |= PNG_QUANTIZE; 422 423 if (!full_quantize) 424 { 425 int i; 426 427 png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, 428 (png_uint_32)(num_palette * (sizeof (png_byte)))); 429 for (i = 0; i < num_palette; i++) 430 png_ptr->quantize_index[i] = (png_byte)i; 431 } 432 433 if (num_palette > maximum_colors) 434 { 435 if (histogram != NULL) 436 { 437 /* This is easy enough, just throw out the least used colors. 438 * Perhaps not the best solution, but good enough. 439 */ 440 441 int i; 442 443 /* Initialize an array to sort colors */ 444 png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, 445 (png_uint_32)(num_palette * (sizeof (png_byte)))); 446 447 /* Initialize the quantize_sort array */ 448 for (i = 0; i < num_palette; i++) 449 png_ptr->quantize_sort[i] = (png_byte)i; 450 451 /* Find the least used palette entries by starting a 452 * bubble sort, and running it until we have sorted 453 * out enough colors. Note that we don't care about 454 * sorting all the colors, just finding which are 455 * least used. 456 */ 457 458 for (i = num_palette - 1; i >= maximum_colors; i--) 459 { 460 int done; /* To stop early if the list is pre-sorted */ 461 int j; 462 463 done = 1; 464 for (j = 0; j < i; j++) 465 { 466 if (histogram[png_ptr->quantize_sort[j]] 467 < histogram[png_ptr->quantize_sort[j + 1]]) 468 { 469 png_byte t; 470 471 t = png_ptr->quantize_sort[j]; 472 png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; 473 png_ptr->quantize_sort[j + 1] = t; 474 done = 0; 475 } 476 } 477 478 if (done) 479 break; 480 } 481 482 /* Swap the palette around, and set up a table, if necessary */ 483 if (full_quantize) 484 { 485 int j = num_palette; 486 487 /* Put all the useful colors within the max, but don't 488 * move the others. 489 */ 490 for (i = 0; i < maximum_colors; i++) 491 { 492 if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 493 { 494 do 495 j--; 496 while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 497 498 palette[i] = palette[j]; 499 } 500 } 501 } 502 else 503 { 504 int j = num_palette; 505 506 /* Move all the used colors inside the max limit, and 507 * develop a translation table. 508 */ 509 for (i = 0; i < maximum_colors; i++) 510 { 511 /* Only move the colors we need to */ 512 if ((int)png_ptr->quantize_sort[i] >= maximum_colors) 513 { 514 png_color tmp_color; 515 516 do 517 j--; 518 while ((int)png_ptr->quantize_sort[j] >= maximum_colors); 519 520 tmp_color = palette[j]; 521 palette[j] = palette[i]; 522 palette[i] = tmp_color; 523 /* Indicate where the color went */ 524 png_ptr->quantize_index[j] = (png_byte)i; 525 png_ptr->quantize_index[i] = (png_byte)j; 526 } 527 } 528 529 /* Find closest color for those colors we are not using */ 530 for (i = 0; i < num_palette; i++) 531 { 532 if ((int)png_ptr->quantize_index[i] >= maximum_colors) 533 { 534 int min_d, k, min_k, d_index; 535 536 /* Find the closest color to one we threw out */ 537 d_index = png_ptr->quantize_index[i]; 538 min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); 539 for (k = 1, min_k = 0; k < maximum_colors; k++) 540 { 541 int d; 542 543 d = PNG_COLOR_DIST(palette[d_index], palette[k]); 544 545 if (d < min_d) 546 { 547 min_d = d; 548 min_k = k; 549 } 550 } 551 /* Point to closest color */ 552 png_ptr->quantize_index[i] = (png_byte)min_k; 553 } 554 } 555 } 556 png_free(png_ptr, png_ptr->quantize_sort); 557 png_ptr->quantize_sort = NULL; 558 } 559 else 560 { 561 /* This is much harder to do simply (and quickly). Perhaps 562 * we need to go through a median cut routine, but those 563 * don't always behave themselves with only a few colors 564 * as input. So we will just find the closest two colors, 565 * and throw out one of them (chosen somewhat randomly). 566 * [We don't understand this at all, so if someone wants to 567 * work on improving it, be our guest - AED, GRP] 568 */ 569 int i; 570 int max_d; 571 int num_new_palette; 572 png_dsortp t; 573 png_dsortpp hash; 574 575 t = NULL; 576 577 /* Initialize palette index arrays */ 578 png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, 579 (png_uint_32)(num_palette * (sizeof (png_byte)))); 580 png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, 581 (png_uint_32)(num_palette * (sizeof (png_byte)))); 582 583 /* Initialize the sort array */ 584 for (i = 0; i < num_palette; i++) 585 { 586 png_ptr->index_to_palette[i] = (png_byte)i; 587 png_ptr->palette_to_index[i] = (png_byte)i; 588 } 589 590 hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * 591 (sizeof (png_dsortp)))); 592 593 num_new_palette = num_palette; 594 595 /* Initial wild guess at how far apart the farthest pixel 596 * pair we will be eliminating will be. Larger 597 * numbers mean more areas will be allocated, Smaller 598 * numbers run the risk of not saving enough data, and 599 * having to do this all over again. 600 * 601 * I have not done extensive checking on this number. 602 */ 603 max_d = 96; 604 605 while (num_new_palette > maximum_colors) 606 { 607 for (i = 0; i < num_new_palette - 1; i++) 608 { 609 int j; 610 611 for (j = i + 1; j < num_new_palette; j++) 612 { 613 int d; 614 615 d = PNG_COLOR_DIST(palette[i], palette[j]); 616 617 if (d <= max_d) 618 { 619 620 t = (png_dsortp)png_malloc_warn(png_ptr, 621 (png_uint_32)(sizeof (png_dsort))); 622 623 if (t == NULL) 624 break; 625 626 t->next = hash[d]; 627 t->left = (png_byte)i; 628 t->right = (png_byte)j; 629 hash[d] = t; 630 } 631 } 632 if (t == NULL) 633 break; 634 } 635 636 if (t != NULL) 637 for (i = 0; i <= max_d; i++) 638 { 639 if (hash[i] != NULL) 640 { 641 png_dsortp p; 642 643 for (p = hash[i]; p; p = p->next) 644 { 645 if ((int)png_ptr->index_to_palette[p->left] 646 < num_new_palette && 647 (int)png_ptr->index_to_palette[p->right] 648 < num_new_palette) 649 { 650 int j, next_j; 651 652 if (num_new_palette & 0x01) 653 { 654 j = p->left; 655 next_j = p->right; 656 } 657 else 658 { 659 j = p->right; 660 next_j = p->left; 661 } 662 663 num_new_palette--; 664 palette[png_ptr->index_to_palette[j]] 665 = palette[num_new_palette]; 666 if (!full_quantize) 667 { 668 int k; 669 670 for (k = 0; k < num_palette; k++) 671 { 672 if (png_ptr->quantize_index[k] == 673 png_ptr->index_to_palette[j]) 674 png_ptr->quantize_index[k] = 675 png_ptr->index_to_palette[next_j]; 676 677 if ((int)png_ptr->quantize_index[k] == 678 num_new_palette) 679 png_ptr->quantize_index[k] = 680 png_ptr->index_to_palette[j]; 681 } 682 } 683 684 png_ptr->index_to_palette[png_ptr->palette_to_index 685 [num_new_palette]] = png_ptr->index_to_palette[j]; 686 687 png_ptr->palette_to_index[png_ptr->index_to_palette[j]] 688 = png_ptr->palette_to_index[num_new_palette]; 689 690 png_ptr->index_to_palette[j] = 691 (png_byte)num_new_palette; 692 693 png_ptr->palette_to_index[num_new_palette] = 694 (png_byte)j; 695 } 696 if (num_new_palette <= maximum_colors) 697 break; 698 } 699 if (num_new_palette <= maximum_colors) 700 break; 701 } 702 } 703 704 for (i = 0; i < 769; i++) 705 { 706 if (hash[i] != NULL) 707 { 708 png_dsortp p = hash[i]; 709 while (p) 710 { 711 t = p->next; 712 png_free(png_ptr, p); 713 p = t; 714 } 715 } 716 hash[i] = 0; 717 } 718 max_d += 96; 719 } 720 png_free(png_ptr, hash); 721 png_free(png_ptr, png_ptr->palette_to_index); 722 png_free(png_ptr, png_ptr->index_to_palette); 723 png_ptr->palette_to_index = NULL; 724 png_ptr->index_to_palette = NULL; 725 } 726 num_palette = maximum_colors; 727 } 728 if (png_ptr->palette == NULL) 729 { 730 png_ptr->palette = palette; 731 } 732 png_ptr->num_palette = (png_uint_16)num_palette; 733 734 if (full_quantize) 735 { 736 int i; 737 png_bytep distance; 738 int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + 739 PNG_QUANTIZE_BLUE_BITS; 740 int num_red = (1 << PNG_QUANTIZE_RED_BITS); 741 int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); 742 int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); 743 png_size_t num_entries = ((png_size_t)1 << total_bits); 744 745 png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, 746 (png_uint_32)(num_entries * (sizeof (png_byte)))); 747 748 distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * 749 (sizeof (png_byte)))); 750 751 memset(distance, 0xff, num_entries * (sizeof (png_byte))); 752 753 for (i = 0; i < num_palette; i++) 754 { 755 int ir, ig, ib; 756 int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); 757 int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); 758 int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); 759 760 for (ir = 0; ir < num_red; ir++) 761 { 762 /* int dr = abs(ir - r); */ 763 int dr = ((ir > r) ? ir - r : r - ir); 764 int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + 765 PNG_QUANTIZE_GREEN_BITS)); 766 767 for (ig = 0; ig < num_green; ig++) 768 { 769 /* int dg = abs(ig - g); */ 770 int dg = ((ig > g) ? ig - g : g - ig); 771 int dt = dr + dg; 772 int dm = ((dr > dg) ? dr : dg); 773 int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); 774 775 for (ib = 0; ib < num_blue; ib++) 776 { 777 int d_index = index_g | ib; 778 /* int db = abs(ib - b); */ 779 int db = ((ib > b) ? ib - b : b - ib); 780 int dmax = ((dm > db) ? dm : db); 781 int d = dmax + dt + db; 782 783 if (d < (int)distance[d_index]) 784 { 785 distance[d_index] = (png_byte)d; 786 png_ptr->palette_lookup[d_index] = (png_byte)i; 787 } 788 } 789 } 790 } 791 } 792 793 png_free(png_ptr, distance); 794 } 795} 796#endif /* PNG_READ_QUANTIZE_SUPPORTED */ 797 798#ifdef PNG_READ_GAMMA_SUPPORTED 799void PNGFAPI 800png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, 801 png_fixed_point file_gamma) 802{ 803 png_debug(1, "in png_set_gamma_fixed"); 804 805 if (!png_rtran_ok(png_ptr, 0)) 806 return; 807 808 /* New in libpng-1.5.4 - reserve particular negative values as flags. */ 809 scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); 810 file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); 811 812 /* Checking the gamma values for being >0 was added in 1.5.4 along with the 813 * premultiplied alpha support; this actually hides an undocumented feature 814 * of the previous implementation which allowed gamma processing to be 815 * disabled in background handling. There is no evidence (so far) that this 816 * was being used; however, png_set_background itself accepted and must still 817 * accept '0' for the gamma value it takes, because it isn't always used. 818 * 819 * Since this is an API change (albeit a very minor one that removes an 820 * undocumented API feature) the following checks were only enabled in 821 * libpng-1.6.0. 822 */ 823 if (file_gamma <= 0) 824 png_error(png_ptr, "invalid file gamma in png_set_gamma"); 825 826 if (scrn_gamma <= 0) 827 png_error(png_ptr, "invalid screen gamma in png_set_gamma"); 828 829 /* Set the gamma values unconditionally - this overrides the value in the PNG 830 * file if a gAMA chunk was present. png_set_alpha_mode provides a 831 * different, easier, way to default the file gamma. 832 */ 833 png_ptr->colorspace.gamma = file_gamma; 834 png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 835 png_ptr->screen_gamma = scrn_gamma; 836} 837 838# ifdef PNG_FLOATING_POINT_SUPPORTED 839void PNGAPI 840png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) 841{ 842 png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), 843 convert_gamma_value(png_ptr, file_gamma)); 844} 845# endif /* FLOATING_POINT_SUPPORTED */ 846#endif /* READ_GAMMA */ 847 848#ifdef PNG_READ_EXPAND_SUPPORTED 849/* Expand paletted images to RGB, expand grayscale images of 850 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks 851 * to alpha channels. 852 */ 853void PNGAPI 854png_set_expand(png_structrp png_ptr) 855{ 856 png_debug(1, "in png_set_expand"); 857 858 if (!png_rtran_ok(png_ptr, 0)) 859 return; 860 861 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 862} 863 864/* GRR 19990627: the following three functions currently are identical 865 * to png_set_expand(). However, it is entirely reasonable that someone 866 * might wish to expand an indexed image to RGB but *not* expand a single, 867 * fully transparent palette entry to a full alpha channel--perhaps instead 868 * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace 869 * the transparent color with a particular RGB value, or drop tRNS entirely. 870 * IOW, a future version of the library may make the transformations flag 871 * a bit more fine-grained, with separate bits for each of these three 872 * functions. 873 * 874 * More to the point, these functions make it obvious what libpng will be 875 * doing, whereas "expand" can (and does) mean any number of things. 876 * 877 * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified 878 * to expand only the sample depth but not to expand the tRNS to alpha 879 * and its name was changed to png_set_expand_gray_1_2_4_to_8(). 880 */ 881 882/* Expand paletted images to RGB. */ 883void PNGAPI 884png_set_palette_to_rgb(png_structrp png_ptr) 885{ 886 png_debug(1, "in png_set_palette_to_rgb"); 887 888 if (!png_rtran_ok(png_ptr, 0)) 889 return; 890 891 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 892} 893 894/* Expand grayscale images of less than 8-bit depth to 8 bits. */ 895void PNGAPI 896png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) 897{ 898 png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); 899 900 if (!png_rtran_ok(png_ptr, 0)) 901 return; 902 903 png_ptr->transformations |= PNG_EXPAND; 904} 905 906/* Expand tRNS chunks to alpha channels. */ 907void PNGAPI 908png_set_tRNS_to_alpha(png_structrp png_ptr) 909{ 910 png_debug(1, "in png_set_tRNS_to_alpha"); 911 912 if (!png_rtran_ok(png_ptr, 0)) 913 return; 914 915 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); 916} 917#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ 918 919#ifdef PNG_READ_EXPAND_16_SUPPORTED 920/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise 921 * it may not work correctly.) 922 */ 923void PNGAPI 924png_set_expand_16(png_structrp png_ptr) 925{ 926 png_debug(1, "in png_set_expand_16"); 927 928 if (!png_rtran_ok(png_ptr, 0)) 929 return; 930 931 png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); 932} 933#endif 934 935#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 936void PNGAPI 937png_set_gray_to_rgb(png_structrp png_ptr) 938{ 939 png_debug(1, "in png_set_gray_to_rgb"); 940 941 if (!png_rtran_ok(png_ptr, 0)) 942 return; 943 944 /* Because rgb must be 8 bits or more: */ 945 png_set_expand_gray_1_2_4_to_8(png_ptr); 946 png_ptr->transformations |= PNG_GRAY_TO_RGB; 947} 948#endif 949 950#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 951void PNGFAPI 952png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, 953 png_fixed_point red, png_fixed_point green) 954{ 955 png_debug(1, "in png_set_rgb_to_gray"); 956 957 /* Need the IHDR here because of the check on color_type below. */ 958 /* TODO: fix this */ 959 if (!png_rtran_ok(png_ptr, 1)) 960 return; 961 962 switch(error_action) 963 { 964 case PNG_ERROR_ACTION_NONE: 965 png_ptr->transformations |= PNG_RGB_TO_GRAY; 966 break; 967 968 case PNG_ERROR_ACTION_WARN: 969 png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; 970 break; 971 972 case PNG_ERROR_ACTION_ERROR: 973 png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; 974 break; 975 976 default: 977 png_error(png_ptr, "invalid error action to rgb_to_gray"); 978 break; 979 } 980 981 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 982#ifdef PNG_READ_EXPAND_SUPPORTED 983 png_ptr->transformations |= PNG_EXPAND; 984#else 985 { 986 /* Make this an error in 1.6 because otherwise the application may assume 987 * that it just worked and get a memory overwrite. 988 */ 989 png_error(png_ptr, 990 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); 991 992 /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ 993 } 994#endif 995 { 996 if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) 997 { 998 png_uint_16 red_int, green_int; 999 1000 /* NOTE: this calculation does not round, but this behavior is retained 1001 * for consistency, the inaccuracy is very small. The code here always 1002 * overwrites the coefficients, regardless of whether they have been 1003 * defaulted or set already. 1004 */ 1005 red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); 1006 green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); 1007 1008 png_ptr->rgb_to_gray_red_coeff = red_int; 1009 png_ptr->rgb_to_gray_green_coeff = green_int; 1010 png_ptr->rgb_to_gray_coefficients_set = 1; 1011 } 1012 1013 else 1014 { 1015 if (red >= 0 && green >= 0) 1016 png_app_warning(png_ptr, 1017 "ignoring out of range rgb_to_gray coefficients"); 1018 1019 /* Use the defaults, from the cHRM chunk if set, else the historical 1020 * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See 1021 * png_do_rgb_to_gray for more discussion of the values. In this case 1022 * the coefficients are not marked as 'set' and are not overwritten if 1023 * something has already provided a default. 1024 */ 1025 if (png_ptr->rgb_to_gray_red_coeff == 0 && 1026 png_ptr->rgb_to_gray_green_coeff == 0) 1027 { 1028 png_ptr->rgb_to_gray_red_coeff = 6968; 1029 png_ptr->rgb_to_gray_green_coeff = 23434; 1030 /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ 1031 } 1032 } 1033 } 1034} 1035 1036#ifdef PNG_FLOATING_POINT_SUPPORTED 1037/* Convert a RGB image to a grayscale of the same width. This allows us, 1038 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. 1039 */ 1040 1041void PNGAPI 1042png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, 1043 double green) 1044{ 1045 png_set_rgb_to_gray_fixed(png_ptr, error_action, 1046 png_fixed(png_ptr, red, "rgb to gray red coefficient"), 1047 png_fixed(png_ptr, green, "rgb to gray green coefficient")); 1048} 1049#endif /* FLOATING POINT */ 1050 1051#endif /* RGB_TO_GRAY */ 1052 1053#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ 1054 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) 1055void PNGAPI 1056png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr 1057 read_user_transform_fn) 1058{ 1059 png_debug(1, "in png_set_read_user_transform_fn"); 1060 1061#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 1062 png_ptr->transformations |= PNG_USER_TRANSFORM; 1063 png_ptr->read_user_transform_fn = read_user_transform_fn; 1064#endif 1065} 1066#endif 1067 1068#ifdef PNG_READ_TRANSFORMS_SUPPORTED 1069#ifdef PNG_READ_GAMMA_SUPPORTED 1070/* In the case of gamma transformations only do transformations on images where 1071 * the [file] gamma and screen_gamma are not close reciprocals, otherwise it 1072 * slows things down slightly, and also needlessly introduces small errors. 1073 */ 1074static int /* PRIVATE */ 1075png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) 1076{ 1077 /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma 1078 * correction as a difference of the overall transform from 1.0 1079 * 1080 * We want to compare the threshold with s*f - 1, if we get 1081 * overflow here it is because of wacky gamma values so we 1082 * turn on processing anyway. 1083 */ 1084 png_fixed_point gtest; 1085 return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || 1086 png_gamma_significant(gtest); 1087} 1088#endif 1089 1090/* Initialize everything needed for the read. This includes modifying 1091 * the palette. 1092 */ 1093 1094/*For the moment 'png_init_palette_transformations' and 1095 * 'png_init_rgb_transformations' only do some flag canceling optimizations. 1096 * The intent is that these two routines should have palette or rgb operations 1097 * extracted from 'png_init_read_transformations'. 1098 */ 1099static void /* PRIVATE */ 1100png_init_palette_transformations(png_structrp png_ptr) 1101{ 1102 /* Called to handle the (input) palette case. In png_do_read_transformations 1103 * the first step is to expand the palette if requested, so this code must 1104 * take care to only make changes that are invariant with respect to the 1105 * palette expansion, or only do them if there is no expansion. 1106 * 1107 * STRIP_ALPHA has already been handled in the caller (by setting num_trans 1108 * to 0.) 1109 */ 1110 int input_has_alpha = 0; 1111 int input_has_transparency = 0; 1112 1113 if (png_ptr->num_trans > 0) 1114 { 1115 int i; 1116 1117 /* Ignore if all the entries are opaque (unlikely!) */ 1118 for (i=0; i<png_ptr->num_trans; ++i) 1119 if (png_ptr->trans_alpha[i] == 255) 1120 continue; 1121 else if (png_ptr->trans_alpha[i] == 0) 1122 input_has_transparency = 1; 1123 else 1124 input_has_alpha = 1; 1125 } 1126 1127 /* If no alpha we can optimize. */ 1128 if (!input_has_alpha) 1129 { 1130 /* Any alpha means background and associative alpha processing is 1131 * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA 1132 * and ENCODE_ALPHA are irrelevant. 1133 */ 1134 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1135 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1136 1137 if (!input_has_transparency) 1138 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1139 } 1140 1141#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1142 /* png_set_background handling - deals with the complexity of whether the 1143 * background color is in the file format or the screen format in the case 1144 * where an 'expand' will happen. 1145 */ 1146 1147 /* The following code cannot be entered in the alpha pre-multiplication case 1148 * because PNG_BACKGROUND_EXPAND is cancelled below. 1149 */ 1150 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1151 (png_ptr->transformations & PNG_EXPAND)) 1152 { 1153 { 1154 png_ptr->background.red = 1155 png_ptr->palette[png_ptr->background.index].red; 1156 png_ptr->background.green = 1157 png_ptr->palette[png_ptr->background.index].green; 1158 png_ptr->background.blue = 1159 png_ptr->palette[png_ptr->background.index].blue; 1160 1161#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 1162 if (png_ptr->transformations & PNG_INVERT_ALPHA) 1163 { 1164 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 1165 { 1166 /* Invert the alpha channel (in tRNS) unless the pixels are 1167 * going to be expanded, in which case leave it for later 1168 */ 1169 int i, istop = png_ptr->num_trans; 1170 1171 for (i=0; i<istop; i++) 1172 png_ptr->trans_alpha[i] = (png_byte)(255 - 1173 png_ptr->trans_alpha[i]); 1174 } 1175 } 1176#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ 1177 } 1178 } /* background expand and (therefore) no alpha association. */ 1179#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1180} 1181 1182static void /* PRIVATE */ 1183png_init_rgb_transformations(png_structrp png_ptr) 1184{ 1185 /* Added to libpng-1.5.4: check the color type to determine whether there 1186 * is any alpha or transparency in the image and simply cancel the 1187 * background and alpha mode stuff if there isn't. 1188 */ 1189 int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; 1190 int input_has_transparency = png_ptr->num_trans > 0; 1191 1192 /* If no alpha we can optimize. */ 1193 if (!input_has_alpha) 1194 { 1195 /* Any alpha means background and associative alpha processing is 1196 * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA 1197 * and ENCODE_ALPHA are irrelevant. 1198 */ 1199# ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1200 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1201 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1202# endif 1203 1204 if (!input_has_transparency) 1205 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); 1206 } 1207 1208#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1209 /* png_set_background handling - deals with the complexity of whether the 1210 * background color is in the file format or the screen format in the case 1211 * where an 'expand' will happen. 1212 */ 1213 1214 /* The following code cannot be entered in the alpha pre-multiplication case 1215 * because PNG_BACKGROUND_EXPAND is cancelled below. 1216 */ 1217 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1218 (png_ptr->transformations & PNG_EXPAND) && 1219 !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) 1220 /* i.e., GRAY or GRAY_ALPHA */ 1221 { 1222 { 1223 /* Expand background and tRNS chunks */ 1224 int gray = png_ptr->background.gray; 1225 int trans_gray = png_ptr->trans_color.gray; 1226 1227 switch (png_ptr->bit_depth) 1228 { 1229 case 1: 1230 gray *= 0xff; 1231 trans_gray *= 0xff; 1232 break; 1233 1234 case 2: 1235 gray *= 0x55; 1236 trans_gray *= 0x55; 1237 break; 1238 1239 case 4: 1240 gray *= 0x11; 1241 trans_gray *= 0x11; 1242 break; 1243 1244 default: 1245 1246 case 8: 1247 /* FALL THROUGH (Already 8 bits) */ 1248 1249 case 16: 1250 /* Already a full 16 bits */ 1251 break; 1252 } 1253 1254 png_ptr->background.red = png_ptr->background.green = 1255 png_ptr->background.blue = (png_uint_16)gray; 1256 1257 if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) 1258 { 1259 png_ptr->trans_color.red = png_ptr->trans_color.green = 1260 png_ptr->trans_color.blue = (png_uint_16)trans_gray; 1261 } 1262 } 1263 } /* background expand and (therefore) no alpha association. */ 1264#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1265} 1266 1267void /* PRIVATE */ 1268png_init_read_transformations(png_structrp png_ptr) 1269{ 1270 png_debug(1, "in png_init_read_transformations"); 1271 1272 /* This internal function is called from png_read_start_row in pngrutil.c 1273 * and it is called before the 'rowbytes' calculation is done, so the code 1274 * in here can change or update the transformations flags. 1275 * 1276 * First do updates that do not depend on the details of the PNG image data 1277 * being processed. 1278 */ 1279 1280#ifdef PNG_READ_GAMMA_SUPPORTED 1281 /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds 1282 * png_set_alpha_mode and this is another source for a default file gamma so 1283 * the test needs to be performed later - here. In addition prior to 1.5.4 1284 * the tests were repeated for the PALETTE color type here - this is no 1285 * longer necessary (and doesn't seem to have been necessary before.) 1286 */ 1287 { 1288 /* The following temporary indicates if overall gamma correction is 1289 * required. 1290 */ 1291 int gamma_correction = 0; 1292 1293 if (png_ptr->colorspace.gamma != 0) /* has been set */ 1294 { 1295 if (png_ptr->screen_gamma != 0) /* screen set too */ 1296 gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, 1297 png_ptr->screen_gamma); 1298 1299 else 1300 /* Assume the output matches the input; a long time default behavior 1301 * of libpng, although the standard has nothing to say about this. 1302 */ 1303 png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); 1304 } 1305 1306 else if (png_ptr->screen_gamma != 0) 1307 /* The converse - assume the file matches the screen, note that this 1308 * perhaps undesireable default can (from 1.5.4) be changed by calling 1309 * png_set_alpha_mode (even if the alpha handling mode isn't required 1310 * or isn't changed from the default.) 1311 */ 1312 png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); 1313 1314 else /* neither are set */ 1315 /* Just in case the following prevents any processing - file and screen 1316 * are both assumed to be linear and there is no way to introduce a 1317 * third gamma value other than png_set_background with 'UNIQUE', and, 1318 * prior to 1.5.4 1319 */ 1320 png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; 1321 1322 /* We have a gamma value now. */ 1323 png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 1324 1325 /* Now turn the gamma transformation on or off as appropriate. Notice 1326 * that PNG_GAMMA just refers to the file->screen correction. Alpha 1327 * composition may independently cause gamma correction because it needs 1328 * linear data (e.g. if the file has a gAMA chunk but the screen gamma 1329 * hasn't been specified.) In any case this flag may get turned off in 1330 * the code immediately below if the transform can be handled outside the 1331 * row loop. 1332 */ 1333 if (gamma_correction) 1334 png_ptr->transformations |= PNG_GAMMA; 1335 1336 else 1337 png_ptr->transformations &= ~PNG_GAMMA; 1338 } 1339#endif 1340 1341 /* Certain transformations have the effect of preventing other 1342 * transformations that happen afterward in png_do_read_transformations, 1343 * resolve the interdependencies here. From the code of 1344 * png_do_read_transformations the order is: 1345 * 1346 * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) 1347 * 2) PNG_STRIP_ALPHA (if no compose) 1348 * 3) PNG_RGB_TO_GRAY 1349 * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY 1350 * 5) PNG_COMPOSE 1351 * 6) PNG_GAMMA 1352 * 7) PNG_STRIP_ALPHA (if compose) 1353 * 8) PNG_ENCODE_ALPHA 1354 * 9) PNG_SCALE_16_TO_8 1355 * 10) PNG_16_TO_8 1356 * 11) PNG_QUANTIZE (converts to palette) 1357 * 12) PNG_EXPAND_16 1358 * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY 1359 * 14) PNG_INVERT_MONO 1360 * 15) PNG_SHIFT 1361 * 16) PNG_PACK 1362 * 17) PNG_BGR 1363 * 18) PNG_PACKSWAP 1364 * 19) PNG_FILLER (includes PNG_ADD_ALPHA) 1365 * 20) PNG_INVERT_ALPHA 1366 * 21) PNG_SWAP_ALPHA 1367 * 22) PNG_SWAP_BYTES 1368 * 23) PNG_USER_TRANSFORM [must be last] 1369 */ 1370#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 1371 if ((png_ptr->transformations & PNG_STRIP_ALPHA) && 1372 !(png_ptr->transformations & PNG_COMPOSE)) 1373 { 1374 /* Stripping the alpha channel happens immediately after the 'expand' 1375 * transformations, before all other transformation, so it cancels out 1376 * the alpha handling. It has the side effect negating the effect of 1377 * PNG_EXPAND_tRNS too: 1378 */ 1379 png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | 1380 PNG_EXPAND_tRNS); 1381 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1382 1383 /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen 1384 * so transparency information would remain just so long as it wasn't 1385 * expanded. This produces unexpected API changes if the set of things 1386 * that do PNG_EXPAND_tRNS changes (perfectly possible given the 1387 * documentation - which says ask for what you want, accept what you 1388 * get.) This makes the behavior consistent from 1.5.4: 1389 */ 1390 png_ptr->num_trans = 0; 1391 } 1392#endif /* STRIP_ALPHA supported, no COMPOSE */ 1393 1394#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 1395 /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA 1396 * settings will have no effect. 1397 */ 1398 if (!png_gamma_significant(png_ptr->screen_gamma)) 1399 { 1400 png_ptr->transformations &= ~PNG_ENCODE_ALPHA; 1401 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; 1402 } 1403#endif 1404 1405#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 1406 /* Make sure the coefficients for the rgb to gray conversion are set 1407 * appropriately. 1408 */ 1409 if (png_ptr->transformations & PNG_RGB_TO_GRAY) 1410 png_colorspace_set_rgb_coefficients(png_ptr); 1411#endif 1412 1413#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 1414#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) 1415 /* Detect gray background and attempt to enable optimization for 1416 * gray --> RGB case. 1417 * 1418 * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or 1419 * RGB_ALPHA (in which case need_expand is superfluous anyway), the 1420 * background color might actually be gray yet not be flagged as such. 1421 * This is not a problem for the current code, which uses 1422 * PNG_BACKGROUND_IS_GRAY only to decide when to do the 1423 * png_do_gray_to_rgb() transformation. 1424 * 1425 * TODO: this code needs to be revised to avoid the complexity and 1426 * interdependencies. The color type of the background should be recorded in 1427 * png_set_background, along with the bit depth, then the code has a record 1428 * of exactly what color space the background is currently in. 1429 */ 1430 if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) 1431 { 1432 /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if 1433 * the file was grayscale the background value is gray. 1434 */ 1435 if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) 1436 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1437 } 1438 1439 else if (png_ptr->transformations & PNG_COMPOSE) 1440 { 1441 /* PNG_COMPOSE: png_set_background was called with need_expand false, 1442 * so the color is in the color space of the output or png_set_alpha_mode 1443 * was called and the color is black. Ignore RGB_TO_GRAY because that 1444 * happens before GRAY_TO_RGB. 1445 */ 1446 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 1447 { 1448 if (png_ptr->background.red == png_ptr->background.green && 1449 png_ptr->background.red == png_ptr->background.blue) 1450 { 1451 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; 1452 png_ptr->background.gray = png_ptr->background.red; 1453 } 1454 } 1455 } 1456#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ 1457#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ 1458 1459 /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations 1460 * can be performed directly on the palette, and some (such as rgb to gray) 1461 * can be optimized inside the palette. This is particularly true of the 1462 * composite (background and alpha) stuff, which can be pretty much all done 1463 * in the palette even if the result is expanded to RGB or gray afterward. 1464 * 1465 * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and 1466 * earlier and the palette stuff is actually handled on the first row. This 1467 * leads to the reported bug that the palette returned by png_get_PLTE is not 1468 * updated. 1469 */ 1470 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1471 png_init_palette_transformations(png_ptr); 1472 1473 else 1474 png_init_rgb_transformations(png_ptr); 1475 1476#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1477 defined(PNG_READ_EXPAND_16_SUPPORTED) 1478 if ((png_ptr->transformations & PNG_EXPAND_16) && 1479 (png_ptr->transformations & PNG_COMPOSE) && 1480 !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1481 png_ptr->bit_depth != 16) 1482 { 1483 /* TODO: fix this. Because the expand_16 operation is after the compose 1484 * handling the background color must be 8, not 16, bits deep, but the 1485 * application will supply a 16-bit value so reduce it here. 1486 * 1487 * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at 1488 * present, so that case is ok (until do_expand_16 is moved.) 1489 * 1490 * NOTE: this discards the low 16 bits of the user supplied background 1491 * color, but until expand_16 works properly there is no choice! 1492 */ 1493# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) 1494 CHOP(png_ptr->background.red); 1495 CHOP(png_ptr->background.green); 1496 CHOP(png_ptr->background.blue); 1497 CHOP(png_ptr->background.gray); 1498# undef CHOP 1499 } 1500#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ 1501 1502#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ 1503 (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ 1504 defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) 1505 if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && 1506 (png_ptr->transformations & PNG_COMPOSE) && 1507 !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && 1508 png_ptr->bit_depth == 16) 1509 { 1510 /* On the other hand, if a 16-bit file is to be reduced to 8-bits per 1511 * component this will also happen after PNG_COMPOSE and so the background 1512 * color must be pre-expanded here. 1513 * 1514 * TODO: fix this too. 1515 */ 1516 png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); 1517 png_ptr->background.green = 1518 (png_uint_16)(png_ptr->background.green * 257); 1519 png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); 1520 png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); 1521 } 1522#endif 1523 1524 /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the 1525 * background support (see the comments in scripts/pnglibconf.dfa), this 1526 * allows pre-multiplication of the alpha channel to be implemented as 1527 * compositing on black. This is probably sub-optimal and has been done in 1528 * 1.5.4 betas simply to enable external critique and testing (i.e. to 1529 * implement the new API quickly, without lots of internal changes.) 1530 */ 1531 1532#ifdef PNG_READ_GAMMA_SUPPORTED 1533# ifdef PNG_READ_BACKGROUND_SUPPORTED 1534 /* Includes ALPHA_MODE */ 1535 png_ptr->background_1 = png_ptr->background; 1536# endif 1537 1538 /* This needs to change - in the palette image case a whole set of tables are 1539 * built when it would be quicker to just calculate the correct value for 1540 * each palette entry directly. Also, the test is too tricky - why check 1541 * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that 1542 * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the 1543 * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction 1544 * the gamma tables will not be built even if composition is required on a 1545 * gamma encoded value. 1546 * 1547 * In 1.5.4 this is addressed below by an additional check on the individual 1548 * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the 1549 * tables. 1550 */ 1551 if ((png_ptr->transformations & PNG_GAMMA) 1552 || ((png_ptr->transformations & PNG_RGB_TO_GRAY) 1553 && (png_gamma_significant(png_ptr->colorspace.gamma) || 1554 png_gamma_significant(png_ptr->screen_gamma))) 1555 || ((png_ptr->transformations & PNG_COMPOSE) 1556 && (png_gamma_significant(png_ptr->colorspace.gamma) 1557 || png_gamma_significant(png_ptr->screen_gamma) 1558# ifdef PNG_READ_BACKGROUND_SUPPORTED 1559 || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE 1560 && png_gamma_significant(png_ptr->background_gamma)) 1561# endif 1562 )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) 1563 && png_gamma_significant(png_ptr->screen_gamma)) 1564 ) 1565 { 1566 png_build_gamma_table(png_ptr, png_ptr->bit_depth); 1567 1568#ifdef PNG_READ_BACKGROUND_SUPPORTED 1569 if (png_ptr->transformations & PNG_COMPOSE) 1570 { 1571 /* Issue a warning about this combination: because RGB_TO_GRAY is 1572 * optimized to do the gamma transform if present yet do_background has 1573 * to do the same thing if both options are set a 1574 * double-gamma-correction happens. This is true in all versions of 1575 * libpng to date. 1576 */ 1577 if (png_ptr->transformations & PNG_RGB_TO_GRAY) 1578 png_warning(png_ptr, 1579 "libpng does not support gamma+background+rgb_to_gray"); 1580 1581 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1582 { 1583 /* We don't get to here unless there is a tRNS chunk with non-opaque 1584 * entries - see the checking code at the start of this function. 1585 */ 1586 png_color back, back_1; 1587 png_colorp palette = png_ptr->palette; 1588 int num_palette = png_ptr->num_palette; 1589 int i; 1590 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) 1591 { 1592 1593 back.red = png_ptr->gamma_table[png_ptr->background.red]; 1594 back.green = png_ptr->gamma_table[png_ptr->background.green]; 1595 back.blue = png_ptr->gamma_table[png_ptr->background.blue]; 1596 1597 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; 1598 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; 1599 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; 1600 } 1601 else 1602 { 1603 png_fixed_point g, gs; 1604 1605 switch (png_ptr->background_gamma_type) 1606 { 1607 case PNG_BACKGROUND_GAMMA_SCREEN: 1608 g = (png_ptr->screen_gamma); 1609 gs = PNG_FP_1; 1610 break; 1611 1612 case PNG_BACKGROUND_GAMMA_FILE: 1613 g = png_reciprocal(png_ptr->colorspace.gamma); 1614 gs = png_reciprocal2(png_ptr->colorspace.gamma, 1615 png_ptr->screen_gamma); 1616 break; 1617 1618 case PNG_BACKGROUND_GAMMA_UNIQUE: 1619 g = png_reciprocal(png_ptr->background_gamma); 1620 gs = png_reciprocal2(png_ptr->background_gamma, 1621 png_ptr->screen_gamma); 1622 break; 1623 default: 1624 g = PNG_FP_1; /* back_1 */ 1625 gs = PNG_FP_1; /* back */ 1626 break; 1627 } 1628 1629 if (png_gamma_significant(gs)) 1630 { 1631 back.red = png_gamma_8bit_correct(png_ptr->background.red, 1632 gs); 1633 back.green = png_gamma_8bit_correct(png_ptr->background.green, 1634 gs); 1635 back.blue = png_gamma_8bit_correct(png_ptr->background.blue, 1636 gs); 1637 } 1638 1639 else 1640 { 1641 back.red = (png_byte)png_ptr->background.red; 1642 back.green = (png_byte)png_ptr->background.green; 1643 back.blue = (png_byte)png_ptr->background.blue; 1644 } 1645 1646 if (png_gamma_significant(g)) 1647 { 1648 back_1.red = png_gamma_8bit_correct(png_ptr->background.red, 1649 g); 1650 back_1.green = png_gamma_8bit_correct( 1651 png_ptr->background.green, g); 1652 back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, 1653 g); 1654 } 1655 1656 else 1657 { 1658 back_1.red = (png_byte)png_ptr->background.red; 1659 back_1.green = (png_byte)png_ptr->background.green; 1660 back_1.blue = (png_byte)png_ptr->background.blue; 1661 } 1662 } 1663 1664 for (i = 0; i < num_palette; i++) 1665 { 1666 if (i < (int)png_ptr->num_trans && 1667 png_ptr->trans_alpha[i] != 0xff) 1668 { 1669 if (png_ptr->trans_alpha[i] == 0) 1670 { 1671 palette[i] = back; 1672 } 1673 else /* if (png_ptr->trans_alpha[i] != 0xff) */ 1674 { 1675 png_byte v, w; 1676 1677 v = png_ptr->gamma_to_1[palette[i].red]; 1678 png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); 1679 palette[i].red = png_ptr->gamma_from_1[w]; 1680 1681 v = png_ptr->gamma_to_1[palette[i].green]; 1682 png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); 1683 palette[i].green = png_ptr->gamma_from_1[w]; 1684 1685 v = png_ptr->gamma_to_1[palette[i].blue]; 1686 png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); 1687 palette[i].blue = png_ptr->gamma_from_1[w]; 1688 } 1689 } 1690 else 1691 { 1692 palette[i].red = png_ptr->gamma_table[palette[i].red]; 1693 palette[i].green = png_ptr->gamma_table[palette[i].green]; 1694 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 1695 } 1696 } 1697 1698 /* Prevent the transformations being done again. 1699 * 1700 * NOTE: this is highly dubious; it removes the transformations in 1701 * place. This seems inconsistent with the general treatment of the 1702 * transformations elsewhere. 1703 */ 1704 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); 1705 } /* color_type == PNG_COLOR_TYPE_PALETTE */ 1706 1707 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ 1708 else /* color_type != PNG_COLOR_TYPE_PALETTE */ 1709 { 1710 int gs_sig, g_sig; 1711 png_fixed_point g = PNG_FP_1; /* Correction to linear */ 1712 png_fixed_point gs = PNG_FP_1; /* Correction to screen */ 1713 1714 switch (png_ptr->background_gamma_type) 1715 { 1716 case PNG_BACKGROUND_GAMMA_SCREEN: 1717 g = png_ptr->screen_gamma; 1718 /* gs = PNG_FP_1; */ 1719 break; 1720 1721 case PNG_BACKGROUND_GAMMA_FILE: 1722 g = png_reciprocal(png_ptr->colorspace.gamma); 1723 gs = png_reciprocal2(png_ptr->colorspace.gamma, 1724 png_ptr->screen_gamma); 1725 break; 1726 1727 case PNG_BACKGROUND_GAMMA_UNIQUE: 1728 g = png_reciprocal(png_ptr->background_gamma); 1729 gs = png_reciprocal2(png_ptr->background_gamma, 1730 png_ptr->screen_gamma); 1731 break; 1732 1733 default: 1734 png_error(png_ptr, "invalid background gamma type"); 1735 } 1736 1737 g_sig = png_gamma_significant(g); 1738 gs_sig = png_gamma_significant(gs); 1739 1740 if (g_sig) 1741 png_ptr->background_1.gray = png_gamma_correct(png_ptr, 1742 png_ptr->background.gray, g); 1743 1744 if (gs_sig) 1745 png_ptr->background.gray = png_gamma_correct(png_ptr, 1746 png_ptr->background.gray, gs); 1747 1748 if ((png_ptr->background.red != png_ptr->background.green) || 1749 (png_ptr->background.red != png_ptr->background.blue) || 1750 (png_ptr->background.red != png_ptr->background.gray)) 1751 { 1752 /* RGB or RGBA with color background */ 1753 if (g_sig) 1754 { 1755 png_ptr->background_1.red = png_gamma_correct(png_ptr, 1756 png_ptr->background.red, g); 1757 1758 png_ptr->background_1.green = png_gamma_correct(png_ptr, 1759 png_ptr->background.green, g); 1760 1761 png_ptr->background_1.blue = png_gamma_correct(png_ptr, 1762 png_ptr->background.blue, g); 1763 } 1764 1765 if (gs_sig) 1766 { 1767 png_ptr->background.red = png_gamma_correct(png_ptr, 1768 png_ptr->background.red, gs); 1769 1770 png_ptr->background.green = png_gamma_correct(png_ptr, 1771 png_ptr->background.green, gs); 1772 1773 png_ptr->background.blue = png_gamma_correct(png_ptr, 1774 png_ptr->background.blue, gs); 1775 } 1776 } 1777 1778 else 1779 { 1780 /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ 1781 png_ptr->background_1.red = png_ptr->background_1.green 1782 = png_ptr->background_1.blue = png_ptr->background_1.gray; 1783 1784 png_ptr->background.red = png_ptr->background.green 1785 = png_ptr->background.blue = png_ptr->background.gray; 1786 } 1787 1788 /* The background is now in screen gamma: */ 1789 png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; 1790 } /* color_type != PNG_COLOR_TYPE_PALETTE */ 1791 }/* png_ptr->transformations & PNG_BACKGROUND */ 1792 1793 else 1794 /* Transformation does not include PNG_BACKGROUND */ 1795#endif /* PNG_READ_BACKGROUND_SUPPORTED */ 1796 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE 1797#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 1798 /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ 1799 && ((png_ptr->transformations & PNG_EXPAND) == 0 || 1800 (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) 1801#endif 1802 ) 1803 { 1804 png_colorp palette = png_ptr->palette; 1805 int num_palette = png_ptr->num_palette; 1806 int i; 1807 1808 /* NOTE: there are other transformations that should probably be in 1809 * here too. 1810 */ 1811 for (i = 0; i < num_palette; i++) 1812 { 1813 palette[i].red = png_ptr->gamma_table[palette[i].red]; 1814 palette[i].green = png_ptr->gamma_table[palette[i].green]; 1815 palette[i].blue = png_ptr->gamma_table[palette[i].blue]; 1816 } 1817 1818 /* Done the gamma correction. */ 1819 png_ptr->transformations &= ~PNG_GAMMA; 1820 } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ 1821 } 1822#ifdef PNG_READ_BACKGROUND_SUPPORTED 1823 else 1824#endif 1825#endif /* PNG_READ_GAMMA_SUPPORTED */ 1826 1827#ifdef PNG_READ_BACKGROUND_SUPPORTED 1828 /* No GAMMA transformation (see the hanging else 4 lines above) */ 1829 if ((png_ptr->transformations & PNG_COMPOSE) && 1830 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) 1831 { 1832 int i; 1833 int istop = (int)png_ptr->num_trans; 1834 png_color back; 1835 png_colorp palette = png_ptr->palette; 1836 1837 back.red = (png_byte)png_ptr->background.red; 1838 back.green = (png_byte)png_ptr->background.green; 1839 back.blue = (png_byte)png_ptr->background.blue; 1840 1841 for (i = 0; i < istop; i++) 1842 { 1843 if (png_ptr->trans_alpha[i] == 0) 1844 { 1845 palette[i] = back; 1846 } 1847 1848 else if (png_ptr->trans_alpha[i] != 0xff) 1849 { 1850 /* The png_composite() macro is defined in png.h */ 1851 png_composite(palette[i].red, palette[i].red, 1852 png_ptr->trans_alpha[i], back.red); 1853 1854 png_composite(palette[i].green, palette[i].green, 1855 png_ptr->trans_alpha[i], back.green); 1856 1857 png_composite(palette[i].blue, palette[i].blue, 1858 png_ptr->trans_alpha[i], back.blue); 1859 } 1860 } 1861 1862 png_ptr->transformations &= ~PNG_COMPOSE; 1863 } 1864#endif /* PNG_READ_BACKGROUND_SUPPORTED */ 1865 1866#ifdef PNG_READ_SHIFT_SUPPORTED 1867 if ((png_ptr->transformations & PNG_SHIFT) && 1868 !(png_ptr->transformations & PNG_EXPAND) && 1869 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) 1870 { 1871 int i; 1872 int istop = png_ptr->num_palette; 1873 int shift = 8 - png_ptr->sig_bit.red; 1874 1875 png_ptr->transformations &= ~PNG_SHIFT; 1876 1877 /* significant bits can be in the range 1 to 7 for a meaninful result, if 1878 * the number of significant bits is 0 then no shift is done (this is an 1879 * error condition which is silently ignored.) 1880 */ 1881 if (shift > 0 && shift < 8) for (i=0; i<istop; ++i) 1882 { 1883 int component = png_ptr->palette[i].red; 1884 1885 component >>= shift; 1886 png_ptr->palette[i].red = (png_byte)component; 1887 } 1888 1889 shift = 8 - png_ptr->sig_bit.green; 1890 if (shift > 0 && shift < 8) for (i=0; i<istop; ++i) 1891 { 1892 int component = png_ptr->palette[i].green; 1893 1894 component >>= shift; 1895 png_ptr->palette[i].green = (png_byte)component; 1896 } 1897 1898 shift = 8 - png_ptr->sig_bit.blue; 1899 if (shift > 0 && shift < 8) for (i=0; i<istop; ++i) 1900 { 1901 int component = png_ptr->palette[i].blue; 1902 1903 component >>= shift; 1904 png_ptr->palette[i].blue = (png_byte)component; 1905 } 1906 } 1907#endif /* PNG_READ_SHIFT_SUPPORTED */ 1908} 1909 1910/* Modify the info structure to reflect the transformations. The 1911 * info should be updated so a PNG file could be written with it, 1912 * assuming the transformations result in valid PNG data. 1913 */ 1914void /* PRIVATE */ 1915png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) 1916{ 1917 png_debug(1, "in png_read_transform_info"); 1918 1919#ifdef PNG_READ_EXPAND_SUPPORTED 1920 if (png_ptr->transformations & PNG_EXPAND) 1921 { 1922 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1923 { 1924 /* This check must match what actually happens in 1925 * png_do_expand_palette; if it ever checks the tRNS chunk to see if 1926 * it is all opaque we must do the same (at present it does not.) 1927 */ 1928 if (png_ptr->num_trans > 0) 1929 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 1930 1931 else 1932 info_ptr->color_type = PNG_COLOR_TYPE_RGB; 1933 1934 info_ptr->bit_depth = 8; 1935 info_ptr->num_trans = 0; 1936 } 1937 else 1938 { 1939 if (png_ptr->num_trans) 1940 { 1941 if (png_ptr->transformations & PNG_EXPAND_tRNS) 1942 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 1943 } 1944 if (info_ptr->bit_depth < 8) 1945 info_ptr->bit_depth = 8; 1946 1947 info_ptr->num_trans = 0; 1948 } 1949 } 1950#endif 1951 1952#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 1953 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 1954 /* The following is almost certainly wrong unless the background value is in 1955 * the screen space! 1956 */ 1957 if (png_ptr->transformations & PNG_COMPOSE) 1958 info_ptr->background = png_ptr->background; 1959#endif 1960 1961#ifdef PNG_READ_GAMMA_SUPPORTED 1962 /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), 1963 * however it seems that the code in png_init_read_transformations, which has 1964 * been called before this from png_read_update_info->png_read_start_row 1965 * sometimes does the gamma transform and cancels the flag. 1966 * 1967 * TODO: this looks wrong; the info_ptr should end up with a gamma equal to 1968 * the screen_gamma value. The following probably results in weirdness if 1969 * the info_ptr is used by the app after the rows have been read. 1970 */ 1971 info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; 1972#endif 1973 1974 if (info_ptr->bit_depth == 16) 1975 { 1976# ifdef PNG_READ_16BIT_SUPPORTED 1977# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 1978 if (png_ptr->transformations & PNG_SCALE_16_TO_8) 1979 info_ptr->bit_depth = 8; 1980# endif 1981 1982# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 1983 if (png_ptr->transformations & PNG_16_TO_8) 1984 info_ptr->bit_depth = 8; 1985# endif 1986 1987# else 1988 /* No 16 bit support: force chopping 16-bit input down to 8, in this case 1989 * the app program can chose if both APIs are available by setting the 1990 * correct scaling to use. 1991 */ 1992# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 1993 /* For compatibility with previous versions use the strip method by 1994 * default. This code works because if PNG_SCALE_16_TO_8 is already 1995 * set the code below will do that in preference to the chop. 1996 */ 1997 png_ptr->transformations |= PNG_16_TO_8; 1998 info_ptr->bit_depth = 8; 1999# else 2000 2001# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 2002 png_ptr->transformations |= PNG_SCALE_16_TO_8; 2003 info_ptr->bit_depth = 8; 2004# else 2005 2006 CONFIGURATION ERROR: you must enable at least one 16 to 8 method 2007# endif 2008# endif 2009#endif /* !READ_16BIT_SUPPORTED */ 2010 } 2011 2012#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 2013 if (png_ptr->transformations & PNG_GRAY_TO_RGB) 2014 info_ptr->color_type = (png_byte)(info_ptr->color_type | 2015 PNG_COLOR_MASK_COLOR); 2016#endif 2017 2018#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2019 if (png_ptr->transformations & PNG_RGB_TO_GRAY) 2020 info_ptr->color_type = (png_byte)(info_ptr->color_type & 2021 ~PNG_COLOR_MASK_COLOR); 2022#endif 2023 2024#ifdef PNG_READ_QUANTIZE_SUPPORTED 2025 if (png_ptr->transformations & PNG_QUANTIZE) 2026 { 2027 if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || 2028 (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && 2029 png_ptr->palette_lookup && info_ptr->bit_depth == 8) 2030 { 2031 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; 2032 } 2033 } 2034#endif 2035 2036#ifdef PNG_READ_EXPAND_16_SUPPORTED 2037 if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && 2038 info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 2039 { 2040 info_ptr->bit_depth = 16; 2041 } 2042#endif 2043 2044#ifdef PNG_READ_PACK_SUPPORTED 2045 if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) 2046 info_ptr->bit_depth = 8; 2047#endif 2048 2049 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 2050 info_ptr->channels = 1; 2051 2052 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) 2053 info_ptr->channels = 3; 2054 2055 else 2056 info_ptr->channels = 1; 2057 2058#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 2059 if (png_ptr->transformations & PNG_STRIP_ALPHA) 2060 { 2061 info_ptr->color_type = (png_byte)(info_ptr->color_type & 2062 ~PNG_COLOR_MASK_ALPHA); 2063 info_ptr->num_trans = 0; 2064 } 2065#endif 2066 2067 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) 2068 info_ptr->channels++; 2069 2070#ifdef PNG_READ_FILLER_SUPPORTED 2071 /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ 2072 if ((png_ptr->transformations & PNG_FILLER) && 2073 ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || 2074 (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) 2075 { 2076 info_ptr->channels++; 2077 /* If adding a true alpha channel not just filler */ 2078 if (png_ptr->transformations & PNG_ADD_ALPHA) 2079 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; 2080 } 2081#endif 2082 2083#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ 2084defined(PNG_READ_USER_TRANSFORM_SUPPORTED) 2085 if (png_ptr->transformations & PNG_USER_TRANSFORM) 2086 { 2087 if (info_ptr->bit_depth < png_ptr->user_transform_depth) 2088 info_ptr->bit_depth = png_ptr->user_transform_depth; 2089 2090 if (info_ptr->channels < png_ptr->user_transform_channels) 2091 info_ptr->channels = png_ptr->user_transform_channels; 2092 } 2093#endif 2094 2095 info_ptr->pixel_depth = (png_byte)(info_ptr->channels * 2096 info_ptr->bit_depth); 2097 2098 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); 2099 2100 /* Adding in 1.5.4: cache the above value in png_struct so that we can later 2101 * check in png_rowbytes that the user buffer won't get overwritten. Note 2102 * that the field is not always set - if png_read_update_info isn't called 2103 * the application has to either not do any transforms or get the calculation 2104 * right itself. 2105 */ 2106 png_ptr->info_rowbytes = info_ptr->rowbytes; 2107 2108#ifndef PNG_READ_EXPAND_SUPPORTED 2109 if (png_ptr) 2110 return; 2111#endif 2112} 2113 2114/* Transform the row. The order of transformations is significant, 2115 * and is very touchy. If you add a transformation, take care to 2116 * decide how it fits in with the other transformations here. 2117 */ 2118void /* PRIVATE */ 2119png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) 2120{ 2121 png_debug(1, "in png_do_read_transformations"); 2122 2123 if (png_ptr->row_buf == NULL) 2124 { 2125 /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this 2126 * error is incredibly rare and incredibly easy to debug without this 2127 * information. 2128 */ 2129 png_error(png_ptr, "NULL row buffer"); 2130 } 2131 2132 /* The following is debugging; prior to 1.5.4 the code was never compiled in; 2133 * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro 2134 * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for 2135 * all transformations, however in practice the ROW_INIT always gets done on 2136 * demand, if necessary. 2137 */ 2138 if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && 2139 !(png_ptr->flags & PNG_FLAG_ROW_INIT)) 2140 { 2141 /* Application has failed to call either png_read_start_image() or 2142 * png_read_update_info() after setting transforms that expand pixels. 2143 * This check added to libpng-1.2.19 (but not enabled until 1.5.4). 2144 */ 2145 png_error(png_ptr, "Uninitialized row"); 2146 } 2147 2148#ifdef PNG_READ_EXPAND_SUPPORTED 2149 if (png_ptr->transformations & PNG_EXPAND) 2150 { 2151 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 2152 { 2153 png_do_expand_palette(row_info, png_ptr->row_buf + 1, 2154 png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); 2155 } 2156 2157 else 2158 { 2159 if (png_ptr->num_trans && 2160 (png_ptr->transformations & PNG_EXPAND_tRNS)) 2161 png_do_expand(row_info, png_ptr->row_buf + 1, 2162 &(png_ptr->trans_color)); 2163 2164 else 2165 png_do_expand(row_info, png_ptr->row_buf + 1, 2166 NULL); 2167 } 2168 } 2169#endif 2170 2171#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 2172 if ((png_ptr->transformations & PNG_STRIP_ALPHA) && 2173 !(png_ptr->transformations & PNG_COMPOSE) && 2174 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 2175 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 2176 png_do_strip_channel(row_info, png_ptr->row_buf + 1, 2177 0 /* at_start == false, because SWAP_ALPHA happens later */); 2178#endif 2179 2180#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2181 if (png_ptr->transformations & PNG_RGB_TO_GRAY) 2182 { 2183 int rgb_error = 2184 png_do_rgb_to_gray(png_ptr, row_info, 2185 png_ptr->row_buf + 1); 2186 2187 if (rgb_error) 2188 { 2189 png_ptr->rgb_to_gray_status=1; 2190 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 2191 PNG_RGB_TO_GRAY_WARN) 2192 png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 2193 2194 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 2195 PNG_RGB_TO_GRAY_ERR) 2196 png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 2197 } 2198 } 2199#endif 2200 2201/* From Andreas Dilger e-mail to png-implement, 26 March 1998: 2202 * 2203 * In most cases, the "simple transparency" should be done prior to doing 2204 * gray-to-RGB, or you will have to test 3x as many bytes to check if a 2205 * pixel is transparent. You would also need to make sure that the 2206 * transparency information is upgraded to RGB. 2207 * 2208 * To summarize, the current flow is: 2209 * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite 2210 * with background "in place" if transparent, 2211 * convert to RGB if necessary 2212 * - Gray + alpha -> composite with gray background and remove alpha bytes, 2213 * convert to RGB if necessary 2214 * 2215 * To support RGB backgrounds for gray images we need: 2216 * - Gray + simple transparency -> convert to RGB + simple transparency, 2217 * compare 3 or 6 bytes and composite with 2218 * background "in place" if transparent 2219 * (3x compare/pixel compared to doing 2220 * composite with gray bkgrnd) 2221 * - Gray + alpha -> convert to RGB + alpha, composite with background and 2222 * remove alpha bytes (3x float 2223 * operations/pixel compared with composite 2224 * on gray background) 2225 * 2226 * Greg's change will do this. The reason it wasn't done before is for 2227 * performance, as this increases the per-pixel operations. If we would check 2228 * in advance if the background was gray or RGB, and position the gray-to-RGB 2229 * transform appropriately, then it would save a lot of work/time. 2230 */ 2231 2232#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 2233 /* If gray -> RGB, do so now only if background is non-gray; else do later 2234 * for performance reasons 2235 */ 2236 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && 2237 !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) 2238 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 2239#endif 2240 2241#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 2242 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 2243 if (png_ptr->transformations & PNG_COMPOSE) 2244 png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); 2245#endif 2246 2247#ifdef PNG_READ_GAMMA_SUPPORTED 2248 if ((png_ptr->transformations & PNG_GAMMA) && 2249#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2250 /* Because RGB_TO_GRAY does the gamma transform. */ 2251 !(png_ptr->transformations & PNG_RGB_TO_GRAY) && 2252#endif 2253#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 2254 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 2255 /* Because PNG_COMPOSE does the gamma transform if there is something to 2256 * do (if there is an alpha channel or transparency.) 2257 */ 2258 !((png_ptr->transformations & PNG_COMPOSE) && 2259 ((png_ptr->num_trans != 0) || 2260 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && 2261#endif 2262 /* Because png_init_read_transformations transforms the palette, unless 2263 * RGB_TO_GRAY will do the transform. 2264 */ 2265 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) 2266 png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); 2267#endif 2268 2269#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 2270 if ((png_ptr->transformations & PNG_STRIP_ALPHA) && 2271 (png_ptr->transformations & PNG_COMPOSE) && 2272 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 2273 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 2274 png_do_strip_channel(row_info, png_ptr->row_buf + 1, 2275 0 /* at_start == false, because SWAP_ALPHA happens later */); 2276#endif 2277 2278#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 2279 if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && 2280 (row_info->color_type & PNG_COLOR_MASK_ALPHA)) 2281 png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); 2282#endif 2283 2284#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 2285 if (png_ptr->transformations & PNG_SCALE_16_TO_8) 2286 png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); 2287#endif 2288 2289#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 2290 /* There is no harm in doing both of these because only one has any effect, 2291 * by putting the 'scale' option first if the app asks for scale (either by 2292 * calling the API or in a TRANSFORM flag) this is what happens. 2293 */ 2294 if (png_ptr->transformations & PNG_16_TO_8) 2295 png_do_chop(row_info, png_ptr->row_buf + 1); 2296#endif 2297 2298#ifdef PNG_READ_QUANTIZE_SUPPORTED 2299 if (png_ptr->transformations & PNG_QUANTIZE) 2300 { 2301 png_do_quantize(row_info, png_ptr->row_buf + 1, 2302 png_ptr->palette_lookup, png_ptr->quantize_index); 2303 2304 if (row_info->rowbytes == 0) 2305 png_error(png_ptr, "png_do_quantize returned rowbytes=0"); 2306 } 2307#endif /* PNG_READ_QUANTIZE_SUPPORTED */ 2308 2309#ifdef PNG_READ_EXPAND_16_SUPPORTED 2310 /* Do the expansion now, after all the arithmetic has been done. Notice 2311 * that previous transformations can handle the PNG_EXPAND_16 flag if this 2312 * is efficient (particularly true in the case of gamma correction, where 2313 * better accuracy results faster!) 2314 */ 2315 if (png_ptr->transformations & PNG_EXPAND_16) 2316 png_do_expand_16(row_info, png_ptr->row_buf + 1); 2317#endif 2318 2319#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 2320 /* NOTE: moved here in 1.5.4 (from much later in this list.) */ 2321 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && 2322 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) 2323 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 2324#endif 2325 2326#ifdef PNG_READ_INVERT_SUPPORTED 2327 if (png_ptr->transformations & PNG_INVERT_MONO) 2328 png_do_invert(row_info, png_ptr->row_buf + 1); 2329#endif 2330 2331#ifdef PNG_READ_SHIFT_SUPPORTED 2332 if (png_ptr->transformations & PNG_SHIFT) 2333 png_do_unshift(row_info, png_ptr->row_buf + 1, 2334 &(png_ptr->shift)); 2335#endif 2336 2337#ifdef PNG_READ_PACK_SUPPORTED 2338 if (png_ptr->transformations & PNG_PACK) 2339 png_do_unpack(row_info, png_ptr->row_buf + 1); 2340#endif 2341 2342#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 2343 /* Added at libpng-1.5.10 */ 2344 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 2345 png_ptr->num_palette_max >= 0) 2346 png_do_check_palette_indexes(png_ptr, row_info); 2347#endif 2348 2349#ifdef PNG_READ_BGR_SUPPORTED 2350 if (png_ptr->transformations & PNG_BGR) 2351 png_do_bgr(row_info, png_ptr->row_buf + 1); 2352#endif 2353 2354#ifdef PNG_READ_PACKSWAP_SUPPORTED 2355 if (png_ptr->transformations & PNG_PACKSWAP) 2356 png_do_packswap(row_info, png_ptr->row_buf + 1); 2357#endif 2358 2359#ifdef PNG_READ_FILLER_SUPPORTED 2360 if (png_ptr->transformations & PNG_FILLER) 2361 png_do_read_filler(row_info, png_ptr->row_buf + 1, 2362 (png_uint_32)png_ptr->filler, png_ptr->flags); 2363#endif 2364 2365#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 2366 if (png_ptr->transformations & PNG_INVERT_ALPHA) 2367 png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); 2368#endif 2369 2370#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 2371 if (png_ptr->transformations & PNG_SWAP_ALPHA) 2372 png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); 2373#endif 2374 2375#ifdef PNG_READ_16BIT_SUPPORTED 2376#ifdef PNG_READ_SWAP_SUPPORTED 2377 if (png_ptr->transformations & PNG_SWAP_BYTES) 2378 png_do_swap(row_info, png_ptr->row_buf + 1); 2379#endif 2380#endif 2381 2382#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 2383 if (png_ptr->transformations & PNG_USER_TRANSFORM) 2384 { 2385 if (png_ptr->read_user_transform_fn != NULL) 2386 (*(png_ptr->read_user_transform_fn)) /* User read transform function */ 2387 (png_ptr, /* png_ptr */ 2388 row_info, /* row_info: */ 2389 /* png_uint_32 width; width of row */ 2390 /* png_size_t rowbytes; number of bytes in row */ 2391 /* png_byte color_type; color type of pixels */ 2392 /* png_byte bit_depth; bit depth of samples */ 2393 /* png_byte channels; number of channels (1-4) */ 2394 /* png_byte pixel_depth; bits per pixel (depth*channels) */ 2395 png_ptr->row_buf + 1); /* start of pixel data for row */ 2396#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED 2397 if (png_ptr->user_transform_depth) 2398 row_info->bit_depth = png_ptr->user_transform_depth; 2399 2400 if (png_ptr->user_transform_channels) 2401 row_info->channels = png_ptr->user_transform_channels; 2402#endif 2403 row_info->pixel_depth = (png_byte)(row_info->bit_depth * 2404 row_info->channels); 2405 2406 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); 2407 } 2408#endif 2409} 2410 2411#ifdef PNG_READ_PACK_SUPPORTED 2412/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, 2413 * without changing the actual values. Thus, if you had a row with 2414 * a bit depth of 1, you would end up with bytes that only contained 2415 * the numbers 0 or 1. If you would rather they contain 0 and 255, use 2416 * png_do_shift() after this. 2417 */ 2418void /* PRIVATE */ 2419png_do_unpack(png_row_infop row_info, png_bytep row) 2420{ 2421 png_debug(1, "in png_do_unpack"); 2422 2423 if (row_info->bit_depth < 8) 2424 { 2425 png_uint_32 i; 2426 png_uint_32 row_width=row_info->width; 2427 2428 switch (row_info->bit_depth) 2429 { 2430 case 1: 2431 { 2432 png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); 2433 png_bytep dp = row + (png_size_t)row_width - 1; 2434 png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); 2435 for (i = 0; i < row_width; i++) 2436 { 2437 *dp = (png_byte)((*sp >> shift) & 0x01); 2438 2439 if (shift == 7) 2440 { 2441 shift = 0; 2442 sp--; 2443 } 2444 2445 else 2446 shift++; 2447 2448 dp--; 2449 } 2450 break; 2451 } 2452 2453 case 2: 2454 { 2455 2456 png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); 2457 png_bytep dp = row + (png_size_t)row_width - 1; 2458 png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 2459 for (i = 0; i < row_width; i++) 2460 { 2461 *dp = (png_byte)((*sp >> shift) & 0x03); 2462 2463 if (shift == 6) 2464 { 2465 shift = 0; 2466 sp--; 2467 } 2468 2469 else 2470 shift += 2; 2471 2472 dp--; 2473 } 2474 break; 2475 } 2476 2477 case 4: 2478 { 2479 png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); 2480 png_bytep dp = row + (png_size_t)row_width - 1; 2481 png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 2482 for (i = 0; i < row_width; i++) 2483 { 2484 *dp = (png_byte)((*sp >> shift) & 0x0f); 2485 2486 if (shift == 4) 2487 { 2488 shift = 0; 2489 sp--; 2490 } 2491 2492 else 2493 shift = 4; 2494 2495 dp--; 2496 } 2497 break; 2498 } 2499 2500 default: 2501 break; 2502 } 2503 row_info->bit_depth = 8; 2504 row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2505 row_info->rowbytes = row_width * row_info->channels; 2506 } 2507} 2508#endif 2509 2510#ifdef PNG_READ_SHIFT_SUPPORTED 2511/* Reverse the effects of png_do_shift. This routine merely shifts the 2512 * pixels back to their significant bits values. Thus, if you have 2513 * a row of bit depth 8, but only 5 are significant, this will shift 2514 * the values back to 0 through 31. 2515 */ 2516void /* PRIVATE */ 2517png_do_unshift(png_row_infop row_info, png_bytep row, 2518 png_const_color_8p sig_bits) 2519{ 2520 int color_type; 2521 2522 png_debug(1, "in png_do_unshift"); 2523 2524 /* The palette case has already been handled in the _init routine. */ 2525 color_type = row_info->color_type; 2526 2527 if (color_type != PNG_COLOR_TYPE_PALETTE) 2528 { 2529 int shift[4]; 2530 int channels = 0; 2531 int bit_depth = row_info->bit_depth; 2532 2533 if (color_type & PNG_COLOR_MASK_COLOR) 2534 { 2535 shift[channels++] = bit_depth - sig_bits->red; 2536 shift[channels++] = bit_depth - sig_bits->green; 2537 shift[channels++] = bit_depth - sig_bits->blue; 2538 } 2539 2540 else 2541 { 2542 shift[channels++] = bit_depth - sig_bits->gray; 2543 } 2544 2545 if (color_type & PNG_COLOR_MASK_ALPHA) 2546 { 2547 shift[channels++] = bit_depth - sig_bits->alpha; 2548 } 2549 2550 { 2551 int c, have_shift; 2552 2553 for (c = have_shift = 0; c < channels; ++c) 2554 { 2555 /* A shift of more than the bit depth is an error condition but it 2556 * gets ignored here. 2557 */ 2558 if (shift[c] <= 0 || shift[c] >= bit_depth) 2559 shift[c] = 0; 2560 2561 else 2562 have_shift = 1; 2563 } 2564 2565 if (!have_shift) 2566 return; 2567 } 2568 2569 switch (bit_depth) 2570 { 2571 default: 2572 /* Must be 1bpp gray: should not be here! */ 2573 /* NOTREACHED */ 2574 break; 2575 2576 case 2: 2577 /* Must be 2bpp gray */ 2578 /* assert(channels == 1 && shift[0] == 1) */ 2579 { 2580 png_bytep bp = row; 2581 png_bytep bp_end = bp + row_info->rowbytes; 2582 2583 while (bp < bp_end) 2584 { 2585 int b = (*bp >> 1) & 0x55; 2586 *bp++ = (png_byte)b; 2587 } 2588 break; 2589 } 2590 2591 case 4: 2592 /* Must be 4bpp gray */ 2593 /* assert(channels == 1) */ 2594 { 2595 png_bytep bp = row; 2596 png_bytep bp_end = bp + row_info->rowbytes; 2597 int gray_shift = shift[0]; 2598 int mask = 0xf >> gray_shift; 2599 2600 mask |= mask << 4; 2601 2602 while (bp < bp_end) 2603 { 2604 int b = (*bp >> gray_shift) & mask; 2605 *bp++ = (png_byte)b; 2606 } 2607 break; 2608 } 2609 2610 case 8: 2611 /* Single byte components, G, GA, RGB, RGBA */ 2612 { 2613 png_bytep bp = row; 2614 png_bytep bp_end = bp + row_info->rowbytes; 2615 int channel = 0; 2616 2617 while (bp < bp_end) 2618 { 2619 int b = *bp >> shift[channel]; 2620 if (++channel >= channels) 2621 channel = 0; 2622 *bp++ = (png_byte)b; 2623 } 2624 break; 2625 } 2626 2627#ifdef PNG_READ_16BIT_SUPPORTED 2628 case 16: 2629 /* Double byte components, G, GA, RGB, RGBA */ 2630 { 2631 png_bytep bp = row; 2632 png_bytep bp_end = bp + row_info->rowbytes; 2633 int channel = 0; 2634 2635 while (bp < bp_end) 2636 { 2637 int value = (bp[0] << 8) + bp[1]; 2638 2639 value >>= shift[channel]; 2640 if (++channel >= channels) 2641 channel = 0; 2642 *bp++ = (png_byte)(value >> 8); 2643 *bp++ = (png_byte)(value & 0xff); 2644 } 2645 break; 2646 } 2647#endif 2648 } 2649 } 2650} 2651#endif 2652 2653#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 2654/* Scale rows of bit depth 16 down to 8 accurately */ 2655void /* PRIVATE */ 2656png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) 2657{ 2658 png_debug(1, "in png_do_scale_16_to_8"); 2659 2660 if (row_info->bit_depth == 16) 2661 { 2662 png_bytep sp = row; /* source */ 2663 png_bytep dp = row; /* destination */ 2664 png_bytep ep = sp + row_info->rowbytes; /* end+1 */ 2665 2666 while (sp < ep) 2667 { 2668 /* The input is an array of 16 bit components, these must be scaled to 2669 * 8 bits each. For a 16 bit value V the required value (from the PNG 2670 * specification) is: 2671 * 2672 * (V * 255) / 65535 2673 * 2674 * This reduces to round(V / 257), or floor((V + 128.5)/257) 2675 * 2676 * Represent V as the two byte value vhi.vlo. Make a guess that the 2677 * result is the top byte of V, vhi, then the correction to this value 2678 * is: 2679 * 2680 * error = floor(((V-vhi.vhi) + 128.5) / 257) 2681 * = floor(((vlo-vhi) + 128.5) / 257) 2682 * 2683 * This can be approximated using integer arithmetic (and a signed 2684 * shift): 2685 * 2686 * error = (vlo-vhi+128) >> 8; 2687 * 2688 * The approximate differs from the exact answer only when (vlo-vhi) is 2689 * 128; it then gives a correction of +1 when the exact correction is 2690 * 0. This gives 128 errors. The exact answer (correct for all 16 bit 2691 * input values) is: 2692 * 2693 * error = (vlo-vhi+128)*65535 >> 24; 2694 * 2695 * An alternative arithmetic calculation which also gives no errors is: 2696 * 2697 * (V * 255 + 32895) >> 16 2698 */ 2699 2700 png_int_32 tmp = *sp++; /* must be signed! */ 2701 tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; 2702 *dp++ = (png_byte)tmp; 2703 } 2704 2705 row_info->bit_depth = 8; 2706 row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2707 row_info->rowbytes = row_info->width * row_info->channels; 2708 } 2709} 2710#endif 2711 2712#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 2713void /* PRIVATE */ 2714/* Simply discard the low byte. This was the default behavior prior 2715 * to libpng-1.5.4. 2716 */ 2717png_do_chop(png_row_infop row_info, png_bytep row) 2718{ 2719 png_debug(1, "in png_do_chop"); 2720 2721 if (row_info->bit_depth == 16) 2722 { 2723 png_bytep sp = row; /* source */ 2724 png_bytep dp = row; /* destination */ 2725 png_bytep ep = sp + row_info->rowbytes; /* end+1 */ 2726 2727 while (sp < ep) 2728 { 2729 *dp++ = *sp; 2730 sp += 2; /* skip low byte */ 2731 } 2732 2733 row_info->bit_depth = 8; 2734 row_info->pixel_depth = (png_byte)(8 * row_info->channels); 2735 row_info->rowbytes = row_info->width * row_info->channels; 2736 } 2737} 2738#endif 2739 2740#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 2741void /* PRIVATE */ 2742png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) 2743{ 2744 png_debug(1, "in png_do_read_swap_alpha"); 2745 2746 { 2747 png_uint_32 row_width = row_info->width; 2748 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 2749 { 2750 /* This converts from RGBA to ARGB */ 2751 if (row_info->bit_depth == 8) 2752 { 2753 png_bytep sp = row + row_info->rowbytes; 2754 png_bytep dp = sp; 2755 png_byte save; 2756 png_uint_32 i; 2757 2758 for (i = 0; i < row_width; i++) 2759 { 2760 save = *(--sp); 2761 *(--dp) = *(--sp); 2762 *(--dp) = *(--sp); 2763 *(--dp) = *(--sp); 2764 *(--dp) = save; 2765 } 2766 } 2767 2768#ifdef PNG_READ_16BIT_SUPPORTED 2769 /* This converts from RRGGBBAA to AARRGGBB */ 2770 else 2771 { 2772 png_bytep sp = row + row_info->rowbytes; 2773 png_bytep dp = sp; 2774 png_byte save[2]; 2775 png_uint_32 i; 2776 2777 for (i = 0; i < row_width; i++) 2778 { 2779 save[0] = *(--sp); 2780 save[1] = *(--sp); 2781 *(--dp) = *(--sp); 2782 *(--dp) = *(--sp); 2783 *(--dp) = *(--sp); 2784 *(--dp) = *(--sp); 2785 *(--dp) = *(--sp); 2786 *(--dp) = *(--sp); 2787 *(--dp) = save[0]; 2788 *(--dp) = save[1]; 2789 } 2790 } 2791#endif 2792 } 2793 2794 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2795 { 2796 /* This converts from GA to AG */ 2797 if (row_info->bit_depth == 8) 2798 { 2799 png_bytep sp = row + row_info->rowbytes; 2800 png_bytep dp = sp; 2801 png_byte save; 2802 png_uint_32 i; 2803 2804 for (i = 0; i < row_width; i++) 2805 { 2806 save = *(--sp); 2807 *(--dp) = *(--sp); 2808 *(--dp) = save; 2809 } 2810 } 2811 2812#ifdef PNG_READ_16BIT_SUPPORTED 2813 /* This converts from GGAA to AAGG */ 2814 else 2815 { 2816 png_bytep sp = row + row_info->rowbytes; 2817 png_bytep dp = sp; 2818 png_byte save[2]; 2819 png_uint_32 i; 2820 2821 for (i = 0; i < row_width; i++) 2822 { 2823 save[0] = *(--sp); 2824 save[1] = *(--sp); 2825 *(--dp) = *(--sp); 2826 *(--dp) = *(--sp); 2827 *(--dp) = save[0]; 2828 *(--dp) = save[1]; 2829 } 2830 } 2831#endif 2832 } 2833 } 2834} 2835#endif 2836 2837#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 2838void /* PRIVATE */ 2839png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) 2840{ 2841 png_uint_32 row_width; 2842 png_debug(1, "in png_do_read_invert_alpha"); 2843 2844 row_width = row_info->width; 2845 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 2846 { 2847 if (row_info->bit_depth == 8) 2848 { 2849 /* This inverts the alpha channel in RGBA */ 2850 png_bytep sp = row + row_info->rowbytes; 2851 png_bytep dp = sp; 2852 png_uint_32 i; 2853 2854 for (i = 0; i < row_width; i++) 2855 { 2856 *(--dp) = (png_byte)(255 - *(--sp)); 2857 2858/* This does nothing: 2859 *(--dp) = *(--sp); 2860 *(--dp) = *(--sp); 2861 *(--dp) = *(--sp); 2862 We can replace it with: 2863*/ 2864 sp-=3; 2865 dp=sp; 2866 } 2867 } 2868 2869#ifdef PNG_READ_16BIT_SUPPORTED 2870 /* This inverts the alpha channel in RRGGBBAA */ 2871 else 2872 { 2873 png_bytep sp = row + row_info->rowbytes; 2874 png_bytep dp = sp; 2875 png_uint_32 i; 2876 2877 for (i = 0; i < row_width; i++) 2878 { 2879 *(--dp) = (png_byte)(255 - *(--sp)); 2880 *(--dp) = (png_byte)(255 - *(--sp)); 2881 2882/* This does nothing: 2883 *(--dp) = *(--sp); 2884 *(--dp) = *(--sp); 2885 *(--dp) = *(--sp); 2886 *(--dp) = *(--sp); 2887 *(--dp) = *(--sp); 2888 *(--dp) = *(--sp); 2889 We can replace it with: 2890*/ 2891 sp-=6; 2892 dp=sp; 2893 } 2894 } 2895#endif 2896 } 2897 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2898 { 2899 if (row_info->bit_depth == 8) 2900 { 2901 /* This inverts the alpha channel in GA */ 2902 png_bytep sp = row + row_info->rowbytes; 2903 png_bytep dp = sp; 2904 png_uint_32 i; 2905 2906 for (i = 0; i < row_width; i++) 2907 { 2908 *(--dp) = (png_byte)(255 - *(--sp)); 2909 *(--dp) = *(--sp); 2910 } 2911 } 2912 2913#ifdef PNG_READ_16BIT_SUPPORTED 2914 else 2915 { 2916 /* This inverts the alpha channel in GGAA */ 2917 png_bytep sp = row + row_info->rowbytes; 2918 png_bytep dp = sp; 2919 png_uint_32 i; 2920 2921 for (i = 0; i < row_width; i++) 2922 { 2923 *(--dp) = (png_byte)(255 - *(--sp)); 2924 *(--dp) = (png_byte)(255 - *(--sp)); 2925/* 2926 *(--dp) = *(--sp); 2927 *(--dp) = *(--sp); 2928*/ 2929 sp-=2; 2930 dp=sp; 2931 } 2932 } 2933#endif 2934 } 2935} 2936#endif 2937 2938#ifdef PNG_READ_FILLER_SUPPORTED 2939/* Add filler channel if we have RGB color */ 2940void /* PRIVATE */ 2941png_do_read_filler(png_row_infop row_info, png_bytep row, 2942 png_uint_32 filler, png_uint_32 flags) 2943{ 2944 png_uint_32 i; 2945 png_uint_32 row_width = row_info->width; 2946 2947#ifdef PNG_READ_16BIT_SUPPORTED 2948 png_byte hi_filler = (png_byte)((filler>>8) & 0xff); 2949#endif 2950 png_byte lo_filler = (png_byte)(filler & 0xff); 2951 2952 png_debug(1, "in png_do_read_filler"); 2953 2954 if ( 2955 row_info->color_type == PNG_COLOR_TYPE_GRAY) 2956 { 2957 if (row_info->bit_depth == 8) 2958 { 2959 if (flags & PNG_FLAG_FILLER_AFTER) 2960 { 2961 /* This changes the data from G to GX */ 2962 png_bytep sp = row + (png_size_t)row_width; 2963 png_bytep dp = sp + (png_size_t)row_width; 2964 for (i = 1; i < row_width; i++) 2965 { 2966 *(--dp) = lo_filler; 2967 *(--dp) = *(--sp); 2968 } 2969 *(--dp) = lo_filler; 2970 row_info->channels = 2; 2971 row_info->pixel_depth = 16; 2972 row_info->rowbytes = row_width * 2; 2973 } 2974 2975 else 2976 { 2977 /* This changes the data from G to XG */ 2978 png_bytep sp = row + (png_size_t)row_width; 2979 png_bytep dp = sp + (png_size_t)row_width; 2980 for (i = 0; i < row_width; i++) 2981 { 2982 *(--dp) = *(--sp); 2983 *(--dp) = lo_filler; 2984 } 2985 row_info->channels = 2; 2986 row_info->pixel_depth = 16; 2987 row_info->rowbytes = row_width * 2; 2988 } 2989 } 2990 2991#ifdef PNG_READ_16BIT_SUPPORTED 2992 else if (row_info->bit_depth == 16) 2993 { 2994 if (flags & PNG_FLAG_FILLER_AFTER) 2995 { 2996 /* This changes the data from GG to GGXX */ 2997 png_bytep sp = row + (png_size_t)row_width * 2; 2998 png_bytep dp = sp + (png_size_t)row_width * 2; 2999 for (i = 1; i < row_width; i++) 3000 { 3001 *(--dp) = hi_filler; 3002 *(--dp) = lo_filler; 3003 *(--dp) = *(--sp); 3004 *(--dp) = *(--sp); 3005 } 3006 *(--dp) = hi_filler; 3007 *(--dp) = lo_filler; 3008 row_info->channels = 2; 3009 row_info->pixel_depth = 32; 3010 row_info->rowbytes = row_width * 4; 3011 } 3012 3013 else 3014 { 3015 /* This changes the data from GG to XXGG */ 3016 png_bytep sp = row + (png_size_t)row_width * 2; 3017 png_bytep dp = sp + (png_size_t)row_width * 2; 3018 for (i = 0; i < row_width; i++) 3019 { 3020 *(--dp) = *(--sp); 3021 *(--dp) = *(--sp); 3022 *(--dp) = hi_filler; 3023 *(--dp) = lo_filler; 3024 } 3025 row_info->channels = 2; 3026 row_info->pixel_depth = 32; 3027 row_info->rowbytes = row_width * 4; 3028 } 3029 } 3030#endif 3031 } /* COLOR_TYPE == GRAY */ 3032 else if (row_info->color_type == PNG_COLOR_TYPE_RGB) 3033 { 3034 if (row_info->bit_depth == 8) 3035 { 3036 if (flags & PNG_FLAG_FILLER_AFTER) 3037 { 3038 /* This changes the data from RGB to RGBX */ 3039 png_bytep sp = row + (png_size_t)row_width * 3; 3040 png_bytep dp = sp + (png_size_t)row_width; 3041 for (i = 1; i < row_width; i++) 3042 { 3043 *(--dp) = lo_filler; 3044 *(--dp) = *(--sp); 3045 *(--dp) = *(--sp); 3046 *(--dp) = *(--sp); 3047 } 3048 *(--dp) = lo_filler; 3049 row_info->channels = 4; 3050 row_info->pixel_depth = 32; 3051 row_info->rowbytes = row_width * 4; 3052 } 3053 3054 else 3055 { 3056 /* This changes the data from RGB to XRGB */ 3057 png_bytep sp = row + (png_size_t)row_width * 3; 3058 png_bytep dp = sp + (png_size_t)row_width; 3059 for (i = 0; i < row_width; i++) 3060 { 3061 *(--dp) = *(--sp); 3062 *(--dp) = *(--sp); 3063 *(--dp) = *(--sp); 3064 *(--dp) = lo_filler; 3065 } 3066 row_info->channels = 4; 3067 row_info->pixel_depth = 32; 3068 row_info->rowbytes = row_width * 4; 3069 } 3070 } 3071 3072#ifdef PNG_READ_16BIT_SUPPORTED 3073 else if (row_info->bit_depth == 16) 3074 { 3075 if (flags & PNG_FLAG_FILLER_AFTER) 3076 { 3077 /* This changes the data from RRGGBB to RRGGBBXX */ 3078 png_bytep sp = row + (png_size_t)row_width * 6; 3079 png_bytep dp = sp + (png_size_t)row_width * 2; 3080 for (i = 1; i < row_width; i++) 3081 { 3082 *(--dp) = hi_filler; 3083 *(--dp) = lo_filler; 3084 *(--dp) = *(--sp); 3085 *(--dp) = *(--sp); 3086 *(--dp) = *(--sp); 3087 *(--dp) = *(--sp); 3088 *(--dp) = *(--sp); 3089 *(--dp) = *(--sp); 3090 } 3091 *(--dp) = hi_filler; 3092 *(--dp) = lo_filler; 3093 row_info->channels = 4; 3094 row_info->pixel_depth = 64; 3095 row_info->rowbytes = row_width * 8; 3096 } 3097 3098 else 3099 { 3100 /* This changes the data from RRGGBB to XXRRGGBB */ 3101 png_bytep sp = row + (png_size_t)row_width * 6; 3102 png_bytep dp = sp + (png_size_t)row_width * 2; 3103 for (i = 0; i < row_width; i++) 3104 { 3105 *(--dp) = *(--sp); 3106 *(--dp) = *(--sp); 3107 *(--dp) = *(--sp); 3108 *(--dp) = *(--sp); 3109 *(--dp) = *(--sp); 3110 *(--dp) = *(--sp); 3111 *(--dp) = hi_filler; 3112 *(--dp) = lo_filler; 3113 } 3114 3115 row_info->channels = 4; 3116 row_info->pixel_depth = 64; 3117 row_info->rowbytes = row_width * 8; 3118 } 3119 } 3120#endif 3121 } /* COLOR_TYPE == RGB */ 3122} 3123#endif 3124 3125#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 3126/* Expand grayscale files to RGB, with or without alpha */ 3127void /* PRIVATE */ 3128png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) 3129{ 3130 png_uint_32 i; 3131 png_uint_32 row_width = row_info->width; 3132 3133 png_debug(1, "in png_do_gray_to_rgb"); 3134 3135 if (row_info->bit_depth >= 8 && 3136 !(row_info->color_type & PNG_COLOR_MASK_COLOR)) 3137 { 3138 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 3139 { 3140 if (row_info->bit_depth == 8) 3141 { 3142 /* This changes G to RGB */ 3143 png_bytep sp = row + (png_size_t)row_width - 1; 3144 png_bytep dp = sp + (png_size_t)row_width * 2; 3145 for (i = 0; i < row_width; i++) 3146 { 3147 *(dp--) = *sp; 3148 *(dp--) = *sp; 3149 *(dp--) = *(sp--); 3150 } 3151 } 3152 3153 else 3154 { 3155 /* This changes GG to RRGGBB */ 3156 png_bytep sp = row + (png_size_t)row_width * 2 - 1; 3157 png_bytep dp = sp + (png_size_t)row_width * 4; 3158 for (i = 0; i < row_width; i++) 3159 { 3160 *(dp--) = *sp; 3161 *(dp--) = *(sp - 1); 3162 *(dp--) = *sp; 3163 *(dp--) = *(sp - 1); 3164 *(dp--) = *(sp--); 3165 *(dp--) = *(sp--); 3166 } 3167 } 3168 } 3169 3170 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 3171 { 3172 if (row_info->bit_depth == 8) 3173 { 3174 /* This changes GA to RGBA */ 3175 png_bytep sp = row + (png_size_t)row_width * 2 - 1; 3176 png_bytep dp = sp + (png_size_t)row_width * 2; 3177 for (i = 0; i < row_width; i++) 3178 { 3179 *(dp--) = *(sp--); 3180 *(dp--) = *sp; 3181 *(dp--) = *sp; 3182 *(dp--) = *(sp--); 3183 } 3184 } 3185 3186 else 3187 { 3188 /* This changes GGAA to RRGGBBAA */ 3189 png_bytep sp = row + (png_size_t)row_width * 4 - 1; 3190 png_bytep dp = sp + (png_size_t)row_width * 4; 3191 for (i = 0; i < row_width; i++) 3192 { 3193 *(dp--) = *(sp--); 3194 *(dp--) = *(sp--); 3195 *(dp--) = *sp; 3196 *(dp--) = *(sp - 1); 3197 *(dp--) = *sp; 3198 *(dp--) = *(sp - 1); 3199 *(dp--) = *(sp--); 3200 *(dp--) = *(sp--); 3201 } 3202 } 3203 } 3204 row_info->channels = (png_byte)(row_info->channels + 2); 3205 row_info->color_type |= PNG_COLOR_MASK_COLOR; 3206 row_info->pixel_depth = (png_byte)(row_info->channels * 3207 row_info->bit_depth); 3208 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 3209 } 3210} 3211#endif 3212 3213#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 3214/* Reduce RGB files to grayscale, with or without alpha 3215 * using the equation given in Poynton's ColorFAQ of 1998-01-04 at 3216 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but 3217 * versions dated 1998 through November 2002 have been archived at 3218 * http://web.archive.org/web/20000816232553/http://www.inforamp.net/ 3219 * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) 3220 * Charles Poynton poynton at poynton.com 3221 * 3222 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B 3223 * 3224 * which can be expressed with integers as 3225 * 3226 * Y = (6969 * R + 23434 * G + 2365 * B)/32768 3227 * 3228 * Poynton's current link (as of January 2003 through July 2011): 3229 * <http://www.poynton.com/notes/colour_and_gamma/> 3230 * has changed the numbers slightly: 3231 * 3232 * Y = 0.2126*R + 0.7152*G + 0.0722*B 3233 * 3234 * which can be expressed with integers as 3235 * 3236 * Y = (6966 * R + 23436 * G + 2366 * B)/32768 3237 * 3238 * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 3239 * end point chromaticities and the D65 white point. Depending on the 3240 * precision used for the D65 white point this produces a variety of different 3241 * numbers, however if the four decimal place value used in ITU-R Rec 709 is 3242 * used (0.3127,0.3290) the Y calculation would be: 3243 * 3244 * Y = (6968 * R + 23435 * G + 2366 * B)/32768 3245 * 3246 * While this is correct the rounding results in an overflow for white, because 3247 * the sum of the rounded coefficients is 32769, not 32768. Consequently 3248 * libpng uses, instead, the closest non-overflowing approximation: 3249 * 3250 * Y = (6968 * R + 23434 * G + 2366 * B)/32768 3251 * 3252 * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk 3253 * (including an sRGB chunk) then the chromaticities are used to calculate the 3254 * coefficients. See the chunk handling in pngrutil.c for more information. 3255 * 3256 * In all cases the calculation is to be done in a linear colorspace. If no 3257 * gamma information is available to correct the encoding of the original RGB 3258 * values this results in an implicit assumption that the original PNG RGB 3259 * values were linear. 3260 * 3261 * Other integer coefficents can be used via png_set_rgb_to_gray(). Because 3262 * the API takes just red and green coefficients the blue coefficient is 3263 * calculated to make the sum 32768. This will result in different rounding 3264 * to that used above. 3265 */ 3266int /* PRIVATE */ 3267png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) 3268 3269{ 3270 int rgb_error = 0; 3271 3272 png_debug(1, "in png_do_rgb_to_gray"); 3273 3274 if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && 3275 (row_info->color_type & PNG_COLOR_MASK_COLOR)) 3276 { 3277 PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; 3278 PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; 3279 PNG_CONST png_uint_32 bc = 32768 - rc - gc; 3280 PNG_CONST png_uint_32 row_width = row_info->width; 3281 PNG_CONST int have_alpha = 3282 (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; 3283 3284 if (row_info->bit_depth == 8) 3285 { 3286#ifdef PNG_READ_GAMMA_SUPPORTED 3287 /* Notice that gamma to/from 1 are not necessarily inverses (if 3288 * there is an overall gamma correction). Prior to 1.5.5 this code 3289 * checked the linearized values for equality; this doesn't match 3290 * the documentation, the original values must be checked. 3291 */ 3292 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) 3293 { 3294 png_bytep sp = row; 3295 png_bytep dp = row; 3296 png_uint_32 i; 3297 3298 for (i = 0; i < row_width; i++) 3299 { 3300 png_byte red = *(sp++); 3301 png_byte green = *(sp++); 3302 png_byte blue = *(sp++); 3303 3304 if (red != green || red != blue) 3305 { 3306 red = png_ptr->gamma_to_1[red]; 3307 green = png_ptr->gamma_to_1[green]; 3308 blue = png_ptr->gamma_to_1[blue]; 3309 3310 rgb_error |= 1; 3311 *(dp++) = png_ptr->gamma_from_1[ 3312 (rc*red + gc*green + bc*blue + 16384)>>15]; 3313 } 3314 3315 else 3316 { 3317 /* If there is no overall correction the table will not be 3318 * set. 3319 */ 3320 if (png_ptr->gamma_table != NULL) 3321 red = png_ptr->gamma_table[red]; 3322 3323 *(dp++) = red; 3324 } 3325 3326 if (have_alpha) 3327 *(dp++) = *(sp++); 3328 } 3329 } 3330 else 3331#endif 3332 { 3333 png_bytep sp = row; 3334 png_bytep dp = row; 3335 png_uint_32 i; 3336 3337 for (i = 0; i < row_width; i++) 3338 { 3339 png_byte red = *(sp++); 3340 png_byte green = *(sp++); 3341 png_byte blue = *(sp++); 3342 3343 if (red != green || red != blue) 3344 { 3345 rgb_error |= 1; 3346 /* NOTE: this is the historical approach which simply 3347 * truncates the results. 3348 */ 3349 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); 3350 } 3351 3352 else 3353 *(dp++) = red; 3354 3355 if (have_alpha) 3356 *(dp++) = *(sp++); 3357 } 3358 } 3359 } 3360 3361 else /* RGB bit_depth == 16 */ 3362 { 3363#ifdef PNG_READ_GAMMA_SUPPORTED 3364 if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) 3365 { 3366 png_bytep sp = row; 3367 png_bytep dp = row; 3368 png_uint_32 i; 3369 3370 for (i = 0; i < row_width; i++) 3371 { 3372 png_uint_16 red, green, blue, w; 3373 3374 red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3375 green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3376 blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3377 3378 if (red == green && red == blue) 3379 { 3380 if (png_ptr->gamma_16_table != NULL) 3381 w = png_ptr->gamma_16_table[(red&0xff) 3382 >> png_ptr->gamma_shift][red>>8]; 3383 3384 else 3385 w = red; 3386 } 3387 3388 else 3389 { 3390 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) 3391 >> png_ptr->gamma_shift][red>>8]; 3392 png_uint_16 green_1 = 3393 png_ptr->gamma_16_to_1[(green&0xff) >> 3394 png_ptr->gamma_shift][green>>8]; 3395 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) 3396 >> png_ptr->gamma_shift][blue>>8]; 3397 png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 3398 + bc*blue_1 + 16384)>>15); 3399 w = png_ptr->gamma_16_from_1[(gray16&0xff) >> 3400 png_ptr->gamma_shift][gray16 >> 8]; 3401 rgb_error |= 1; 3402 } 3403 3404 *(dp++) = (png_byte)((w>>8) & 0xff); 3405 *(dp++) = (png_byte)(w & 0xff); 3406 3407 if (have_alpha) 3408 { 3409 *(dp++) = *(sp++); 3410 *(dp++) = *(sp++); 3411 } 3412 } 3413 } 3414 else 3415#endif 3416 { 3417 png_bytep sp = row; 3418 png_bytep dp = row; 3419 png_uint_32 i; 3420 3421 for (i = 0; i < row_width; i++) 3422 { 3423 png_uint_16 red, green, blue, gray16; 3424 3425 red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3426 green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3427 blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; 3428 3429 if (red != green || red != blue) 3430 rgb_error |= 1; 3431 3432 /* From 1.5.5 in the 16 bit case do the accurate conversion even 3433 * in the 'fast' case - this is because this is where the code 3434 * ends up when handling linear 16 bit data. 3435 */ 3436 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> 3437 15); 3438 *(dp++) = (png_byte)((gray16>>8) & 0xff); 3439 *(dp++) = (png_byte)(gray16 & 0xff); 3440 3441 if (have_alpha) 3442 { 3443 *(dp++) = *(sp++); 3444 *(dp++) = *(sp++); 3445 } 3446 } 3447 } 3448 } 3449 3450 row_info->channels = (png_byte)(row_info->channels - 2); 3451 row_info->color_type = (png_byte)(row_info->color_type & 3452 ~PNG_COLOR_MASK_COLOR); 3453 row_info->pixel_depth = (png_byte)(row_info->channels * 3454 row_info->bit_depth); 3455 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 3456 } 3457 return rgb_error; 3458} 3459#endif 3460#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 3461 3462#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED 3463/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth 3464 * large of png_color. This lets grayscale images be treated as 3465 * paletted. Most useful for gamma correction and simplification 3466 * of code. This API is not used internally. 3467 */ 3468void PNGAPI 3469png_build_grayscale_palette(int bit_depth, png_colorp palette) 3470{ 3471 int num_palette; 3472 int color_inc; 3473 int i; 3474 int v; 3475 3476 png_debug(1, "in png_do_build_grayscale_palette"); 3477 3478 if (palette == NULL) 3479 return; 3480 3481 switch (bit_depth) 3482 { 3483 case 1: 3484 num_palette = 2; 3485 color_inc = 0xff; 3486 break; 3487 3488 case 2: 3489 num_palette = 4; 3490 color_inc = 0x55; 3491 break; 3492 3493 case 4: 3494 num_palette = 16; 3495 color_inc = 0x11; 3496 break; 3497 3498 case 8: 3499 num_palette = 256; 3500 color_inc = 1; 3501 break; 3502 3503 default: 3504 num_palette = 0; 3505 color_inc = 0; 3506 break; 3507 } 3508 3509 for (i = 0, v = 0; i < num_palette; i++, v += color_inc) 3510 { 3511 palette[i].red = (png_byte)v; 3512 palette[i].green = (png_byte)v; 3513 palette[i].blue = (png_byte)v; 3514 } 3515} 3516#endif 3517 3518 3519#ifdef PNG_READ_TRANSFORMS_SUPPORTED 3520#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 3521 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 3522/* Replace any alpha or transparency with the supplied background color. 3523 * "background" is already in the screen gamma, while "background_1" is 3524 * at a gamma of 1.0. Paletted files have already been taken care of. 3525 */ 3526void /* PRIVATE */ 3527png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 3528{ 3529#ifdef PNG_READ_GAMMA_SUPPORTED 3530 png_const_bytep gamma_table = png_ptr->gamma_table; 3531 png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; 3532 png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; 3533 png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; 3534 png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; 3535 png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; 3536 int gamma_shift = png_ptr->gamma_shift; 3537 int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; 3538#endif 3539 3540 png_bytep sp; 3541 png_uint_32 i; 3542 png_uint_32 row_width = row_info->width; 3543 int shift; 3544 3545 png_debug(1, "in png_do_compose"); 3546 3547 { 3548 switch (row_info->color_type) 3549 { 3550 case PNG_COLOR_TYPE_GRAY: 3551 { 3552 switch (row_info->bit_depth) 3553 { 3554 case 1: 3555 { 3556 sp = row; 3557 shift = 7; 3558 for (i = 0; i < row_width; i++) 3559 { 3560 if ((png_uint_16)((*sp >> shift) & 0x01) 3561 == png_ptr->trans_color.gray) 3562 { 3563 unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); 3564 tmp |= png_ptr->background.gray << shift; 3565 *sp = (png_byte)(tmp & 0xff); 3566 } 3567 3568 if (!shift) 3569 { 3570 shift = 7; 3571 sp++; 3572 } 3573 3574 else 3575 shift--; 3576 } 3577 break; 3578 } 3579 3580 case 2: 3581 { 3582#ifdef PNG_READ_GAMMA_SUPPORTED 3583 if (gamma_table != NULL) 3584 { 3585 sp = row; 3586 shift = 6; 3587 for (i = 0; i < row_width; i++) 3588 { 3589 if ((png_uint_16)((*sp >> shift) & 0x03) 3590 == png_ptr->trans_color.gray) 3591 { 3592 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3593 tmp |= png_ptr->background.gray << shift; 3594 *sp = (png_byte)(tmp & 0xff); 3595 } 3596 3597 else 3598 { 3599 unsigned int p = (*sp >> shift) & 0x03; 3600 unsigned int g = (gamma_table [p | (p << 2) | 3601 (p << 4) | (p << 6)] >> 6) & 0x03; 3602 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3603 tmp |= g << shift; 3604 *sp = (png_byte)(tmp & 0xff); 3605 } 3606 3607 if (!shift) 3608 { 3609 shift = 6; 3610 sp++; 3611 } 3612 3613 else 3614 shift -= 2; 3615 } 3616 } 3617 3618 else 3619#endif 3620 { 3621 sp = row; 3622 shift = 6; 3623 for (i = 0; i < row_width; i++) 3624 { 3625 if ((png_uint_16)((*sp >> shift) & 0x03) 3626 == png_ptr->trans_color.gray) 3627 { 3628 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3629 tmp |= png_ptr->background.gray << shift; 3630 *sp = (png_byte)(tmp & 0xff); 3631 } 3632 3633 if (!shift) 3634 { 3635 shift = 6; 3636 sp++; 3637 } 3638 3639 else 3640 shift -= 2; 3641 } 3642 } 3643 break; 3644 } 3645 3646 case 4: 3647 { 3648#ifdef PNG_READ_GAMMA_SUPPORTED 3649 if (gamma_table != NULL) 3650 { 3651 sp = row; 3652 shift = 4; 3653 for (i = 0; i < row_width; i++) 3654 { 3655 if ((png_uint_16)((*sp >> shift) & 0x0f) 3656 == png_ptr->trans_color.gray) 3657 { 3658 unsigned int tmp = *sp & (0xf0f >> (4 - shift)); 3659 tmp |= png_ptr->background.gray << shift; 3660 *sp = (png_byte)(tmp & 0xff); 3661 } 3662 3663 else 3664 { 3665 unsigned int p = (*sp >> shift) & 0x0f; 3666 unsigned int g = (gamma_table[p | (p << 4)] >> 4) & 3667 0x0f; 3668 unsigned int tmp = *sp & (0xf0f >> (4 - shift)); 3669 tmp |= g << shift; 3670 *sp = (png_byte)(tmp & 0xff); 3671 } 3672 3673 if (!shift) 3674 { 3675 shift = 4; 3676 sp++; 3677 } 3678 3679 else 3680 shift -= 4; 3681 } 3682 } 3683 3684 else 3685#endif 3686 { 3687 sp = row; 3688 shift = 4; 3689 for (i = 0; i < row_width; i++) 3690 { 3691 if ((png_uint_16)((*sp >> shift) & 0x0f) 3692 == png_ptr->trans_color.gray) 3693 { 3694 unsigned int tmp = *sp & (0xf0f >> (4 - shift)); 3695 tmp |= png_ptr->background.gray << shift; 3696 *sp = (png_byte)(tmp & 0xff); 3697 } 3698 3699 if (!shift) 3700 { 3701 shift = 4; 3702 sp++; 3703 } 3704 3705 else 3706 shift -= 4; 3707 } 3708 } 3709 break; 3710 } 3711 3712 case 8: 3713 { 3714#ifdef PNG_READ_GAMMA_SUPPORTED 3715 if (gamma_table != NULL) 3716 { 3717 sp = row; 3718 for (i = 0; i < row_width; i++, sp++) 3719 { 3720 if (*sp == png_ptr->trans_color.gray) 3721 *sp = (png_byte)png_ptr->background.gray; 3722 3723 else 3724 *sp = gamma_table[*sp]; 3725 } 3726 } 3727 else 3728#endif 3729 { 3730 sp = row; 3731 for (i = 0; i < row_width; i++, sp++) 3732 { 3733 if (*sp == png_ptr->trans_color.gray) 3734 *sp = (png_byte)png_ptr->background.gray; 3735 } 3736 } 3737 break; 3738 } 3739 3740 case 16: 3741 { 3742#ifdef PNG_READ_GAMMA_SUPPORTED 3743 if (gamma_16 != NULL) 3744 { 3745 sp = row; 3746 for (i = 0; i < row_width; i++, sp += 2) 3747 { 3748 png_uint_16 v; 3749 3750 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3751 3752 if (v == png_ptr->trans_color.gray) 3753 { 3754 /* Background is already in screen gamma */ 3755 *sp = (png_byte)((png_ptr->background.gray >> 8) 3756 & 0xff); 3757 *(sp + 1) = (png_byte)(png_ptr->background.gray 3758 & 0xff); 3759 } 3760 3761 else 3762 { 3763 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3764 *sp = (png_byte)((v >> 8) & 0xff); 3765 *(sp + 1) = (png_byte)(v & 0xff); 3766 } 3767 } 3768 } 3769 else 3770#endif 3771 { 3772 sp = row; 3773 for (i = 0; i < row_width; i++, sp += 2) 3774 { 3775 png_uint_16 v; 3776 3777 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3778 3779 if (v == png_ptr->trans_color.gray) 3780 { 3781 *sp = (png_byte)((png_ptr->background.gray >> 8) 3782 & 0xff); 3783 *(sp + 1) = (png_byte)(png_ptr->background.gray 3784 & 0xff); 3785 } 3786 } 3787 } 3788 break; 3789 } 3790 3791 default: 3792 break; 3793 } 3794 break; 3795 } 3796 3797 case PNG_COLOR_TYPE_RGB: 3798 { 3799 if (row_info->bit_depth == 8) 3800 { 3801#ifdef PNG_READ_GAMMA_SUPPORTED 3802 if (gamma_table != NULL) 3803 { 3804 sp = row; 3805 for (i = 0; i < row_width; i++, sp += 3) 3806 { 3807 if (*sp == png_ptr->trans_color.red && 3808 *(sp + 1) == png_ptr->trans_color.green && 3809 *(sp + 2) == png_ptr->trans_color.blue) 3810 { 3811 *sp = (png_byte)png_ptr->background.red; 3812 *(sp + 1) = (png_byte)png_ptr->background.green; 3813 *(sp + 2) = (png_byte)png_ptr->background.blue; 3814 } 3815 3816 else 3817 { 3818 *sp = gamma_table[*sp]; 3819 *(sp + 1) = gamma_table[*(sp + 1)]; 3820 *(sp + 2) = gamma_table[*(sp + 2)]; 3821 } 3822 } 3823 } 3824 else 3825#endif 3826 { 3827 sp = row; 3828 for (i = 0; i < row_width; i++, sp += 3) 3829 { 3830 if (*sp == png_ptr->trans_color.red && 3831 *(sp + 1) == png_ptr->trans_color.green && 3832 *(sp + 2) == png_ptr->trans_color.blue) 3833 { 3834 *sp = (png_byte)png_ptr->background.red; 3835 *(sp + 1) = (png_byte)png_ptr->background.green; 3836 *(sp + 2) = (png_byte)png_ptr->background.blue; 3837 } 3838 } 3839 } 3840 } 3841 else /* if (row_info->bit_depth == 16) */ 3842 { 3843#ifdef PNG_READ_GAMMA_SUPPORTED 3844 if (gamma_16 != NULL) 3845 { 3846 sp = row; 3847 for (i = 0; i < row_width; i++, sp += 6) 3848 { 3849 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3850 3851 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3852 + *(sp + 3)); 3853 3854 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3855 + *(sp + 5)); 3856 3857 if (r == png_ptr->trans_color.red && 3858 g == png_ptr->trans_color.green && 3859 b == png_ptr->trans_color.blue) 3860 { 3861 /* Background is already in screen gamma */ 3862 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3863 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3864 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3865 & 0xff); 3866 *(sp + 3) = (png_byte)(png_ptr->background.green 3867 & 0xff); 3868 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3869 & 0xff); 3870 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3871 } 3872 3873 else 3874 { 3875 png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3876 *sp = (png_byte)((v >> 8) & 0xff); 3877 *(sp + 1) = (png_byte)(v & 0xff); 3878 3879 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3880 *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3881 *(sp + 3) = (png_byte)(v & 0xff); 3882 3883 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3884 *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3885 *(sp + 5) = (png_byte)(v & 0xff); 3886 } 3887 } 3888 } 3889 3890 else 3891#endif 3892 { 3893 sp = row; 3894 for (i = 0; i < row_width; i++, sp += 6) 3895 { 3896 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3897 3898 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3899 + *(sp + 3)); 3900 3901 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3902 + *(sp + 5)); 3903 3904 if (r == png_ptr->trans_color.red && 3905 g == png_ptr->trans_color.green && 3906 b == png_ptr->trans_color.blue) 3907 { 3908 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3909 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3910 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3911 & 0xff); 3912 *(sp + 3) = (png_byte)(png_ptr->background.green 3913 & 0xff); 3914 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3915 & 0xff); 3916 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3917 } 3918 } 3919 } 3920 } 3921 break; 3922 } 3923 3924 case PNG_COLOR_TYPE_GRAY_ALPHA: 3925 { 3926 if (row_info->bit_depth == 8) 3927 { 3928#ifdef PNG_READ_GAMMA_SUPPORTED 3929 if (gamma_to_1 != NULL && gamma_from_1 != NULL && 3930 gamma_table != NULL) 3931 { 3932 sp = row; 3933 for (i = 0; i < row_width; i++, sp += 2) 3934 { 3935 png_uint_16 a = *(sp + 1); 3936 3937 if (a == 0xff) 3938 *sp = gamma_table[*sp]; 3939 3940 else if (a == 0) 3941 { 3942 /* Background is already in screen gamma */ 3943 *sp = (png_byte)png_ptr->background.gray; 3944 } 3945 3946 else 3947 { 3948 png_byte v, w; 3949 3950 v = gamma_to_1[*sp]; 3951 png_composite(w, v, a, png_ptr->background_1.gray); 3952 if (!optimize) 3953 w = gamma_from_1[w]; 3954 *sp = w; 3955 } 3956 } 3957 } 3958 else 3959#endif 3960 { 3961 sp = row; 3962 for (i = 0; i < row_width; i++, sp += 2) 3963 { 3964 png_byte a = *(sp + 1); 3965 3966 if (a == 0) 3967 *sp = (png_byte)png_ptr->background.gray; 3968 3969 else if (a < 0xff) 3970 png_composite(*sp, *sp, a, png_ptr->background.gray); 3971 } 3972 } 3973 } 3974 else /* if (png_ptr->bit_depth == 16) */ 3975 { 3976#ifdef PNG_READ_GAMMA_SUPPORTED 3977 if (gamma_16 != NULL && gamma_16_from_1 != NULL && 3978 gamma_16_to_1 != NULL) 3979 { 3980 sp = row; 3981 for (i = 0; i < row_width; i++, sp += 4) 3982 { 3983 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 3984 + *(sp + 3)); 3985 3986 if (a == (png_uint_16)0xffff) 3987 { 3988 png_uint_16 v; 3989 3990 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3991 *sp = (png_byte)((v >> 8) & 0xff); 3992 *(sp + 1) = (png_byte)(v & 0xff); 3993 } 3994 3995 else if (a == 0) 3996 { 3997 /* Background is already in screen gamma */ 3998 *sp = (png_byte)((png_ptr->background.gray >> 8) 3999 & 0xff); 4000 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 4001 } 4002 4003 else 4004 { 4005 png_uint_16 g, v, w; 4006 4007 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 4008 png_composite_16(v, g, a, png_ptr->background_1.gray); 4009 if (optimize) 4010 w = v; 4011 else 4012 w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; 4013 *sp = (png_byte)((w >> 8) & 0xff); 4014 *(sp + 1) = (png_byte)(w & 0xff); 4015 } 4016 } 4017 } 4018 else 4019#endif 4020 { 4021 sp = row; 4022 for (i = 0; i < row_width; i++, sp += 4) 4023 { 4024 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 4025 + *(sp + 3)); 4026 4027 if (a == 0) 4028 { 4029 *sp = (png_byte)((png_ptr->background.gray >> 8) 4030 & 0xff); 4031 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 4032 } 4033 4034 else if (a < 0xffff) 4035 { 4036 png_uint_16 g, v; 4037 4038 g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 4039 png_composite_16(v, g, a, png_ptr->background.gray); 4040 *sp = (png_byte)((v >> 8) & 0xff); 4041 *(sp + 1) = (png_byte)(v & 0xff); 4042 } 4043 } 4044 } 4045 } 4046 break; 4047 } 4048 4049 case PNG_COLOR_TYPE_RGB_ALPHA: 4050 { 4051 if (row_info->bit_depth == 8) 4052 { 4053#ifdef PNG_READ_GAMMA_SUPPORTED 4054 if (gamma_to_1 != NULL && gamma_from_1 != NULL && 4055 gamma_table != NULL) 4056 { 4057 sp = row; 4058 for (i = 0; i < row_width; i++, sp += 4) 4059 { 4060 png_byte a = *(sp + 3); 4061 4062 if (a == 0xff) 4063 { 4064 *sp = gamma_table[*sp]; 4065 *(sp + 1) = gamma_table[*(sp + 1)]; 4066 *(sp + 2) = gamma_table[*(sp + 2)]; 4067 } 4068 4069 else if (a == 0) 4070 { 4071 /* Background is already in screen gamma */ 4072 *sp = (png_byte)png_ptr->background.red; 4073 *(sp + 1) = (png_byte)png_ptr->background.green; 4074 *(sp + 2) = (png_byte)png_ptr->background.blue; 4075 } 4076 4077 else 4078 { 4079 png_byte v, w; 4080 4081 v = gamma_to_1[*sp]; 4082 png_composite(w, v, a, png_ptr->background_1.red); 4083 if (!optimize) w = gamma_from_1[w]; 4084 *sp = w; 4085 4086 v = gamma_to_1[*(sp + 1)]; 4087 png_composite(w, v, a, png_ptr->background_1.green); 4088 if (!optimize) w = gamma_from_1[w]; 4089 *(sp + 1) = w; 4090 4091 v = gamma_to_1[*(sp + 2)]; 4092 png_composite(w, v, a, png_ptr->background_1.blue); 4093 if (!optimize) w = gamma_from_1[w]; 4094 *(sp + 2) = w; 4095 } 4096 } 4097 } 4098 else 4099#endif 4100 { 4101 sp = row; 4102 for (i = 0; i < row_width; i++, sp += 4) 4103 { 4104 png_byte a = *(sp + 3); 4105 4106 if (a == 0) 4107 { 4108 *sp = (png_byte)png_ptr->background.red; 4109 *(sp + 1) = (png_byte)png_ptr->background.green; 4110 *(sp + 2) = (png_byte)png_ptr->background.blue; 4111 } 4112 4113 else if (a < 0xff) 4114 { 4115 png_composite(*sp, *sp, a, png_ptr->background.red); 4116 4117 png_composite(*(sp + 1), *(sp + 1), a, 4118 png_ptr->background.green); 4119 4120 png_composite(*(sp + 2), *(sp + 2), a, 4121 png_ptr->background.blue); 4122 } 4123 } 4124 } 4125 } 4126 else /* if (row_info->bit_depth == 16) */ 4127 { 4128#ifdef PNG_READ_GAMMA_SUPPORTED 4129 if (gamma_16 != NULL && gamma_16_from_1 != NULL && 4130 gamma_16_to_1 != NULL) 4131 { 4132 sp = row; 4133 for (i = 0; i < row_width; i++, sp += 8) 4134 { 4135 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 4136 << 8) + (png_uint_16)(*(sp + 7))); 4137 4138 if (a == (png_uint_16)0xffff) 4139 { 4140 png_uint_16 v; 4141 4142 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 4143 *sp = (png_byte)((v >> 8) & 0xff); 4144 *(sp + 1) = (png_byte)(v & 0xff); 4145 4146 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 4147 *(sp + 2) = (png_byte)((v >> 8) & 0xff); 4148 *(sp + 3) = (png_byte)(v & 0xff); 4149 4150 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 4151 *(sp + 4) = (png_byte)((v >> 8) & 0xff); 4152 *(sp + 5) = (png_byte)(v & 0xff); 4153 } 4154 4155 else if (a == 0) 4156 { 4157 /* Background is already in screen gamma */ 4158 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 4159 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 4160 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 4161 & 0xff); 4162 *(sp + 3) = (png_byte)(png_ptr->background.green 4163 & 0xff); 4164 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 4165 & 0xff); 4166 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 4167 } 4168 4169 else 4170 { 4171 png_uint_16 v, w; 4172 4173 v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 4174 png_composite_16(w, v, a, png_ptr->background_1.red); 4175 if (!optimize) 4176 w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 4177 8]; 4178 *sp = (png_byte)((w >> 8) & 0xff); 4179 *(sp + 1) = (png_byte)(w & 0xff); 4180 4181 v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; 4182 png_composite_16(w, v, a, png_ptr->background_1.green); 4183 if (!optimize) 4184 w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 4185 8]; 4186 4187 *(sp + 2) = (png_byte)((w >> 8) & 0xff); 4188 *(sp + 3) = (png_byte)(w & 0xff); 4189 4190 v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; 4191 png_composite_16(w, v, a, png_ptr->background_1.blue); 4192 if (!optimize) 4193 w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 4194 8]; 4195 4196 *(sp + 4) = (png_byte)((w >> 8) & 0xff); 4197 *(sp + 5) = (png_byte)(w & 0xff); 4198 } 4199 } 4200 } 4201 4202 else 4203#endif 4204 { 4205 sp = row; 4206 for (i = 0; i < row_width; i++, sp += 8) 4207 { 4208 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 4209 << 8) + (png_uint_16)(*(sp + 7))); 4210 4211 if (a == 0) 4212 { 4213 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 4214 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 4215 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 4216 & 0xff); 4217 *(sp + 3) = (png_byte)(png_ptr->background.green 4218 & 0xff); 4219 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 4220 & 0xff); 4221 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 4222 } 4223 4224 else if (a < 0xffff) 4225 { 4226 png_uint_16 v; 4227 4228 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 4229 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 4230 + *(sp + 3)); 4231 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 4232 + *(sp + 5)); 4233 4234 png_composite_16(v, r, a, png_ptr->background.red); 4235 *sp = (png_byte)((v >> 8) & 0xff); 4236 *(sp + 1) = (png_byte)(v & 0xff); 4237 4238 png_composite_16(v, g, a, png_ptr->background.green); 4239 *(sp + 2) = (png_byte)((v >> 8) & 0xff); 4240 *(sp + 3) = (png_byte)(v & 0xff); 4241 4242 png_composite_16(v, b, a, png_ptr->background.blue); 4243 *(sp + 4) = (png_byte)((v >> 8) & 0xff); 4244 *(sp + 5) = (png_byte)(v & 0xff); 4245 } 4246 } 4247 } 4248 } 4249 break; 4250 } 4251 4252 default: 4253 break; 4254 } 4255 } 4256} 4257#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */ 4258 4259#ifdef PNG_READ_GAMMA_SUPPORTED 4260/* Gamma correct the image, avoiding the alpha channel. Make sure 4261 * you do this after you deal with the transparency issue on grayscale 4262 * or RGB images. If your bit depth is 8, use gamma_table, if it 4263 * is 16, use gamma_16_table and gamma_shift. Build these with 4264 * build_gamma_table(). 4265 */ 4266void /* PRIVATE */ 4267png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 4268{ 4269 png_const_bytep gamma_table = png_ptr->gamma_table; 4270 png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; 4271 int gamma_shift = png_ptr->gamma_shift; 4272 4273 png_bytep sp; 4274 png_uint_32 i; 4275 png_uint_32 row_width=row_info->width; 4276 4277 png_debug(1, "in png_do_gamma"); 4278 4279 if (((row_info->bit_depth <= 8 && gamma_table != NULL) || 4280 (row_info->bit_depth == 16 && gamma_16_table != NULL))) 4281 { 4282 switch (row_info->color_type) 4283 { 4284 case PNG_COLOR_TYPE_RGB: 4285 { 4286 if (row_info->bit_depth == 8) 4287 { 4288 sp = row; 4289 for (i = 0; i < row_width; i++) 4290 { 4291 *sp = gamma_table[*sp]; 4292 sp++; 4293 *sp = gamma_table[*sp]; 4294 sp++; 4295 *sp = gamma_table[*sp]; 4296 sp++; 4297 } 4298 } 4299 4300 else /* if (row_info->bit_depth == 16) */ 4301 { 4302 sp = row; 4303 for (i = 0; i < row_width; i++) 4304 { 4305 png_uint_16 v; 4306 4307 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4308 *sp = (png_byte)((v >> 8) & 0xff); 4309 *(sp + 1) = (png_byte)(v & 0xff); 4310 sp += 2; 4311 4312 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4313 *sp = (png_byte)((v >> 8) & 0xff); 4314 *(sp + 1) = (png_byte)(v & 0xff); 4315 sp += 2; 4316 4317 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4318 *sp = (png_byte)((v >> 8) & 0xff); 4319 *(sp + 1) = (png_byte)(v & 0xff); 4320 sp += 2; 4321 } 4322 } 4323 break; 4324 } 4325 4326 case PNG_COLOR_TYPE_RGB_ALPHA: 4327 { 4328 if (row_info->bit_depth == 8) 4329 { 4330 sp = row; 4331 for (i = 0; i < row_width; i++) 4332 { 4333 *sp = gamma_table[*sp]; 4334 sp++; 4335 4336 *sp = gamma_table[*sp]; 4337 sp++; 4338 4339 *sp = gamma_table[*sp]; 4340 sp++; 4341 4342 sp++; 4343 } 4344 } 4345 4346 else /* if (row_info->bit_depth == 16) */ 4347 { 4348 sp = row; 4349 for (i = 0; i < row_width; i++) 4350 { 4351 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4352 *sp = (png_byte)((v >> 8) & 0xff); 4353 *(sp + 1) = (png_byte)(v & 0xff); 4354 sp += 2; 4355 4356 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4357 *sp = (png_byte)((v >> 8) & 0xff); 4358 *(sp + 1) = (png_byte)(v & 0xff); 4359 sp += 2; 4360 4361 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4362 *sp = (png_byte)((v >> 8) & 0xff); 4363 *(sp + 1) = (png_byte)(v & 0xff); 4364 sp += 4; 4365 } 4366 } 4367 break; 4368 } 4369 4370 case PNG_COLOR_TYPE_GRAY_ALPHA: 4371 { 4372 if (row_info->bit_depth == 8) 4373 { 4374 sp = row; 4375 for (i = 0; i < row_width; i++) 4376 { 4377 *sp = gamma_table[*sp]; 4378 sp += 2; 4379 } 4380 } 4381 4382 else /* if (row_info->bit_depth == 16) */ 4383 { 4384 sp = row; 4385 for (i = 0; i < row_width; i++) 4386 { 4387 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4388 *sp = (png_byte)((v >> 8) & 0xff); 4389 *(sp + 1) = (png_byte)(v & 0xff); 4390 sp += 4; 4391 } 4392 } 4393 break; 4394 } 4395 4396 case PNG_COLOR_TYPE_GRAY: 4397 { 4398 if (row_info->bit_depth == 2) 4399 { 4400 sp = row; 4401 for (i = 0; i < row_width; i += 4) 4402 { 4403 int a = *sp & 0xc0; 4404 int b = *sp & 0x30; 4405 int c = *sp & 0x0c; 4406 int d = *sp & 0x03; 4407 4408 *sp = (png_byte)( 4409 ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| 4410 ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| 4411 ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| 4412 ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); 4413 sp++; 4414 } 4415 } 4416 4417 if (row_info->bit_depth == 4) 4418 { 4419 sp = row; 4420 for (i = 0; i < row_width; i += 2) 4421 { 4422 int msb = *sp & 0xf0; 4423 int lsb = *sp & 0x0f; 4424 4425 *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) 4426 | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); 4427 sp++; 4428 } 4429 } 4430 4431 else if (row_info->bit_depth == 8) 4432 { 4433 sp = row; 4434 for (i = 0; i < row_width; i++) 4435 { 4436 *sp = gamma_table[*sp]; 4437 sp++; 4438 } 4439 } 4440 4441 else if (row_info->bit_depth == 16) 4442 { 4443 sp = row; 4444 for (i = 0; i < row_width; i++) 4445 { 4446 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4447 *sp = (png_byte)((v >> 8) & 0xff); 4448 *(sp + 1) = (png_byte)(v & 0xff); 4449 sp += 2; 4450 } 4451 } 4452 break; 4453 } 4454 4455 default: 4456 break; 4457 } 4458 } 4459} 4460#endif 4461 4462#ifdef PNG_READ_ALPHA_MODE_SUPPORTED 4463/* Encode the alpha channel to the output gamma (the input channel is always 4464 * linear.) Called only with color types that have an alpha channel. Needs the 4465 * from_1 tables. 4466 */ 4467void /* PRIVATE */ 4468png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 4469{ 4470 png_uint_32 row_width = row_info->width; 4471 4472 png_debug(1, "in png_do_encode_alpha"); 4473 4474 if (row_info->color_type & PNG_COLOR_MASK_ALPHA) 4475 { 4476 if (row_info->bit_depth == 8) 4477 { 4478 PNG_CONST png_bytep table = png_ptr->gamma_from_1; 4479 4480 if (table != NULL) 4481 { 4482 PNG_CONST int step = 4483 (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; 4484 4485 /* The alpha channel is the last component: */ 4486 row += step - 1; 4487 4488 for (; row_width > 0; --row_width, row += step) 4489 *row = table[*row]; 4490 4491 return; 4492 } 4493 } 4494 4495 else if (row_info->bit_depth == 16) 4496 { 4497 PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; 4498 PNG_CONST int gamma_shift = png_ptr->gamma_shift; 4499 4500 if (table != NULL) 4501 { 4502 PNG_CONST int step = 4503 (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; 4504 4505 /* The alpha channel is the last component: */ 4506 row += step - 2; 4507 4508 for (; row_width > 0; --row_width, row += step) 4509 { 4510 png_uint_16 v; 4511 4512 v = table[*(row + 1) >> gamma_shift][*row]; 4513 *row = (png_byte)((v >> 8) & 0xff); 4514 *(row + 1) = (png_byte)(v & 0xff); 4515 } 4516 4517 return; 4518 } 4519 } 4520 } 4521 4522 /* Only get to here if called with a weird row_info; no harm has been done, 4523 * so just issue a warning. 4524 */ 4525 png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); 4526} 4527#endif 4528 4529#ifdef PNG_READ_EXPAND_SUPPORTED 4530/* Expands a palette row to an RGB or RGBA row depending 4531 * upon whether you supply trans and num_trans. 4532 */ 4533void /* PRIVATE */ 4534png_do_expand_palette(png_row_infop row_info, png_bytep row, 4535 png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) 4536{ 4537 int shift, value; 4538 png_bytep sp, dp; 4539 png_uint_32 i; 4540 png_uint_32 row_width=row_info->width; 4541 4542 png_debug(1, "in png_do_expand_palette"); 4543 4544 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 4545 { 4546 if (row_info->bit_depth < 8) 4547 { 4548 switch (row_info->bit_depth) 4549 { 4550 case 1: 4551 { 4552 sp = row + (png_size_t)((row_width - 1) >> 3); 4553 dp = row + (png_size_t)row_width - 1; 4554 shift = 7 - (int)((row_width + 7) & 0x07); 4555 for (i = 0; i < row_width; i++) 4556 { 4557 if ((*sp >> shift) & 0x01) 4558 *dp = 1; 4559 4560 else 4561 *dp = 0; 4562 4563 if (shift == 7) 4564 { 4565 shift = 0; 4566 sp--; 4567 } 4568 4569 else 4570 shift++; 4571 4572 dp--; 4573 } 4574 break; 4575 } 4576 4577 case 2: 4578 { 4579 sp = row + (png_size_t)((row_width - 1) >> 2); 4580 dp = row + (png_size_t)row_width - 1; 4581 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4582 for (i = 0; i < row_width; i++) 4583 { 4584 value = (*sp >> shift) & 0x03; 4585 *dp = (png_byte)value; 4586 if (shift == 6) 4587 { 4588 shift = 0; 4589 sp--; 4590 } 4591 4592 else 4593 shift += 2; 4594 4595 dp--; 4596 } 4597 break; 4598 } 4599 4600 case 4: 4601 { 4602 sp = row + (png_size_t)((row_width - 1) >> 1); 4603 dp = row + (png_size_t)row_width - 1; 4604 shift = (int)((row_width & 0x01) << 2); 4605 for (i = 0; i < row_width; i++) 4606 { 4607 value = (*sp >> shift) & 0x0f; 4608 *dp = (png_byte)value; 4609 if (shift == 4) 4610 { 4611 shift = 0; 4612 sp--; 4613 } 4614 4615 else 4616 shift += 4; 4617 4618 dp--; 4619 } 4620 break; 4621 } 4622 4623 default: 4624 break; 4625 } 4626 row_info->bit_depth = 8; 4627 row_info->pixel_depth = 8; 4628 row_info->rowbytes = row_width; 4629 } 4630 4631 if (row_info->bit_depth == 8) 4632 { 4633 { 4634 if (num_trans > 0) 4635 { 4636 sp = row + (png_size_t)row_width - 1; 4637 dp = row + (png_size_t)(row_width << 2) - 1; 4638 4639 for (i = 0; i < row_width; i++) 4640 { 4641 if ((int)(*sp) >= num_trans) 4642 *dp-- = 0xff; 4643 4644 else 4645 *dp-- = trans_alpha[*sp]; 4646 4647 *dp-- = palette[*sp].blue; 4648 *dp-- = palette[*sp].green; 4649 *dp-- = palette[*sp].red; 4650 sp--; 4651 } 4652 row_info->bit_depth = 8; 4653 row_info->pixel_depth = 32; 4654 row_info->rowbytes = row_width * 4; 4655 row_info->color_type = 6; 4656 row_info->channels = 4; 4657 } 4658 4659 else 4660 { 4661 sp = row + (png_size_t)row_width - 1; 4662 dp = row + (png_size_t)(row_width * 3) - 1; 4663 4664 for (i = 0; i < row_width; i++) 4665 { 4666 *dp-- = palette[*sp].blue; 4667 *dp-- = palette[*sp].green; 4668 *dp-- = palette[*sp].red; 4669 sp--; 4670 } 4671 4672 row_info->bit_depth = 8; 4673 row_info->pixel_depth = 24; 4674 row_info->rowbytes = row_width * 3; 4675 row_info->color_type = 2; 4676 row_info->channels = 3; 4677 } 4678 } 4679 } 4680 } 4681} 4682 4683/* If the bit depth < 8, it is expanded to 8. Also, if the already 4684 * expanded transparency value is supplied, an alpha channel is built. 4685 */ 4686void /* PRIVATE */ 4687png_do_expand(png_row_infop row_info, png_bytep row, 4688 png_const_color_16p trans_color) 4689{ 4690 int shift, value; 4691 png_bytep sp, dp; 4692 png_uint_32 i; 4693 png_uint_32 row_width=row_info->width; 4694 4695 png_debug(1, "in png_do_expand"); 4696 4697 { 4698 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 4699 { 4700 unsigned int gray = trans_color ? trans_color->gray : 0; 4701 4702 if (row_info->bit_depth < 8) 4703 { 4704 switch (row_info->bit_depth) 4705 { 4706 case 1: 4707 { 4708 gray = (gray & 0x01) * 0xff; 4709 sp = row + (png_size_t)((row_width - 1) >> 3); 4710 dp = row + (png_size_t)row_width - 1; 4711 shift = 7 - (int)((row_width + 7) & 0x07); 4712 for (i = 0; i < row_width; i++) 4713 { 4714 if ((*sp >> shift) & 0x01) 4715 *dp = 0xff; 4716 4717 else 4718 *dp = 0; 4719 4720 if (shift == 7) 4721 { 4722 shift = 0; 4723 sp--; 4724 } 4725 4726 else 4727 shift++; 4728 4729 dp--; 4730 } 4731 break; 4732 } 4733 4734 case 2: 4735 { 4736 gray = (gray & 0x03) * 0x55; 4737 sp = row + (png_size_t)((row_width - 1) >> 2); 4738 dp = row + (png_size_t)row_width - 1; 4739 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4740 for (i = 0; i < row_width; i++) 4741 { 4742 value = (*sp >> shift) & 0x03; 4743 *dp = (png_byte)(value | (value << 2) | (value << 4) | 4744 (value << 6)); 4745 if (shift == 6) 4746 { 4747 shift = 0; 4748 sp--; 4749 } 4750 4751 else 4752 shift += 2; 4753 4754 dp--; 4755 } 4756 break; 4757 } 4758 4759 case 4: 4760 { 4761 gray = (gray & 0x0f) * 0x11; 4762 sp = row + (png_size_t)((row_width - 1) >> 1); 4763 dp = row + (png_size_t)row_width - 1; 4764 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 4765 for (i = 0; i < row_width; i++) 4766 { 4767 value = (*sp >> shift) & 0x0f; 4768 *dp = (png_byte)(value | (value << 4)); 4769 if (shift == 4) 4770 { 4771 shift = 0; 4772 sp--; 4773 } 4774 4775 else 4776 shift = 4; 4777 4778 dp--; 4779 } 4780 break; 4781 } 4782 4783 default: 4784 break; 4785 } 4786 4787 row_info->bit_depth = 8; 4788 row_info->pixel_depth = 8; 4789 row_info->rowbytes = row_width; 4790 } 4791 4792 if (trans_color != NULL) 4793 { 4794 if (row_info->bit_depth == 8) 4795 { 4796 gray = gray & 0xff; 4797 sp = row + (png_size_t)row_width - 1; 4798 dp = row + (png_size_t)(row_width << 1) - 1; 4799 4800 for (i = 0; i < row_width; i++) 4801 { 4802 if (*sp == gray) 4803 *dp-- = 0; 4804 4805 else 4806 *dp-- = 0xff; 4807 4808 *dp-- = *sp--; 4809 } 4810 } 4811 4812 else if (row_info->bit_depth == 16) 4813 { 4814 unsigned int gray_high = (gray >> 8) & 0xff; 4815 unsigned int gray_low = gray & 0xff; 4816 sp = row + row_info->rowbytes - 1; 4817 dp = row + (row_info->rowbytes << 1) - 1; 4818 for (i = 0; i < row_width; i++) 4819 { 4820 if (*(sp - 1) == gray_high && *(sp) == gray_low) 4821 { 4822 *dp-- = 0; 4823 *dp-- = 0; 4824 } 4825 4826 else 4827 { 4828 *dp-- = 0xff; 4829 *dp-- = 0xff; 4830 } 4831 4832 *dp-- = *sp--; 4833 *dp-- = *sp--; 4834 } 4835 } 4836 4837 row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; 4838 row_info->channels = 2; 4839 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); 4840 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 4841 row_width); 4842 } 4843 } 4844 else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) 4845 { 4846 if (row_info->bit_depth == 8) 4847 { 4848 png_byte red = (png_byte)(trans_color->red & 0xff); 4849 png_byte green = (png_byte)(trans_color->green & 0xff); 4850 png_byte blue = (png_byte)(trans_color->blue & 0xff); 4851 sp = row + (png_size_t)row_info->rowbytes - 1; 4852 dp = row + (png_size_t)(row_width << 2) - 1; 4853 for (i = 0; i < row_width; i++) 4854 { 4855 if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) 4856 *dp-- = 0; 4857 4858 else 4859 *dp-- = 0xff; 4860 4861 *dp-- = *sp--; 4862 *dp-- = *sp--; 4863 *dp-- = *sp--; 4864 } 4865 } 4866 else if (row_info->bit_depth == 16) 4867 { 4868 png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); 4869 png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); 4870 png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); 4871 png_byte red_low = (png_byte)(trans_color->red & 0xff); 4872 png_byte green_low = (png_byte)(trans_color->green & 0xff); 4873 png_byte blue_low = (png_byte)(trans_color->blue & 0xff); 4874 sp = row + row_info->rowbytes - 1; 4875 dp = row + (png_size_t)(row_width << 3) - 1; 4876 for (i = 0; i < row_width; i++) 4877 { 4878 if (*(sp - 5) == red_high && 4879 *(sp - 4) == red_low && 4880 *(sp - 3) == green_high && 4881 *(sp - 2) == green_low && 4882 *(sp - 1) == blue_high && 4883 *(sp ) == blue_low) 4884 { 4885 *dp-- = 0; 4886 *dp-- = 0; 4887 } 4888 4889 else 4890 { 4891 *dp-- = 0xff; 4892 *dp-- = 0xff; 4893 } 4894 4895 *dp-- = *sp--; 4896 *dp-- = *sp--; 4897 *dp-- = *sp--; 4898 *dp-- = *sp--; 4899 *dp-- = *sp--; 4900 *dp-- = *sp--; 4901 } 4902 } 4903 row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 4904 row_info->channels = 4; 4905 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); 4906 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4907 } 4908 } 4909} 4910#endif 4911 4912#ifdef PNG_READ_EXPAND_16_SUPPORTED 4913/* If the bit depth is 8 and the color type is not a palette type expand the 4914 * whole row to 16 bits. Has no effect otherwise. 4915 */ 4916void /* PRIVATE */ 4917png_do_expand_16(png_row_infop row_info, png_bytep row) 4918{ 4919 if (row_info->bit_depth == 8 && 4920 row_info->color_type != PNG_COLOR_TYPE_PALETTE) 4921 { 4922 /* The row have a sequence of bytes containing [0..255] and we need 4923 * to turn it into another row containing [0..65535], to do this we 4924 * calculate: 4925 * 4926 * (input / 255) * 65535 4927 * 4928 * Which happens to be exactly input * 257 and this can be achieved 4929 * simply by byte replication in place (copying backwards). 4930 */ 4931 png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ 4932 png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ 4933 while (dp > sp) 4934 dp[-2] = dp[-1] = *--sp, dp -= 2; 4935 4936 row_info->rowbytes *= 2; 4937 row_info->bit_depth = 16; 4938 row_info->pixel_depth = (png_byte)(row_info->channels * 16); 4939 } 4940} 4941#endif 4942 4943#ifdef PNG_READ_QUANTIZE_SUPPORTED 4944void /* PRIVATE */ 4945png_do_quantize(png_row_infop row_info, png_bytep row, 4946 png_const_bytep palette_lookup, png_const_bytep quantize_lookup) 4947{ 4948 png_bytep sp, dp; 4949 png_uint_32 i; 4950 png_uint_32 row_width=row_info->width; 4951 4952 png_debug(1, "in png_do_quantize"); 4953 4954 if (row_info->bit_depth == 8) 4955 { 4956 if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) 4957 { 4958 int r, g, b, p; 4959 sp = row; 4960 dp = row; 4961 for (i = 0; i < row_width; i++) 4962 { 4963 r = *sp++; 4964 g = *sp++; 4965 b = *sp++; 4966 4967 /* This looks real messy, but the compiler will reduce 4968 * it down to a reasonable formula. For example, with 4969 * 5 bits per color, we get: 4970 * p = (((r >> 3) & 0x1f) << 10) | 4971 * (((g >> 3) & 0x1f) << 5) | 4972 * ((b >> 3) & 0x1f); 4973 */ 4974 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 4975 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 4976 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 4977 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 4978 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 4979 (PNG_QUANTIZE_BLUE_BITS)) | 4980 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 4981 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 4982 4983 *dp++ = palette_lookup[p]; 4984 } 4985 4986 row_info->color_type = PNG_COLOR_TYPE_PALETTE; 4987 row_info->channels = 1; 4988 row_info->pixel_depth = row_info->bit_depth; 4989 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4990 } 4991 4992 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 4993 palette_lookup != NULL) 4994 { 4995 int r, g, b, p; 4996 sp = row; 4997 dp = row; 4998 for (i = 0; i < row_width; i++) 4999 { 5000 r = *sp++; 5001 g = *sp++; 5002 b = *sp++; 5003 sp++; 5004 5005 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 5006 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 5007 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 5008 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 5009 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 5010 (PNG_QUANTIZE_BLUE_BITS)) | 5011 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 5012 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 5013 5014 *dp++ = palette_lookup[p]; 5015 } 5016 5017 row_info->color_type = PNG_COLOR_TYPE_PALETTE; 5018 row_info->channels = 1; 5019 row_info->pixel_depth = row_info->bit_depth; 5020 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 5021 } 5022 5023 else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 5024 quantize_lookup) 5025 { 5026 sp = row; 5027 5028 for (i = 0; i < row_width; i++, sp++) 5029 { 5030 *sp = quantize_lookup[*sp]; 5031 } 5032 } 5033 } 5034} 5035#endif /* PNG_READ_QUANTIZE_SUPPORTED */ 5036#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 5037 5038#ifdef PNG_MNG_FEATURES_SUPPORTED 5039/* Undoes intrapixel differencing */ 5040void /* PRIVATE */ 5041png_do_read_intrapixel(png_row_infop row_info, png_bytep row) 5042{ 5043 png_debug(1, "in png_do_read_intrapixel"); 5044 5045 if ( 5046 (row_info->color_type & PNG_COLOR_MASK_COLOR)) 5047 { 5048 int bytes_per_pixel; 5049 png_uint_32 row_width = row_info->width; 5050 5051 if (row_info->bit_depth == 8) 5052 { 5053 png_bytep rp; 5054 png_uint_32 i; 5055 5056 if (row_info->color_type == PNG_COLOR_TYPE_RGB) 5057 bytes_per_pixel = 3; 5058 5059 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 5060 bytes_per_pixel = 4; 5061 5062 else 5063 return; 5064 5065 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 5066 { 5067 *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); 5068 *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); 5069 } 5070 } 5071 else if (row_info->bit_depth == 16) 5072 { 5073 png_bytep rp; 5074 png_uint_32 i; 5075 5076 if (row_info->color_type == PNG_COLOR_TYPE_RGB) 5077 bytes_per_pixel = 6; 5078 5079 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 5080 bytes_per_pixel = 8; 5081 5082 else 5083 return; 5084 5085 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 5086 { 5087 png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); 5088 png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); 5089 png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); 5090 png_uint_32 red = (s0 + s1 + 65536) & 0xffff; 5091 png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; 5092 *(rp ) = (png_byte)((red >> 8) & 0xff); 5093 *(rp + 1) = (png_byte)(red & 0xff); 5094 *(rp + 4) = (png_byte)((blue >> 8) & 0xff); 5095 *(rp + 5) = (png_byte)(blue & 0xff); 5096 } 5097 } 5098 } 5099} 5100#endif /* PNG_MNG_FEATURES_SUPPORTED */ 5101#endif /* PNG_READ_SUPPORTED */ 5102