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