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