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