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.35 [July 15, 2018] 33 * Copyright (c) 1998-2002,2004,2006-2018 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 accommodate 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 size_t num_entries = ((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 undesirable 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 meaningful 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 + (size_t)((row_width - 1) >> 3); 2183 png_bytep dp = row + (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 + (size_t)((row_width - 1) >> 2); 2207 png_bytep dp = row + (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 + (size_t)((row_width - 1) >> 1); 2230 png_bytep dp = row + (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_uint_32 row_width = row_info->width; 2495 2496 png_debug(1, "in png_do_read_swap_alpha"); 2497 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 #endif 2585 2586 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 2587 static void 2588 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) 2589 { 2590 png_uint_32 row_width; 2591 png_debug(1, "in png_do_read_invert_alpha"); 2592 2593 row_width = row_info->width; 2594 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 2595 { 2596 if (row_info->bit_depth == 8) 2597 { 2598 /* This inverts the alpha channel in RGBA */ 2599 png_bytep sp = row + row_info->rowbytes; 2600 png_bytep dp = sp; 2601 png_uint_32 i; 2602 2603 for (i = 0; i < row_width; i++) 2604 { 2605 *(--dp) = (png_byte)(255 - *(--sp)); 2606 2607 /* This does nothing: 2608 *(--dp) = *(--sp); 2609 *(--dp) = *(--sp); 2610 *(--dp) = *(--sp); 2611 We can replace it with: 2612 */ 2613 sp-=3; 2614 dp=sp; 2615 } 2616 } 2617 2618 #ifdef PNG_READ_16BIT_SUPPORTED 2619 /* This inverts the alpha channel in RRGGBBAA */ 2620 else 2621 { 2622 png_bytep sp = row + row_info->rowbytes; 2623 png_bytep dp = sp; 2624 png_uint_32 i; 2625 2626 for (i = 0; i < row_width; i++) 2627 { 2628 *(--dp) = (png_byte)(255 - *(--sp)); 2629 *(--dp) = (png_byte)(255 - *(--sp)); 2630 2631 /* This does nothing: 2632 *(--dp) = *(--sp); 2633 *(--dp) = *(--sp); 2634 *(--dp) = *(--sp); 2635 *(--dp) = *(--sp); 2636 *(--dp) = *(--sp); 2637 *(--dp) = *(--sp); 2638 We can replace it with: 2639 */ 2640 sp-=6; 2641 dp=sp; 2642 } 2643 } 2644 #endif 2645 } 2646 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2647 { 2648 if (row_info->bit_depth == 8) 2649 { 2650 /* This inverts the alpha channel in GA */ 2651 png_bytep sp = row + row_info->rowbytes; 2652 png_bytep dp = sp; 2653 png_uint_32 i; 2654 2655 for (i = 0; i < row_width; i++) 2656 { 2657 *(--dp) = (png_byte)(255 - *(--sp)); 2658 *(--dp) = *(--sp); 2659 } 2660 } 2661 2662 #ifdef PNG_READ_16BIT_SUPPORTED 2663 else 2664 { 2665 /* This inverts the alpha channel in GGAA */ 2666 png_bytep sp = row + row_info->rowbytes; 2667 png_bytep dp = sp; 2668 png_uint_32 i; 2669 2670 for (i = 0; i < row_width; i++) 2671 { 2672 *(--dp) = (png_byte)(255 - *(--sp)); 2673 *(--dp) = (png_byte)(255 - *(--sp)); 2674 /* 2675 *(--dp) = *(--sp); 2676 *(--dp) = *(--sp); 2677 */ 2678 sp-=2; 2679 dp=sp; 2680 } 2681 } 2682 #endif 2683 } 2684 } 2685 #endif 2686 2687 #ifdef PNG_READ_FILLER_SUPPORTED 2688 /* Add filler channel if we have RGB color */ 2689 static void 2690 png_do_read_filler(png_row_infop row_info, png_bytep row, 2691 png_uint_32 filler, png_uint_32 flags) 2692 { 2693 png_uint_32 i; 2694 png_uint_32 row_width = row_info->width; 2695 2696 #ifdef PNG_READ_16BIT_SUPPORTED 2697 png_byte hi_filler = (png_byte)(filler>>8); 2698 #endif 2699 png_byte lo_filler = (png_byte)filler; 2700 2701 png_debug(1, "in png_do_read_filler"); 2702 2703 if ( 2704 row_info->color_type == PNG_COLOR_TYPE_GRAY) 2705 { 2706 if (row_info->bit_depth == 8) 2707 { 2708 if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2709 { 2710 /* This changes the data from G to GX */ 2711 png_bytep sp = row + (size_t)row_width; 2712 png_bytep dp = sp + (size_t)row_width; 2713 for (i = 1; i < row_width; i++) 2714 { 2715 *(--dp) = lo_filler; 2716 *(--dp) = *(--sp); 2717 } 2718 *(--dp) = lo_filler; 2719 row_info->channels = 2; 2720 row_info->pixel_depth = 16; 2721 row_info->rowbytes = row_width * 2; 2722 } 2723 2724 else 2725 { 2726 /* This changes the data from G to XG */ 2727 png_bytep sp = row + (size_t)row_width; 2728 png_bytep dp = sp + (size_t)row_width; 2729 for (i = 0; i < row_width; i++) 2730 { 2731 *(--dp) = *(--sp); 2732 *(--dp) = lo_filler; 2733 } 2734 row_info->channels = 2; 2735 row_info->pixel_depth = 16; 2736 row_info->rowbytes = row_width * 2; 2737 } 2738 } 2739 2740 #ifdef PNG_READ_16BIT_SUPPORTED 2741 else if (row_info->bit_depth == 16) 2742 { 2743 if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2744 { 2745 /* This changes the data from GG to GGXX */ 2746 png_bytep sp = row + (size_t)row_width * 2; 2747 png_bytep dp = sp + (size_t)row_width * 2; 2748 for (i = 1; i < row_width; i++) 2749 { 2750 *(--dp) = lo_filler; 2751 *(--dp) = hi_filler; 2752 *(--dp) = *(--sp); 2753 *(--dp) = *(--sp); 2754 } 2755 *(--dp) = lo_filler; 2756 *(--dp) = hi_filler; 2757 row_info->channels = 2; 2758 row_info->pixel_depth = 32; 2759 row_info->rowbytes = row_width * 4; 2760 } 2761 2762 else 2763 { 2764 /* This changes the data from GG to XXGG */ 2765 png_bytep sp = row + (size_t)row_width * 2; 2766 png_bytep dp = sp + (size_t)row_width * 2; 2767 for (i = 0; i < row_width; i++) 2768 { 2769 *(--dp) = *(--sp); 2770 *(--dp) = *(--sp); 2771 *(--dp) = lo_filler; 2772 *(--dp) = hi_filler; 2773 } 2774 row_info->channels = 2; 2775 row_info->pixel_depth = 32; 2776 row_info->rowbytes = row_width * 4; 2777 } 2778 } 2779 #endif 2780 } /* COLOR_TYPE == GRAY */ 2781 else if (row_info->color_type == PNG_COLOR_TYPE_RGB) 2782 { 2783 if (row_info->bit_depth == 8) 2784 { 2785 if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2786 { 2787 /* This changes the data from RGB to RGBX */ 2788 png_bytep sp = row + (size_t)row_width * 3; 2789 png_bytep dp = sp + (size_t)row_width; 2790 for (i = 1; i < row_width; i++) 2791 { 2792 *(--dp) = lo_filler; 2793 *(--dp) = *(--sp); 2794 *(--dp) = *(--sp); 2795 *(--dp) = *(--sp); 2796 } 2797 *(--dp) = lo_filler; 2798 row_info->channels = 4; 2799 row_info->pixel_depth = 32; 2800 row_info->rowbytes = row_width * 4; 2801 } 2802 2803 else 2804 { 2805 /* This changes the data from RGB to XRGB */ 2806 png_bytep sp = row + (size_t)row_width * 3; 2807 png_bytep dp = sp + (size_t)row_width; 2808 for (i = 0; i < row_width; i++) 2809 { 2810 *(--dp) = *(--sp); 2811 *(--dp) = *(--sp); 2812 *(--dp) = *(--sp); 2813 *(--dp) = lo_filler; 2814 } 2815 row_info->channels = 4; 2816 row_info->pixel_depth = 32; 2817 row_info->rowbytes = row_width * 4; 2818 } 2819 } 2820 2821 #ifdef PNG_READ_16BIT_SUPPORTED 2822 else if (row_info->bit_depth == 16) 2823 { 2824 if ((flags & PNG_FLAG_FILLER_AFTER) != 0) 2825 { 2826 /* This changes the data from RRGGBB to RRGGBBXX */ 2827 png_bytep sp = row + (size_t)row_width * 6; 2828 png_bytep dp = sp + (size_t)row_width * 2; 2829 for (i = 1; i < row_width; i++) 2830 { 2831 *(--dp) = lo_filler; 2832 *(--dp) = hi_filler; 2833 *(--dp) = *(--sp); 2834 *(--dp) = *(--sp); 2835 *(--dp) = *(--sp); 2836 *(--dp) = *(--sp); 2837 *(--dp) = *(--sp); 2838 *(--dp) = *(--sp); 2839 } 2840 *(--dp) = lo_filler; 2841 *(--dp) = hi_filler; 2842 row_info->channels = 4; 2843 row_info->pixel_depth = 64; 2844 row_info->rowbytes = row_width * 8; 2845 } 2846 2847 else 2848 { 2849 /* This changes the data from RRGGBB to XXRRGGBB */ 2850 png_bytep sp = row + (size_t)row_width * 6; 2851 png_bytep dp = sp + (size_t)row_width * 2; 2852 for (i = 0; i < row_width; i++) 2853 { 2854 *(--dp) = *(--sp); 2855 *(--dp) = *(--sp); 2856 *(--dp) = *(--sp); 2857 *(--dp) = *(--sp); 2858 *(--dp) = *(--sp); 2859 *(--dp) = *(--sp); 2860 *(--dp) = lo_filler; 2861 *(--dp) = hi_filler; 2862 } 2863 2864 row_info->channels = 4; 2865 row_info->pixel_depth = 64; 2866 row_info->rowbytes = row_width * 8; 2867 } 2868 } 2869 #endif 2870 } /* COLOR_TYPE == RGB */ 2871 } 2872 #endif 2873 2874 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 2875 /* Expand grayscale files to RGB, with or without alpha */ 2876 static void 2877 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) 2878 { 2879 png_uint_32 i; 2880 png_uint_32 row_width = row_info->width; 2881 2882 png_debug(1, "in png_do_gray_to_rgb"); 2883 2884 if (row_info->bit_depth >= 8 && 2885 (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) 2886 { 2887 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 2888 { 2889 if (row_info->bit_depth == 8) 2890 { 2891 /* This changes G to RGB */ 2892 png_bytep sp = row + (size_t)row_width - 1; 2893 png_bytep dp = sp + (size_t)row_width * 2; 2894 for (i = 0; i < row_width; i++) 2895 { 2896 *(dp--) = *sp; 2897 *(dp--) = *sp; 2898 *(dp--) = *(sp--); 2899 } 2900 } 2901 2902 else 2903 { 2904 /* This changes GG to RRGGBB */ 2905 png_bytep sp = row + (size_t)row_width * 2 - 1; 2906 png_bytep dp = sp + (size_t)row_width * 4; 2907 for (i = 0; i < row_width; i++) 2908 { 2909 *(dp--) = *sp; 2910 *(dp--) = *(sp - 1); 2911 *(dp--) = *sp; 2912 *(dp--) = *(sp - 1); 2913 *(dp--) = *(sp--); 2914 *(dp--) = *(sp--); 2915 } 2916 } 2917 } 2918 2919 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 2920 { 2921 if (row_info->bit_depth == 8) 2922 { 2923 /* This changes GA to RGBA */ 2924 png_bytep sp = row + (size_t)row_width * 2 - 1; 2925 png_bytep dp = sp + (size_t)row_width * 2; 2926 for (i = 0; i < row_width; i++) 2927 { 2928 *(dp--) = *(sp--); 2929 *(dp--) = *sp; 2930 *(dp--) = *sp; 2931 *(dp--) = *(sp--); 2932 } 2933 } 2934 2935 else 2936 { 2937 /* This changes GGAA to RRGGBBAA */ 2938 png_bytep sp = row + (size_t)row_width * 4 - 1; 2939 png_bytep dp = sp + (size_t)row_width * 4; 2940 for (i = 0; i < row_width; i++) 2941 { 2942 *(dp--) = *(sp--); 2943 *(dp--) = *(sp--); 2944 *(dp--) = *sp; 2945 *(dp--) = *(sp - 1); 2946 *(dp--) = *sp; 2947 *(dp--) = *(sp - 1); 2948 *(dp--) = *(sp--); 2949 *(dp--) = *(sp--); 2950 } 2951 } 2952 } 2953 row_info->channels = (png_byte)(row_info->channels + 2); 2954 row_info->color_type |= PNG_COLOR_MASK_COLOR; 2955 row_info->pixel_depth = (png_byte)(row_info->channels * 2956 row_info->bit_depth); 2957 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 2958 } 2959 } 2960 #endif 2961 2962 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2963 /* Reduce RGB files to grayscale, with or without alpha 2964 * using the equation given in Poynton's ColorFAQ of 1998-01-04 at 2965 * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but 2966 * versions dated 1998 through November 2002 have been archived at 2967 * https://web.archive.org/web/20000816232553/www.inforamp.net/ 2968 * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) 2969 * Charles Poynton poynton at poynton.com 2970 * 2971 * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B 2972 * 2973 * which can be expressed with integers as 2974 * 2975 * Y = (6969 * R + 23434 * G + 2365 * B)/32768 2976 * 2977 * Poynton's current link (as of January 2003 through July 2011): 2978 * <http://www.poynton.com/notes/colour_and_gamma/> 2979 * has changed the numbers slightly: 2980 * 2981 * Y = 0.2126*R + 0.7152*G + 0.0722*B 2982 * 2983 * which can be expressed with integers as 2984 * 2985 * Y = (6966 * R + 23436 * G + 2366 * B)/32768 2986 * 2987 * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 2988 * end point chromaticities and the D65 white point. Depending on the 2989 * precision used for the D65 white point this produces a variety of different 2990 * numbers, however if the four decimal place value used in ITU-R Rec 709 is 2991 * used (0.3127,0.3290) the Y calculation would be: 2992 * 2993 * Y = (6968 * R + 23435 * G + 2366 * B)/32768 2994 * 2995 * While this is correct the rounding results in an overflow for white, because 2996 * the sum of the rounded coefficients is 32769, not 32768. Consequently 2997 * libpng uses, instead, the closest non-overflowing approximation: 2998 * 2999 * Y = (6968 * R + 23434 * G + 2366 * B)/32768 3000 * 3001 * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk 3002 * (including an sRGB chunk) then the chromaticities are used to calculate the 3003 * coefficients. See the chunk handling in pngrutil.c for more information. 3004 * 3005 * In all cases the calculation is to be done in a linear colorspace. If no 3006 * gamma information is available to correct the encoding of the original RGB 3007 * values this results in an implicit assumption that the original PNG RGB 3008 * values were linear. 3009 * 3010 * Other integer coefficients can be used via png_set_rgb_to_gray(). Because 3011 * the API takes just red and green coefficients the blue coefficient is 3012 * calculated to make the sum 32768. This will result in different rounding 3013 * to that used above. 3014 */ 3015 static int 3016 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) 3017 3018 { 3019 int rgb_error = 0; 3020 3021 png_debug(1, "in png_do_rgb_to_gray"); 3022 3023 if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && 3024 (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) 3025 { 3026 PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; 3027 PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; 3028 PNG_CONST png_uint_32 bc = 32768 - rc - gc; 3029 PNG_CONST png_uint_32 row_width = row_info->width; 3030 PNG_CONST int have_alpha = 3031 (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; 3032 3033 if (row_info->bit_depth == 8) 3034 { 3035 #ifdef PNG_READ_GAMMA_SUPPORTED 3036 /* Notice that gamma to/from 1 are not necessarily inverses (if 3037 * there is an overall gamma correction). Prior to 1.5.5 this code 3038 * checked the linearized values for equality; this doesn't match 3039 * the documentation, the original values must be checked. 3040 */ 3041 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) 3042 { 3043 png_bytep sp = row; 3044 png_bytep dp = row; 3045 png_uint_32 i; 3046 3047 for (i = 0; i < row_width; i++) 3048 { 3049 png_byte red = *(sp++); 3050 png_byte green = *(sp++); 3051 png_byte blue = *(sp++); 3052 3053 if (red != green || red != blue) 3054 { 3055 red = png_ptr->gamma_to_1[red]; 3056 green = png_ptr->gamma_to_1[green]; 3057 blue = png_ptr->gamma_to_1[blue]; 3058 3059 rgb_error |= 1; 3060 *(dp++) = png_ptr->gamma_from_1[ 3061 (rc*red + gc*green + bc*blue + 16384)>>15]; 3062 } 3063 3064 else 3065 { 3066 /* If there is no overall correction the table will not be 3067 * set. 3068 */ 3069 if (png_ptr->gamma_table != NULL) 3070 red = png_ptr->gamma_table[red]; 3071 3072 *(dp++) = red; 3073 } 3074 3075 if (have_alpha != 0) 3076 *(dp++) = *(sp++); 3077 } 3078 } 3079 else 3080 #endif 3081 { 3082 png_bytep sp = row; 3083 png_bytep dp = row; 3084 png_uint_32 i; 3085 3086 for (i = 0; i < row_width; i++) 3087 { 3088 png_byte red = *(sp++); 3089 png_byte green = *(sp++); 3090 png_byte blue = *(sp++); 3091 3092 if (red != green || red != blue) 3093 { 3094 rgb_error |= 1; 3095 /* NOTE: this is the historical approach which simply 3096 * truncates the results. 3097 */ 3098 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); 3099 } 3100 3101 else 3102 *(dp++) = red; 3103 3104 if (have_alpha != 0) 3105 *(dp++) = *(sp++); 3106 } 3107 } 3108 } 3109 3110 else /* RGB bit_depth == 16 */ 3111 { 3112 #ifdef PNG_READ_GAMMA_SUPPORTED 3113 if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) 3114 { 3115 png_bytep sp = row; 3116 png_bytep dp = row; 3117 png_uint_32 i; 3118 3119 for (i = 0; i < row_width; i++) 3120 { 3121 png_uint_16 red, green, blue, w; 3122 png_byte hi,lo; 3123 3124 hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); 3125 hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); 3126 hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); 3127 3128 if (red == green && red == blue) 3129 { 3130 if (png_ptr->gamma_16_table != NULL) 3131 w = png_ptr->gamma_16_table[(red & 0xff) 3132 >> png_ptr->gamma_shift][red >> 8]; 3133 3134 else 3135 w = red; 3136 } 3137 3138 else 3139 { 3140 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff) 3141 >> png_ptr->gamma_shift][red>>8]; 3142 png_uint_16 green_1 = 3143 png_ptr->gamma_16_to_1[(green & 0xff) >> 3144 png_ptr->gamma_shift][green>>8]; 3145 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff) 3146 >> png_ptr->gamma_shift][blue>>8]; 3147 png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 3148 + bc*blue_1 + 16384)>>15); 3149 w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >> 3150 png_ptr->gamma_shift][gray16 >> 8]; 3151 rgb_error |= 1; 3152 } 3153 3154 *(dp++) = (png_byte)((w>>8) & 0xff); 3155 *(dp++) = (png_byte)(w & 0xff); 3156 3157 if (have_alpha != 0) 3158 { 3159 *(dp++) = *(sp++); 3160 *(dp++) = *(sp++); 3161 } 3162 } 3163 } 3164 else 3165 #endif 3166 { 3167 png_bytep sp = row; 3168 png_bytep dp = row; 3169 png_uint_32 i; 3170 3171 for (i = 0; i < row_width; i++) 3172 { 3173 png_uint_16 red, green, blue, gray16; 3174 png_byte hi,lo; 3175 3176 hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); 3177 hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); 3178 hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); 3179 3180 if (red != green || red != blue) 3181 rgb_error |= 1; 3182 3183 /* From 1.5.5 in the 16-bit case do the accurate conversion even 3184 * in the 'fast' case - this is because this is where the code 3185 * ends up when handling linear 16-bit data. 3186 */ 3187 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> 3188 15); 3189 *(dp++) = (png_byte)((gray16 >> 8) & 0xff); 3190 *(dp++) = (png_byte)(gray16 & 0xff); 3191 3192 if (have_alpha != 0) 3193 { 3194 *(dp++) = *(sp++); 3195 *(dp++) = *(sp++); 3196 } 3197 } 3198 } 3199 } 3200 3201 row_info->channels = (png_byte)(row_info->channels - 2); 3202 row_info->color_type = (png_byte)(row_info->color_type & 3203 ~PNG_COLOR_MASK_COLOR); 3204 row_info->pixel_depth = (png_byte)(row_info->channels * 3205 row_info->bit_depth); 3206 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 3207 } 3208 return rgb_error; 3209 } 3210 #endif 3211 3212 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 3213 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 3214 /* Replace any alpha or transparency with the supplied background color. 3215 * "background" is already in the screen gamma, while "background_1" is 3216 * at a gamma of 1.0. Paletted files have already been taken care of. 3217 */ 3218 static void 3219 png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 3220 { 3221 #ifdef PNG_READ_GAMMA_SUPPORTED 3222 png_const_bytep gamma_table = png_ptr->gamma_table; 3223 png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; 3224 png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; 3225 png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; 3226 png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; 3227 png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; 3228 int gamma_shift = png_ptr->gamma_shift; 3229 int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; 3230 #endif 3231 3232 png_bytep sp; 3233 png_uint_32 i; 3234 png_uint_32 row_width = row_info->width; 3235 int shift; 3236 3237 png_debug(1, "in png_do_compose"); 3238 3239 switch (row_info->color_type) 3240 { 3241 case PNG_COLOR_TYPE_GRAY: 3242 { 3243 switch (row_info->bit_depth) 3244 { 3245 case 1: 3246 { 3247 sp = row; 3248 shift = 7; 3249 for (i = 0; i < row_width; i++) 3250 { 3251 if ((png_uint_16)((*sp >> shift) & 0x01) 3252 == png_ptr->trans_color.gray) 3253 { 3254 unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); 3255 tmp |= 3256 (unsigned int)(png_ptr->background.gray << shift); 3257 *sp = (png_byte)(tmp & 0xff); 3258 } 3259 3260 if (shift == 0) 3261 { 3262 shift = 7; 3263 sp++; 3264 } 3265 3266 else 3267 shift--; 3268 } 3269 break; 3270 } 3271 3272 case 2: 3273 { 3274 #ifdef PNG_READ_GAMMA_SUPPORTED 3275 if (gamma_table != NULL) 3276 { 3277 sp = row; 3278 shift = 6; 3279 for (i = 0; i < row_width; i++) 3280 { 3281 if ((png_uint_16)((*sp >> shift) & 0x03) 3282 == png_ptr->trans_color.gray) 3283 { 3284 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3285 tmp |= 3286 (unsigned int)png_ptr->background.gray << shift; 3287 *sp = (png_byte)(tmp & 0xff); 3288 } 3289 3290 else 3291 { 3292 unsigned int p = (*sp >> shift) & 0x03; 3293 unsigned int g = (gamma_table [p | (p << 2) | 3294 (p << 4) | (p << 6)] >> 6) & 0x03; 3295 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3296 tmp |= (unsigned int)(g << shift); 3297 *sp = (png_byte)(tmp & 0xff); 3298 } 3299 3300 if (shift == 0) 3301 { 3302 shift = 6; 3303 sp++; 3304 } 3305 3306 else 3307 shift -= 2; 3308 } 3309 } 3310 3311 else 3312 #endif 3313 { 3314 sp = row; 3315 shift = 6; 3316 for (i = 0; i < row_width; i++) 3317 { 3318 if ((png_uint_16)((*sp >> shift) & 0x03) 3319 == png_ptr->trans_color.gray) 3320 { 3321 unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); 3322 tmp |= 3323 (unsigned int)png_ptr->background.gray << shift; 3324 *sp = (png_byte)(tmp & 0xff); 3325 } 3326 3327 if (shift == 0) 3328 { 3329 shift = 6; 3330 sp++; 3331 } 3332 3333 else 3334 shift -= 2; 3335 } 3336 } 3337 break; 3338 } 3339 3340 case 4: 3341 { 3342 #ifdef PNG_READ_GAMMA_SUPPORTED 3343 if (gamma_table != NULL) 3344 { 3345 sp = row; 3346 shift = 4; 3347 for (i = 0; i < row_width; i++) 3348 { 3349 if ((png_uint_16)((*sp >> shift) & 0x0f) 3350 == png_ptr->trans_color.gray) 3351 { 3352 unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); 3353 tmp |= 3354 (unsigned int)(png_ptr->background.gray << shift); 3355 *sp = (png_byte)(tmp & 0xff); 3356 } 3357 3358 else 3359 { 3360 unsigned int p = (*sp >> shift) & 0x0f; 3361 unsigned int g = (gamma_table[p | (p << 4)] >> 4) & 3362 0x0f; 3363 unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); 3364 tmp |= (unsigned int)(g << shift); 3365 *sp = (png_byte)(tmp & 0xff); 3366 } 3367 3368 if (shift == 0) 3369 { 3370 shift = 4; 3371 sp++; 3372 } 3373 3374 else 3375 shift -= 4; 3376 } 3377 } 3378 3379 else 3380 #endif 3381 { 3382 sp = row; 3383 shift = 4; 3384 for (i = 0; i < row_width; i++) 3385 { 3386 if ((png_uint_16)((*sp >> shift) & 0x0f) 3387 == png_ptr->trans_color.gray) 3388 { 3389 unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); 3390 tmp |= 3391 (unsigned int)(png_ptr->background.gray << shift); 3392 *sp = (png_byte)(tmp & 0xff); 3393 } 3394 3395 if (shift == 0) 3396 { 3397 shift = 4; 3398 sp++; 3399 } 3400 3401 else 3402 shift -= 4; 3403 } 3404 } 3405 break; 3406 } 3407 3408 case 8: 3409 { 3410 #ifdef PNG_READ_GAMMA_SUPPORTED 3411 if (gamma_table != NULL) 3412 { 3413 sp = row; 3414 for (i = 0; i < row_width; i++, sp++) 3415 { 3416 if (*sp == png_ptr->trans_color.gray) 3417 *sp = (png_byte)png_ptr->background.gray; 3418 3419 else 3420 *sp = gamma_table[*sp]; 3421 } 3422 } 3423 else 3424 #endif 3425 { 3426 sp = row; 3427 for (i = 0; i < row_width; i++, sp++) 3428 { 3429 if (*sp == png_ptr->trans_color.gray) 3430 *sp = (png_byte)png_ptr->background.gray; 3431 } 3432 } 3433 break; 3434 } 3435 3436 case 16: 3437 { 3438 #ifdef PNG_READ_GAMMA_SUPPORTED 3439 if (gamma_16 != NULL) 3440 { 3441 sp = row; 3442 for (i = 0; i < row_width; i++, sp += 2) 3443 { 3444 png_uint_16 v; 3445 3446 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3447 3448 if (v == png_ptr->trans_color.gray) 3449 { 3450 /* Background is already in screen gamma */ 3451 *sp = (png_byte)((png_ptr->background.gray >> 8) 3452 & 0xff); 3453 *(sp + 1) = (png_byte)(png_ptr->background.gray 3454 & 0xff); 3455 } 3456 3457 else 3458 { 3459 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3460 *sp = (png_byte)((v >> 8) & 0xff); 3461 *(sp + 1) = (png_byte)(v & 0xff); 3462 } 3463 } 3464 } 3465 else 3466 #endif 3467 { 3468 sp = row; 3469 for (i = 0; i < row_width; i++, sp += 2) 3470 { 3471 png_uint_16 v; 3472 3473 v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3474 3475 if (v == png_ptr->trans_color.gray) 3476 { 3477 *sp = (png_byte)((png_ptr->background.gray >> 8) 3478 & 0xff); 3479 *(sp + 1) = (png_byte)(png_ptr->background.gray 3480 & 0xff); 3481 } 3482 } 3483 } 3484 break; 3485 } 3486 3487 default: 3488 break; 3489 } 3490 break; 3491 } 3492 3493 case PNG_COLOR_TYPE_RGB: 3494 { 3495 if (row_info->bit_depth == 8) 3496 { 3497 #ifdef PNG_READ_GAMMA_SUPPORTED 3498 if (gamma_table != NULL) 3499 { 3500 sp = row; 3501 for (i = 0; i < row_width; i++, sp += 3) 3502 { 3503 if (*sp == png_ptr->trans_color.red && 3504 *(sp + 1) == png_ptr->trans_color.green && 3505 *(sp + 2) == png_ptr->trans_color.blue) 3506 { 3507 *sp = (png_byte)png_ptr->background.red; 3508 *(sp + 1) = (png_byte)png_ptr->background.green; 3509 *(sp + 2) = (png_byte)png_ptr->background.blue; 3510 } 3511 3512 else 3513 { 3514 *sp = gamma_table[*sp]; 3515 *(sp + 1) = gamma_table[*(sp + 1)]; 3516 *(sp + 2) = gamma_table[*(sp + 2)]; 3517 } 3518 } 3519 } 3520 else 3521 #endif 3522 { 3523 sp = row; 3524 for (i = 0; i < row_width; i++, sp += 3) 3525 { 3526 if (*sp == png_ptr->trans_color.red && 3527 *(sp + 1) == png_ptr->trans_color.green && 3528 *(sp + 2) == png_ptr->trans_color.blue) 3529 { 3530 *sp = (png_byte)png_ptr->background.red; 3531 *(sp + 1) = (png_byte)png_ptr->background.green; 3532 *(sp + 2) = (png_byte)png_ptr->background.blue; 3533 } 3534 } 3535 } 3536 } 3537 else /* if (row_info->bit_depth == 16) */ 3538 { 3539 #ifdef PNG_READ_GAMMA_SUPPORTED 3540 if (gamma_16 != NULL) 3541 { 3542 sp = row; 3543 for (i = 0; i < row_width; i++, sp += 6) 3544 { 3545 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3546 3547 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3548 + *(sp + 3)); 3549 3550 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3551 + *(sp + 5)); 3552 3553 if (r == png_ptr->trans_color.red && 3554 g == png_ptr->trans_color.green && 3555 b == png_ptr->trans_color.blue) 3556 { 3557 /* Background is already in screen gamma */ 3558 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3559 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3560 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3561 & 0xff); 3562 *(sp + 3) = (png_byte)(png_ptr->background.green 3563 & 0xff); 3564 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3565 & 0xff); 3566 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3567 } 3568 3569 else 3570 { 3571 png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3572 *sp = (png_byte)((v >> 8) & 0xff); 3573 *(sp + 1) = (png_byte)(v & 0xff); 3574 3575 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3576 *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3577 *(sp + 3) = (png_byte)(v & 0xff); 3578 3579 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3580 *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3581 *(sp + 5) = (png_byte)(v & 0xff); 3582 } 3583 } 3584 } 3585 3586 else 3587 #endif 3588 { 3589 sp = row; 3590 for (i = 0; i < row_width; i++, sp += 6) 3591 { 3592 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3593 3594 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3595 + *(sp + 3)); 3596 3597 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3598 + *(sp + 5)); 3599 3600 if (r == png_ptr->trans_color.red && 3601 g == png_ptr->trans_color.green && 3602 b == png_ptr->trans_color.blue) 3603 { 3604 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3605 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3606 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3607 & 0xff); 3608 *(sp + 3) = (png_byte)(png_ptr->background.green 3609 & 0xff); 3610 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3611 & 0xff); 3612 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3613 } 3614 } 3615 } 3616 } 3617 break; 3618 } 3619 3620 case PNG_COLOR_TYPE_GRAY_ALPHA: 3621 { 3622 if (row_info->bit_depth == 8) 3623 { 3624 #ifdef PNG_READ_GAMMA_SUPPORTED 3625 if (gamma_to_1 != NULL && gamma_from_1 != NULL && 3626 gamma_table != NULL) 3627 { 3628 sp = row; 3629 for (i = 0; i < row_width; i++, sp += 2) 3630 { 3631 png_uint_16 a = *(sp + 1); 3632 3633 if (a == 0xff) 3634 *sp = gamma_table[*sp]; 3635 3636 else if (a == 0) 3637 { 3638 /* Background is already in screen gamma */ 3639 *sp = (png_byte)png_ptr->background.gray; 3640 } 3641 3642 else 3643 { 3644 png_byte v, w; 3645 3646 v = gamma_to_1[*sp]; 3647 png_composite(w, v, a, png_ptr->background_1.gray); 3648 if (optimize == 0) 3649 w = gamma_from_1[w]; 3650 *sp = w; 3651 } 3652 } 3653 } 3654 else 3655 #endif 3656 { 3657 sp = row; 3658 for (i = 0; i < row_width; i++, sp += 2) 3659 { 3660 png_byte a = *(sp + 1); 3661 3662 if (a == 0) 3663 *sp = (png_byte)png_ptr->background.gray; 3664 3665 else if (a < 0xff) 3666 png_composite(*sp, *sp, a, png_ptr->background.gray); 3667 } 3668 } 3669 } 3670 else /* if (png_ptr->bit_depth == 16) */ 3671 { 3672 #ifdef PNG_READ_GAMMA_SUPPORTED 3673 if (gamma_16 != NULL && gamma_16_from_1 != NULL && 3674 gamma_16_to_1 != NULL) 3675 { 3676 sp = row; 3677 for (i = 0; i < row_width; i++, sp += 4) 3678 { 3679 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 3680 + *(sp + 3)); 3681 3682 if (a == (png_uint_16)0xffff) 3683 { 3684 png_uint_16 v; 3685 3686 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3687 *sp = (png_byte)((v >> 8) & 0xff); 3688 *(sp + 1) = (png_byte)(v & 0xff); 3689 } 3690 3691 else if (a == 0) 3692 { 3693 /* Background is already in screen gamma */ 3694 *sp = (png_byte)((png_ptr->background.gray >> 8) 3695 & 0xff); 3696 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 3697 } 3698 3699 else 3700 { 3701 png_uint_16 g, v, w; 3702 3703 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 3704 png_composite_16(v, g, a, png_ptr->background_1.gray); 3705 if (optimize != 0) 3706 w = v; 3707 else 3708 w = gamma_16_from_1[(v & 0xff) >> 3709 gamma_shift][v >> 8]; 3710 *sp = (png_byte)((w >> 8) & 0xff); 3711 *(sp + 1) = (png_byte)(w & 0xff); 3712 } 3713 } 3714 } 3715 else 3716 #endif 3717 { 3718 sp = row; 3719 for (i = 0; i < row_width; i++, sp += 4) 3720 { 3721 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) 3722 + *(sp + 3)); 3723 3724 if (a == 0) 3725 { 3726 *sp = (png_byte)((png_ptr->background.gray >> 8) 3727 & 0xff); 3728 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); 3729 } 3730 3731 else if (a < 0xffff) 3732 { 3733 png_uint_16 g, v; 3734 3735 g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3736 png_composite_16(v, g, a, png_ptr->background.gray); 3737 *sp = (png_byte)((v >> 8) & 0xff); 3738 *(sp + 1) = (png_byte)(v & 0xff); 3739 } 3740 } 3741 } 3742 } 3743 break; 3744 } 3745 3746 case PNG_COLOR_TYPE_RGB_ALPHA: 3747 { 3748 if (row_info->bit_depth == 8) 3749 { 3750 #ifdef PNG_READ_GAMMA_SUPPORTED 3751 if (gamma_to_1 != NULL && gamma_from_1 != NULL && 3752 gamma_table != NULL) 3753 { 3754 sp = row; 3755 for (i = 0; i < row_width; i++, sp += 4) 3756 { 3757 png_byte a = *(sp + 3); 3758 3759 if (a == 0xff) 3760 { 3761 *sp = gamma_table[*sp]; 3762 *(sp + 1) = gamma_table[*(sp + 1)]; 3763 *(sp + 2) = gamma_table[*(sp + 2)]; 3764 } 3765 3766 else if (a == 0) 3767 { 3768 /* Background is already in screen gamma */ 3769 *sp = (png_byte)png_ptr->background.red; 3770 *(sp + 1) = (png_byte)png_ptr->background.green; 3771 *(sp + 2) = (png_byte)png_ptr->background.blue; 3772 } 3773 3774 else 3775 { 3776 png_byte v, w; 3777 3778 v = gamma_to_1[*sp]; 3779 png_composite(w, v, a, png_ptr->background_1.red); 3780 if (optimize == 0) w = gamma_from_1[w]; 3781 *sp = w; 3782 3783 v = gamma_to_1[*(sp + 1)]; 3784 png_composite(w, v, a, png_ptr->background_1.green); 3785 if (optimize == 0) w = gamma_from_1[w]; 3786 *(sp + 1) = w; 3787 3788 v = gamma_to_1[*(sp + 2)]; 3789 png_composite(w, v, a, png_ptr->background_1.blue); 3790 if (optimize == 0) w = gamma_from_1[w]; 3791 *(sp + 2) = w; 3792 } 3793 } 3794 } 3795 else 3796 #endif 3797 { 3798 sp = row; 3799 for (i = 0; i < row_width; i++, sp += 4) 3800 { 3801 png_byte a = *(sp + 3); 3802 3803 if (a == 0) 3804 { 3805 *sp = (png_byte)png_ptr->background.red; 3806 *(sp + 1) = (png_byte)png_ptr->background.green; 3807 *(sp + 2) = (png_byte)png_ptr->background.blue; 3808 } 3809 3810 else if (a < 0xff) 3811 { 3812 png_composite(*sp, *sp, a, png_ptr->background.red); 3813 3814 png_composite(*(sp + 1), *(sp + 1), a, 3815 png_ptr->background.green); 3816 3817 png_composite(*(sp + 2), *(sp + 2), a, 3818 png_ptr->background.blue); 3819 } 3820 } 3821 } 3822 } 3823 else /* if (row_info->bit_depth == 16) */ 3824 { 3825 #ifdef PNG_READ_GAMMA_SUPPORTED 3826 if (gamma_16 != NULL && gamma_16_from_1 != NULL && 3827 gamma_16_to_1 != NULL) 3828 { 3829 sp = row; 3830 for (i = 0; i < row_width; i++, sp += 8) 3831 { 3832 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 3833 << 8) + (png_uint_16)(*(sp + 7))); 3834 3835 if (a == (png_uint_16)0xffff) 3836 { 3837 png_uint_16 v; 3838 3839 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; 3840 *sp = (png_byte)((v >> 8) & 0xff); 3841 *(sp + 1) = (png_byte)(v & 0xff); 3842 3843 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3844 *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3845 *(sp + 3) = (png_byte)(v & 0xff); 3846 3847 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3848 *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3849 *(sp + 5) = (png_byte)(v & 0xff); 3850 } 3851 3852 else if (a == 0) 3853 { 3854 /* Background is already in screen gamma */ 3855 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3856 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3857 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3858 & 0xff); 3859 *(sp + 3) = (png_byte)(png_ptr->background.green 3860 & 0xff); 3861 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3862 & 0xff); 3863 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3864 } 3865 3866 else 3867 { 3868 png_uint_16 v, w; 3869 3870 v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; 3871 png_composite_16(w, v, a, png_ptr->background_1.red); 3872 if (optimize == 0) 3873 w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> 3874 8]; 3875 *sp = (png_byte)((w >> 8) & 0xff); 3876 *(sp + 1) = (png_byte)(w & 0xff); 3877 3878 v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; 3879 png_composite_16(w, v, a, png_ptr->background_1.green); 3880 if (optimize == 0) 3881 w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> 3882 8]; 3883 3884 *(sp + 2) = (png_byte)((w >> 8) & 0xff); 3885 *(sp + 3) = (png_byte)(w & 0xff); 3886 3887 v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; 3888 png_composite_16(w, v, a, png_ptr->background_1.blue); 3889 if (optimize == 0) 3890 w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> 3891 8]; 3892 3893 *(sp + 4) = (png_byte)((w >> 8) & 0xff); 3894 *(sp + 5) = (png_byte)(w & 0xff); 3895 } 3896 } 3897 } 3898 3899 else 3900 #endif 3901 { 3902 sp = row; 3903 for (i = 0; i < row_width; i++, sp += 8) 3904 { 3905 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) 3906 << 8) + (png_uint_16)(*(sp + 7))); 3907 3908 if (a == 0) 3909 { 3910 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); 3911 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); 3912 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) 3913 & 0xff); 3914 *(sp + 3) = (png_byte)(png_ptr->background.green 3915 & 0xff); 3916 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) 3917 & 0xff); 3918 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); 3919 } 3920 3921 else if (a < 0xffff) 3922 { 3923 png_uint_16 v; 3924 3925 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); 3926 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) 3927 + *(sp + 3)); 3928 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) 3929 + *(sp + 5)); 3930 3931 png_composite_16(v, r, a, png_ptr->background.red); 3932 *sp = (png_byte)((v >> 8) & 0xff); 3933 *(sp + 1) = (png_byte)(v & 0xff); 3934 3935 png_composite_16(v, g, a, png_ptr->background.green); 3936 *(sp + 2) = (png_byte)((v >> 8) & 0xff); 3937 *(sp + 3) = (png_byte)(v & 0xff); 3938 3939 png_composite_16(v, b, a, png_ptr->background.blue); 3940 *(sp + 4) = (png_byte)((v >> 8) & 0xff); 3941 *(sp + 5) = (png_byte)(v & 0xff); 3942 } 3943 } 3944 } 3945 } 3946 break; 3947 } 3948 3949 default: 3950 break; 3951 } 3952 } 3953 #endif /* READ_BACKGROUND || READ_ALPHA_MODE */ 3954 3955 #ifdef PNG_READ_GAMMA_SUPPORTED 3956 /* Gamma correct the image, avoiding the alpha channel. Make sure 3957 * you do this after you deal with the transparency issue on grayscale 3958 * or RGB images. If your bit depth is 8, use gamma_table, if it 3959 * is 16, use gamma_16_table and gamma_shift. Build these with 3960 * build_gamma_table(). 3961 */ 3962 static void 3963 png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 3964 { 3965 png_const_bytep gamma_table = png_ptr->gamma_table; 3966 png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; 3967 int gamma_shift = png_ptr->gamma_shift; 3968 3969 png_bytep sp; 3970 png_uint_32 i; 3971 png_uint_32 row_width=row_info->width; 3972 3973 png_debug(1, "in png_do_gamma"); 3974 3975 if (((row_info->bit_depth <= 8 && gamma_table != NULL) || 3976 (row_info->bit_depth == 16 && gamma_16_table != NULL))) 3977 { 3978 switch (row_info->color_type) 3979 { 3980 case PNG_COLOR_TYPE_RGB: 3981 { 3982 if (row_info->bit_depth == 8) 3983 { 3984 sp = row; 3985 for (i = 0; i < row_width; i++) 3986 { 3987 *sp = gamma_table[*sp]; 3988 sp++; 3989 *sp = gamma_table[*sp]; 3990 sp++; 3991 *sp = gamma_table[*sp]; 3992 sp++; 3993 } 3994 } 3995 3996 else /* if (row_info->bit_depth == 16) */ 3997 { 3998 sp = row; 3999 for (i = 0; i < row_width; i++) 4000 { 4001 png_uint_16 v; 4002 4003 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4004 *sp = (png_byte)((v >> 8) & 0xff); 4005 *(sp + 1) = (png_byte)(v & 0xff); 4006 sp += 2; 4007 4008 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4009 *sp = (png_byte)((v >> 8) & 0xff); 4010 *(sp + 1) = (png_byte)(v & 0xff); 4011 sp += 2; 4012 4013 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4014 *sp = (png_byte)((v >> 8) & 0xff); 4015 *(sp + 1) = (png_byte)(v & 0xff); 4016 sp += 2; 4017 } 4018 } 4019 break; 4020 } 4021 4022 case PNG_COLOR_TYPE_RGB_ALPHA: 4023 { 4024 if (row_info->bit_depth == 8) 4025 { 4026 sp = row; 4027 for (i = 0; i < row_width; i++) 4028 { 4029 *sp = gamma_table[*sp]; 4030 sp++; 4031 4032 *sp = gamma_table[*sp]; 4033 sp++; 4034 4035 *sp = gamma_table[*sp]; 4036 sp++; 4037 4038 sp++; 4039 } 4040 } 4041 4042 else /* if (row_info->bit_depth == 16) */ 4043 { 4044 sp = row; 4045 for (i = 0; i < row_width; i++) 4046 { 4047 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4048 *sp = (png_byte)((v >> 8) & 0xff); 4049 *(sp + 1) = (png_byte)(v & 0xff); 4050 sp += 2; 4051 4052 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4053 *sp = (png_byte)((v >> 8) & 0xff); 4054 *(sp + 1) = (png_byte)(v & 0xff); 4055 sp += 2; 4056 4057 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4058 *sp = (png_byte)((v >> 8) & 0xff); 4059 *(sp + 1) = (png_byte)(v & 0xff); 4060 sp += 4; 4061 } 4062 } 4063 break; 4064 } 4065 4066 case PNG_COLOR_TYPE_GRAY_ALPHA: 4067 { 4068 if (row_info->bit_depth == 8) 4069 { 4070 sp = row; 4071 for (i = 0; i < row_width; i++) 4072 { 4073 *sp = gamma_table[*sp]; 4074 sp += 2; 4075 } 4076 } 4077 4078 else /* if (row_info->bit_depth == 16) */ 4079 { 4080 sp = row; 4081 for (i = 0; i < row_width; i++) 4082 { 4083 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4084 *sp = (png_byte)((v >> 8) & 0xff); 4085 *(sp + 1) = (png_byte)(v & 0xff); 4086 sp += 4; 4087 } 4088 } 4089 break; 4090 } 4091 4092 case PNG_COLOR_TYPE_GRAY: 4093 { 4094 if (row_info->bit_depth == 2) 4095 { 4096 sp = row; 4097 for (i = 0; i < row_width; i += 4) 4098 { 4099 int a = *sp & 0xc0; 4100 int b = *sp & 0x30; 4101 int c = *sp & 0x0c; 4102 int d = *sp & 0x03; 4103 4104 *sp = (png_byte)( 4105 ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| 4106 ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| 4107 ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| 4108 ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); 4109 sp++; 4110 } 4111 } 4112 4113 if (row_info->bit_depth == 4) 4114 { 4115 sp = row; 4116 for (i = 0; i < row_width; i += 2) 4117 { 4118 int msb = *sp & 0xf0; 4119 int lsb = *sp & 0x0f; 4120 4121 *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) 4122 | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); 4123 sp++; 4124 } 4125 } 4126 4127 else if (row_info->bit_depth == 8) 4128 { 4129 sp = row; 4130 for (i = 0; i < row_width; i++) 4131 { 4132 *sp = gamma_table[*sp]; 4133 sp++; 4134 } 4135 } 4136 4137 else if (row_info->bit_depth == 16) 4138 { 4139 sp = row; 4140 for (i = 0; i < row_width; i++) 4141 { 4142 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; 4143 *sp = (png_byte)((v >> 8) & 0xff); 4144 *(sp + 1) = (png_byte)(v & 0xff); 4145 sp += 2; 4146 } 4147 } 4148 break; 4149 } 4150 4151 default: 4152 break; 4153 } 4154 } 4155 } 4156 #endif 4157 4158 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 4159 /* Encode the alpha channel to the output gamma (the input channel is always 4160 * linear.) Called only with color types that have an alpha channel. Needs the 4161 * from_1 tables. 4162 */ 4163 static void 4164 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) 4165 { 4166 png_uint_32 row_width = row_info->width; 4167 4168 png_debug(1, "in png_do_encode_alpha"); 4169 4170 if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) 4171 { 4172 if (row_info->bit_depth == 8) 4173 { 4174 PNG_CONST png_bytep table = png_ptr->gamma_from_1; 4175 4176 if (table != NULL) 4177 { 4178 PNG_CONST int step = 4179 (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; 4180 4181 /* The alpha channel is the last component: */ 4182 row += step - 1; 4183 4184 for (; row_width > 0; --row_width, row += step) 4185 *row = table[*row]; 4186 4187 return; 4188 } 4189 } 4190 4191 else if (row_info->bit_depth == 16) 4192 { 4193 PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; 4194 PNG_CONST int gamma_shift = png_ptr->gamma_shift; 4195 4196 if (table != NULL) 4197 { 4198 PNG_CONST int step = 4199 (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; 4200 4201 /* The alpha channel is the last component: */ 4202 row += step - 2; 4203 4204 for (; row_width > 0; --row_width, row += step) 4205 { 4206 png_uint_16 v; 4207 4208 v = table[*(row + 1) >> gamma_shift][*row]; 4209 *row = (png_byte)((v >> 8) & 0xff); 4210 *(row + 1) = (png_byte)(v & 0xff); 4211 } 4212 4213 return; 4214 } 4215 } 4216 } 4217 4218 /* Only get to here if called with a weird row_info; no harm has been done, 4219 * so just issue a warning. 4220 */ 4221 png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); 4222 } 4223 #endif 4224 4225 #ifdef PNG_READ_EXPAND_SUPPORTED 4226 /* Expands a palette row to an RGB or RGBA row depending 4227 * upon whether you supply trans and num_trans. 4228 */ 4229 static void 4230 png_do_expand_palette(png_row_infop row_info, png_bytep row, 4231 png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) 4232 { 4233 int shift, value; 4234 png_bytep sp, dp; 4235 png_uint_32 i; 4236 png_uint_32 row_width=row_info->width; 4237 4238 png_debug(1, "in png_do_expand_palette"); 4239 4240 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 4241 { 4242 if (row_info->bit_depth < 8) 4243 { 4244 switch (row_info->bit_depth) 4245 { 4246 case 1: 4247 { 4248 sp = row + (size_t)((row_width - 1) >> 3); 4249 dp = row + (size_t)row_width - 1; 4250 shift = 7 - (int)((row_width + 7) & 0x07); 4251 for (i = 0; i < row_width; i++) 4252 { 4253 if ((*sp >> shift) & 0x01) 4254 *dp = 1; 4255 4256 else 4257 *dp = 0; 4258 4259 if (shift == 7) 4260 { 4261 shift = 0; 4262 sp--; 4263 } 4264 4265 else 4266 shift++; 4267 4268 dp--; 4269 } 4270 break; 4271 } 4272 4273 case 2: 4274 { 4275 sp = row + (size_t)((row_width - 1) >> 2); 4276 dp = row + (size_t)row_width - 1; 4277 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4278 for (i = 0; i < row_width; i++) 4279 { 4280 value = (*sp >> shift) & 0x03; 4281 *dp = (png_byte)value; 4282 if (shift == 6) 4283 { 4284 shift = 0; 4285 sp--; 4286 } 4287 4288 else 4289 shift += 2; 4290 4291 dp--; 4292 } 4293 break; 4294 } 4295 4296 case 4: 4297 { 4298 sp = row + (size_t)((row_width - 1) >> 1); 4299 dp = row + (size_t)row_width - 1; 4300 shift = (int)((row_width & 0x01) << 2); 4301 for (i = 0; i < row_width; i++) 4302 { 4303 value = (*sp >> shift) & 0x0f; 4304 *dp = (png_byte)value; 4305 if (shift == 4) 4306 { 4307 shift = 0; 4308 sp--; 4309 } 4310 4311 else 4312 shift += 4; 4313 4314 dp--; 4315 } 4316 break; 4317 } 4318 4319 default: 4320 break; 4321 } 4322 row_info->bit_depth = 8; 4323 row_info->pixel_depth = 8; 4324 row_info->rowbytes = row_width; 4325 } 4326 4327 if (row_info->bit_depth == 8) 4328 { 4329 { 4330 if (num_trans > 0) 4331 { 4332 sp = row + (size_t)row_width - 1; 4333 dp = row + ((size_t)row_width << 2) - 1; 4334 4335 for (i = 0; i < row_width; i++) 4336 { 4337 if ((int)(*sp) >= num_trans) 4338 *dp-- = 0xff; 4339 4340 else 4341 *dp-- = trans_alpha[*sp]; 4342 4343 *dp-- = palette[*sp].blue; 4344 *dp-- = palette[*sp].green; 4345 *dp-- = palette[*sp].red; 4346 sp--; 4347 } 4348 row_info->bit_depth = 8; 4349 row_info->pixel_depth = 32; 4350 row_info->rowbytes = row_width * 4; 4351 row_info->color_type = 6; 4352 row_info->channels = 4; 4353 } 4354 4355 else 4356 { 4357 sp = row + (size_t)row_width - 1; 4358 dp = row + (size_t)(row_width * 3) - 1; 4359 4360 for (i = 0; i < row_width; i++) 4361 { 4362 *dp-- = palette[*sp].blue; 4363 *dp-- = palette[*sp].green; 4364 *dp-- = palette[*sp].red; 4365 sp--; 4366 } 4367 4368 row_info->bit_depth = 8; 4369 row_info->pixel_depth = 24; 4370 row_info->rowbytes = row_width * 3; 4371 row_info->color_type = 2; 4372 row_info->channels = 3; 4373 } 4374 } 4375 } 4376 } 4377 } 4378 4379 /* If the bit depth < 8, it is expanded to 8. Also, if the already 4380 * expanded transparency value is supplied, an alpha channel is built. 4381 */ 4382 static void 4383 png_do_expand(png_row_infop row_info, png_bytep row, 4384 png_const_color_16p trans_color) 4385 { 4386 int shift, value; 4387 png_bytep sp, dp; 4388 png_uint_32 i; 4389 png_uint_32 row_width=row_info->width; 4390 4391 png_debug(1, "in png_do_expand"); 4392 4393 if (row_info->color_type == PNG_COLOR_TYPE_GRAY) 4394 { 4395 unsigned int gray = trans_color != NULL ? trans_color->gray : 0; 4396 4397 if (row_info->bit_depth < 8) 4398 { 4399 switch (row_info->bit_depth) 4400 { 4401 case 1: 4402 { 4403 gray = (gray & 0x01) * 0xff; 4404 sp = row + (size_t)((row_width - 1) >> 3); 4405 dp = row + (size_t)row_width - 1; 4406 shift = 7 - (int)((row_width + 7) & 0x07); 4407 for (i = 0; i < row_width; i++) 4408 { 4409 if ((*sp >> shift) & 0x01) 4410 *dp = 0xff; 4411 4412 else 4413 *dp = 0; 4414 4415 if (shift == 7) 4416 { 4417 shift = 0; 4418 sp--; 4419 } 4420 4421 else 4422 shift++; 4423 4424 dp--; 4425 } 4426 break; 4427 } 4428 4429 case 2: 4430 { 4431 gray = (gray & 0x03) * 0x55; 4432 sp = row + (size_t)((row_width - 1) >> 2); 4433 dp = row + (size_t)row_width - 1; 4434 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); 4435 for (i = 0; i < row_width; i++) 4436 { 4437 value = (*sp >> shift) & 0x03; 4438 *dp = (png_byte)(value | (value << 2) | (value << 4) | 4439 (value << 6)); 4440 if (shift == 6) 4441 { 4442 shift = 0; 4443 sp--; 4444 } 4445 4446 else 4447 shift += 2; 4448 4449 dp--; 4450 } 4451 break; 4452 } 4453 4454 case 4: 4455 { 4456 gray = (gray & 0x0f) * 0x11; 4457 sp = row + (size_t)((row_width - 1) >> 1); 4458 dp = row + (size_t)row_width - 1; 4459 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); 4460 for (i = 0; i < row_width; i++) 4461 { 4462 value = (*sp >> shift) & 0x0f; 4463 *dp = (png_byte)(value | (value << 4)); 4464 if (shift == 4) 4465 { 4466 shift = 0; 4467 sp--; 4468 } 4469 4470 else 4471 shift = 4; 4472 4473 dp--; 4474 } 4475 break; 4476 } 4477 4478 default: 4479 break; 4480 } 4481 4482 row_info->bit_depth = 8; 4483 row_info->pixel_depth = 8; 4484 row_info->rowbytes = row_width; 4485 } 4486 4487 if (trans_color != NULL) 4488 { 4489 if (row_info->bit_depth == 8) 4490 { 4491 gray = gray & 0xff; 4492 sp = row + (size_t)row_width - 1; 4493 dp = row + ((size_t)row_width << 1) - 1; 4494 4495 for (i = 0; i < row_width; i++) 4496 { 4497 if ((*sp & 0xffU) == gray) 4498 *dp-- = 0; 4499 4500 else 4501 *dp-- = 0xff; 4502 4503 *dp-- = *sp--; 4504 } 4505 } 4506 4507 else if (row_info->bit_depth == 16) 4508 { 4509 unsigned int gray_high = (gray >> 8) & 0xff; 4510 unsigned int gray_low = gray & 0xff; 4511 sp = row + row_info->rowbytes - 1; 4512 dp = row + (row_info->rowbytes << 1) - 1; 4513 for (i = 0; i < row_width; i++) 4514 { 4515 if ((*(sp - 1) & 0xffU) == gray_high && 4516 (*(sp) & 0xffU) == gray_low) 4517 { 4518 *dp-- = 0; 4519 *dp-- = 0; 4520 } 4521 4522 else 4523 { 4524 *dp-- = 0xff; 4525 *dp-- = 0xff; 4526 } 4527 4528 *dp-- = *sp--; 4529 *dp-- = *sp--; 4530 } 4531 } 4532 4533 row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; 4534 row_info->channels = 2; 4535 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); 4536 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 4537 row_width); 4538 } 4539 } 4540 else if (row_info->color_type == PNG_COLOR_TYPE_RGB && 4541 trans_color != NULL) 4542 { 4543 if (row_info->bit_depth == 8) 4544 { 4545 png_byte red = (png_byte)(trans_color->red & 0xff); 4546 png_byte green = (png_byte)(trans_color->green & 0xff); 4547 png_byte blue = (png_byte)(trans_color->blue & 0xff); 4548 sp = row + (size_t)row_info->rowbytes - 1; 4549 dp = row + ((size_t)row_width << 2) - 1; 4550 for (i = 0; i < row_width; i++) 4551 { 4552 if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) 4553 *dp-- = 0; 4554 4555 else 4556 *dp-- = 0xff; 4557 4558 *dp-- = *sp--; 4559 *dp-- = *sp--; 4560 *dp-- = *sp--; 4561 } 4562 } 4563 else if (row_info->bit_depth == 16) 4564 { 4565 png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); 4566 png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); 4567 png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); 4568 png_byte red_low = (png_byte)(trans_color->red & 0xff); 4569 png_byte green_low = (png_byte)(trans_color->green & 0xff); 4570 png_byte blue_low = (png_byte)(trans_color->blue & 0xff); 4571 sp = row + row_info->rowbytes - 1; 4572 dp = row + ((size_t)row_width << 3) - 1; 4573 for (i = 0; i < row_width; i++) 4574 { 4575 if (*(sp - 5) == red_high && 4576 *(sp - 4) == red_low && 4577 *(sp - 3) == green_high && 4578 *(sp - 2) == green_low && 4579 *(sp - 1) == blue_high && 4580 *(sp ) == blue_low) 4581 { 4582 *dp-- = 0; 4583 *dp-- = 0; 4584 } 4585 4586 else 4587 { 4588 *dp-- = 0xff; 4589 *dp-- = 0xff; 4590 } 4591 4592 *dp-- = *sp--; 4593 *dp-- = *sp--; 4594 *dp-- = *sp--; 4595 *dp-- = *sp--; 4596 *dp-- = *sp--; 4597 *dp-- = *sp--; 4598 } 4599 } 4600 row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; 4601 row_info->channels = 4; 4602 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); 4603 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4604 } 4605 } 4606 #endif 4607 4608 #ifdef PNG_READ_EXPAND_16_SUPPORTED 4609 /* If the bit depth is 8 and the color type is not a palette type expand the 4610 * whole row to 16 bits. Has no effect otherwise. 4611 */ 4612 static void 4613 png_do_expand_16(png_row_infop row_info, png_bytep row) 4614 { 4615 if (row_info->bit_depth == 8 && 4616 row_info->color_type != PNG_COLOR_TYPE_PALETTE) 4617 { 4618 /* The row have a sequence of bytes containing [0..255] and we need 4619 * to turn it into another row containing [0..65535], to do this we 4620 * calculate: 4621 * 4622 * (input / 255) * 65535 4623 * 4624 * Which happens to be exactly input * 257 and this can be achieved 4625 * simply by byte replication in place (copying backwards). 4626 */ 4627 png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ 4628 png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ 4629 while (dp > sp) 4630 { 4631 dp[-2] = dp[-1] = *--sp; dp -= 2; 4632 } 4633 4634 row_info->rowbytes *= 2; 4635 row_info->bit_depth = 16; 4636 row_info->pixel_depth = (png_byte)(row_info->channels * 16); 4637 } 4638 } 4639 #endif 4640 4641 #ifdef PNG_READ_QUANTIZE_SUPPORTED 4642 static void 4643 png_do_quantize(png_row_infop row_info, png_bytep row, 4644 png_const_bytep palette_lookup, png_const_bytep quantize_lookup) 4645 { 4646 png_bytep sp, dp; 4647 png_uint_32 i; 4648 png_uint_32 row_width=row_info->width; 4649 4650 png_debug(1, "in png_do_quantize"); 4651 4652 if (row_info->bit_depth == 8) 4653 { 4654 if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) 4655 { 4656 int r, g, b, p; 4657 sp = row; 4658 dp = row; 4659 for (i = 0; i < row_width; i++) 4660 { 4661 r = *sp++; 4662 g = *sp++; 4663 b = *sp++; 4664 4665 /* This looks real messy, but the compiler will reduce 4666 * it down to a reasonable formula. For example, with 4667 * 5 bits per color, we get: 4668 * p = (((r >> 3) & 0x1f) << 10) | 4669 * (((g >> 3) & 0x1f) << 5) | 4670 * ((b >> 3) & 0x1f); 4671 */ 4672 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 4673 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 4674 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 4675 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 4676 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 4677 (PNG_QUANTIZE_BLUE_BITS)) | 4678 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 4679 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 4680 4681 *dp++ = palette_lookup[p]; 4682 } 4683 4684 row_info->color_type = PNG_COLOR_TYPE_PALETTE; 4685 row_info->channels = 1; 4686 row_info->pixel_depth = row_info->bit_depth; 4687 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4688 } 4689 4690 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 4691 palette_lookup != NULL) 4692 { 4693 int r, g, b, p; 4694 sp = row; 4695 dp = row; 4696 for (i = 0; i < row_width; i++) 4697 { 4698 r = *sp++; 4699 g = *sp++; 4700 b = *sp++; 4701 sp++; 4702 4703 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & 4704 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << 4705 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | 4706 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & 4707 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << 4708 (PNG_QUANTIZE_BLUE_BITS)) | 4709 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & 4710 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); 4711 4712 *dp++ = palette_lookup[p]; 4713 } 4714 4715 row_info->color_type = PNG_COLOR_TYPE_PALETTE; 4716 row_info->channels = 1; 4717 row_info->pixel_depth = row_info->bit_depth; 4718 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); 4719 } 4720 4721 else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 4722 quantize_lookup) 4723 { 4724 sp = row; 4725 4726 for (i = 0; i < row_width; i++, sp++) 4727 { 4728 *sp = quantize_lookup[*sp]; 4729 } 4730 } 4731 } 4732 } 4733 #endif /* READ_QUANTIZE */ 4734 4735 /* Transform the row. The order of transformations is significant, 4736 * and is very touchy. If you add a transformation, take care to 4737 * decide how it fits in with the other transformations here. 4738 */ 4739 void /* PRIVATE */ 4740 png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) 4741 { 4742 png_debug(1, "in png_do_read_transformations"); 4743 4744 if (png_ptr->row_buf == NULL) 4745 { 4746 /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this 4747 * error is incredibly rare and incredibly easy to debug without this 4748 * information. 4749 */ 4750 png_error(png_ptr, "NULL row buffer"); 4751 } 4752 4753 /* The following is debugging; prior to 1.5.4 the code was never compiled in; 4754 * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro 4755 * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for 4756 * all transformations, however in practice the ROW_INIT always gets done on 4757 * demand, if necessary. 4758 */ 4759 if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && 4760 (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 4761 { 4762 /* Application has failed to call either png_read_start_image() or 4763 * png_read_update_info() after setting transforms that expand pixels. 4764 * This check added to libpng-1.2.19 (but not enabled until 1.5.4). 4765 */ 4766 png_error(png_ptr, "Uninitialized row"); 4767 } 4768 4769 #ifdef PNG_READ_EXPAND_SUPPORTED 4770 if ((png_ptr->transformations & PNG_EXPAND) != 0) 4771 { 4772 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) 4773 { 4774 png_do_expand_palette(row_info, png_ptr->row_buf + 1, 4775 png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); 4776 } 4777 4778 else 4779 { 4780 if (png_ptr->num_trans != 0 && 4781 (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) 4782 png_do_expand(row_info, png_ptr->row_buf + 1, 4783 &(png_ptr->trans_color)); 4784 4785 else 4786 png_do_expand(row_info, png_ptr->row_buf + 1, NULL); 4787 } 4788 } 4789 #endif 4790 4791 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 4792 if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && 4793 (png_ptr->transformations & PNG_COMPOSE) == 0 && 4794 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 4795 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 4796 png_do_strip_channel(row_info, png_ptr->row_buf + 1, 4797 0 /* at_start == false, because SWAP_ALPHA happens later */); 4798 #endif 4799 4800 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 4801 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) 4802 { 4803 int rgb_error = 4804 png_do_rgb_to_gray(png_ptr, row_info, 4805 png_ptr->row_buf + 1); 4806 4807 if (rgb_error != 0) 4808 { 4809 png_ptr->rgb_to_gray_status=1; 4810 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 4811 PNG_RGB_TO_GRAY_WARN) 4812 png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 4813 4814 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 4815 PNG_RGB_TO_GRAY_ERR) 4816 png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); 4817 } 4818 } 4819 #endif 4820 4821 /* From Andreas Dilger e-mail to png-implement, 26 March 1998: 4822 * 4823 * In most cases, the "simple transparency" should be done prior to doing 4824 * gray-to-RGB, or you will have to test 3x as many bytes to check if a 4825 * pixel is transparent. You would also need to make sure that the 4826 * transparency information is upgraded to RGB. 4827 * 4828 * To summarize, the current flow is: 4829 * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite 4830 * with background "in place" if transparent, 4831 * convert to RGB if necessary 4832 * - Gray + alpha -> composite with gray background and remove alpha bytes, 4833 * convert to RGB if necessary 4834 * 4835 * To support RGB backgrounds for gray images we need: 4836 * - Gray + simple transparency -> convert to RGB + simple transparency, 4837 * compare 3 or 6 bytes and composite with 4838 * background "in place" if transparent 4839 * (3x compare/pixel compared to doing 4840 * composite with gray bkgrnd) 4841 * - Gray + alpha -> convert to RGB + alpha, composite with background and 4842 * remove alpha bytes (3x float 4843 * operations/pixel compared with composite 4844 * on gray background) 4845 * 4846 * Greg's change will do this. The reason it wasn't done before is for 4847 * performance, as this increases the per-pixel operations. If we would check 4848 * in advance if the background was gray or RGB, and position the gray-to-RGB 4849 * transform appropriately, then it would save a lot of work/time. 4850 */ 4851 4852 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 4853 /* If gray -> RGB, do so now only if background is non-gray; else do later 4854 * for performance reasons 4855 */ 4856 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && 4857 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) 4858 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 4859 #endif 4860 4861 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 4862 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 4863 if ((png_ptr->transformations & PNG_COMPOSE) != 0) 4864 png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); 4865 #endif 4866 4867 #ifdef PNG_READ_GAMMA_SUPPORTED 4868 if ((png_ptr->transformations & PNG_GAMMA) != 0 && 4869 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 4870 /* Because RGB_TO_GRAY does the gamma transform. */ 4871 (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && 4872 #endif 4873 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 4874 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 4875 /* Because PNG_COMPOSE does the gamma transform if there is something to 4876 * do (if there is an alpha channel or transparency.) 4877 */ 4878 !((png_ptr->transformations & PNG_COMPOSE) != 0 && 4879 ((png_ptr->num_trans != 0) || 4880 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && 4881 #endif 4882 /* Because png_init_read_transformations transforms the palette, unless 4883 * RGB_TO_GRAY will do the transform. 4884 */ 4885 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) 4886 png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); 4887 #endif 4888 4889 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 4890 if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && 4891 (png_ptr->transformations & PNG_COMPOSE) != 0 && 4892 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 4893 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) 4894 png_do_strip_channel(row_info, png_ptr->row_buf + 1, 4895 0 /* at_start == false, because SWAP_ALPHA happens later */); 4896 #endif 4897 4898 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 4899 if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && 4900 (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) 4901 png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); 4902 #endif 4903 4904 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 4905 if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) 4906 png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); 4907 #endif 4908 4909 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 4910 /* There is no harm in doing both of these because only one has any effect, 4911 * by putting the 'scale' option first if the app asks for scale (either by 4912 * calling the API or in a TRANSFORM flag) this is what happens. 4913 */ 4914 if ((png_ptr->transformations & PNG_16_TO_8) != 0) 4915 png_do_chop(row_info, png_ptr->row_buf + 1); 4916 #endif 4917 4918 #ifdef PNG_READ_QUANTIZE_SUPPORTED 4919 if ((png_ptr->transformations & PNG_QUANTIZE) != 0) 4920 { 4921 png_do_quantize(row_info, png_ptr->row_buf + 1, 4922 png_ptr->palette_lookup, png_ptr->quantize_index); 4923 4924 if (row_info->rowbytes == 0) 4925 png_error(png_ptr, "png_do_quantize returned rowbytes=0"); 4926 } 4927 #endif /* READ_QUANTIZE */ 4928 4929 #ifdef PNG_READ_EXPAND_16_SUPPORTED 4930 /* Do the expansion now, after all the arithmetic has been done. Notice 4931 * that previous transformations can handle the PNG_EXPAND_16 flag if this 4932 * is efficient (particularly true in the case of gamma correction, where 4933 * better accuracy results faster!) 4934 */ 4935 if ((png_ptr->transformations & PNG_EXPAND_16) != 0) 4936 png_do_expand_16(row_info, png_ptr->row_buf + 1); 4937 #endif 4938 4939 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 4940 /* NOTE: moved here in 1.5.4 (from much later in this list.) */ 4941 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && 4942 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) 4943 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); 4944 #endif 4945 4946 #ifdef PNG_READ_INVERT_SUPPORTED 4947 if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) 4948 png_do_invert(row_info, png_ptr->row_buf + 1); 4949 #endif 4950 4951 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 4952 if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) 4953 png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); 4954 #endif 4955 4956 #ifdef PNG_READ_SHIFT_SUPPORTED 4957 if ((png_ptr->transformations & PNG_SHIFT) != 0) 4958 png_do_unshift(row_info, png_ptr->row_buf + 1, 4959 &(png_ptr->shift)); 4960 #endif 4961 4962 #ifdef PNG_READ_PACK_SUPPORTED 4963 if ((png_ptr->transformations & PNG_PACK) != 0) 4964 png_do_unpack(row_info, png_ptr->row_buf + 1); 4965 #endif 4966 4967 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 4968 /* Added at libpng-1.5.10 */ 4969 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && 4970 png_ptr->num_palette_max >= 0) 4971 png_do_check_palette_indexes(png_ptr, row_info); 4972 #endif 4973 4974 #ifdef PNG_READ_BGR_SUPPORTED 4975 if ((png_ptr->transformations & PNG_BGR) != 0) 4976 png_do_bgr(row_info, png_ptr->row_buf + 1); 4977 #endif 4978 4979 #ifdef PNG_READ_PACKSWAP_SUPPORTED 4980 if ((png_ptr->transformations & PNG_PACKSWAP) != 0) 4981 png_do_packswap(row_info, png_ptr->row_buf + 1); 4982 #endif 4983 4984 #ifdef PNG_READ_FILLER_SUPPORTED 4985 if ((png_ptr->transformations & PNG_FILLER) != 0) 4986 png_do_read_filler(row_info, png_ptr->row_buf + 1, 4987 (png_uint_32)png_ptr->filler, png_ptr->flags); 4988 #endif 4989 4990 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 4991 if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) 4992 png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); 4993 #endif 4994 4995 #ifdef PNG_READ_16BIT_SUPPORTED 4996 #ifdef PNG_READ_SWAP_SUPPORTED 4997 if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) 4998 png_do_swap(row_info, png_ptr->row_buf + 1); 4999 #endif 5000 #endif 5001 5002 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED 5003 if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) 5004 { 5005 if (png_ptr->read_user_transform_fn != NULL) 5006 (*(png_ptr->read_user_transform_fn)) /* User read transform function */ 5007 (png_ptr, /* png_ptr */ 5008 row_info, /* row_info: */ 5009 /* png_uint_32 width; width of row */ 5010 /* size_t rowbytes; number of bytes in row */ 5011 /* png_byte color_type; color type of pixels */ 5012 /* png_byte bit_depth; bit depth of samples */ 5013 /* png_byte channels; number of channels (1-4) */ 5014 /* png_byte pixel_depth; bits per pixel (depth*channels) */ 5015 png_ptr->row_buf + 1); /* start of pixel data for row */ 5016 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED 5017 if (png_ptr->user_transform_depth != 0) 5018 row_info->bit_depth = png_ptr->user_transform_depth; 5019 5020 if (png_ptr->user_transform_channels != 0) 5021 row_info->channels = png_ptr->user_transform_channels; 5022 #endif 5023 row_info->pixel_depth = (png_byte)(row_info->bit_depth * 5024 row_info->channels); 5025 5026 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); 5027 } 5028 #endif 5029 } 5030 5031 #endif /* READ_TRANSFORMS */ 5032 #endif /* READ */