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