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