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