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