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