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