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