00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #define PNG_INTERNAL
00017 #include "png.h"
00018 #if defined(PNG_READ_SUPPORTED)
00019
00020
00021 void PNGAPI
00022 png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
00023 {
00024 png_debug(1, "in png_set_crc_action\n");
00025
00026 if (png_ptr == NULL) return;
00027 switch (crit_action)
00028 {
00029 case PNG_CRC_NO_CHANGE:
00030 break;
00031 case PNG_CRC_WARN_USE:
00032 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
00033 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
00034 break;
00035 case PNG_CRC_QUIET_USE:
00036 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
00037 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
00038 PNG_FLAG_CRC_CRITICAL_IGNORE;
00039 break;
00040 case PNG_CRC_WARN_DISCARD:
00041 png_warning(png_ptr,
00042 "Can't discard critical data on CRC error.");
00043 case PNG_CRC_ERROR_QUIT:
00044 case PNG_CRC_DEFAULT:
00045 default:
00046 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
00047 break;
00048 }
00049
00050 switch (ancil_action)
00051 {
00052 case PNG_CRC_NO_CHANGE:
00053 break;
00054 case PNG_CRC_WARN_USE:
00055 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
00056 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
00057 break;
00058 case PNG_CRC_QUIET_USE:
00059 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
00060 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
00061 PNG_FLAG_CRC_ANCILLARY_NOWARN;
00062 break;
00063 case PNG_CRC_ERROR_QUIT:
00064 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
00065 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
00066 break;
00067 case PNG_CRC_WARN_DISCARD:
00068 case PNG_CRC_DEFAULT:
00069 default:
00070 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
00071 break;
00072 }
00073 }
00074
00075 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
00076 defined(PNG_FLOATING_POINT_SUPPORTED)
00077
00078 void PNGAPI
00079 png_set_background(png_structp png_ptr,
00080 png_color_16p background_color, int background_gamma_code,
00081 int need_expand, double background_gamma)
00082 {
00083 png_debug(1, "in png_set_background\n");
00084 if (png_ptr == NULL) return;
00085 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
00086 {
00087 png_warning(png_ptr, "Application must supply a known background gamma");
00088 return;
00089 }
00090
00091 png_ptr->transformations |= PNG_BACKGROUND;
00092 png_memcpy(&(png_ptr->background), background_color,
00093 png_sizeof(png_color_16));
00094 png_ptr->background_gamma = (float)background_gamma;
00095 png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
00096 png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
00097 }
00098 #endif
00099
00100 #if defined(PNG_READ_16_TO_8_SUPPORTED)
00101
00102 void PNGAPI
00103 png_set_strip_16(png_structp png_ptr)
00104 {
00105 png_debug(1, "in png_set_strip_16\n");
00106 if (png_ptr == NULL) return;
00107 png_ptr->transformations |= PNG_16_TO_8;
00108 }
00109 #endif
00110
00111 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
00112 void PNGAPI
00113 png_set_strip_alpha(png_structp png_ptr)
00114 {
00115 png_debug(1, "in png_set_strip_alpha\n");
00116 if (png_ptr == NULL) return;
00117 png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
00118 }
00119 #endif
00120
00121 #if defined(PNG_READ_DITHER_SUPPORTED)
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 typedef struct png_dsort_struct
00132 {
00133 struct png_dsort_struct FAR * next;
00134 png_byte left;
00135 png_byte right;
00136 } png_dsort;
00137 typedef png_dsort FAR * png_dsortp;
00138 typedef png_dsort FAR * FAR * png_dsortpp;
00139
00140 void PNGAPI
00141 png_set_dither(png_structp png_ptr, png_colorp palette,
00142 int num_palette, int maximum_colors, png_uint_16p histogram,
00143 int full_dither)
00144 {
00145 png_debug(1, "in png_set_dither\n");
00146 if (png_ptr == NULL) return;
00147 png_ptr->transformations |= PNG_DITHER;
00148
00149 if (!full_dither)
00150 {
00151 int i;
00152
00153 png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
00154 (png_uint_32)(num_palette * png_sizeof(png_byte)));
00155 for (i = 0; i < num_palette; i++)
00156 png_ptr->dither_index[i] = (png_byte)i;
00157 }
00158
00159 if (num_palette > maximum_colors)
00160 {
00161 if (histogram != NULL)
00162 {
00163
00164
00165
00166 int i;
00167
00168
00169 png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
00170 (png_uint_32)(num_palette * png_sizeof(png_byte)));
00171
00172
00173 for (i = 0; i < num_palette; i++)
00174 png_ptr->dither_sort[i] = (png_byte)i;
00175
00176
00177
00178
00179
00180
00181
00182 for (i = num_palette - 1; i >= maximum_colors; i--)
00183 {
00184 int done;
00185 int j;
00186
00187 done = 1;
00188 for (j = 0; j < i; j++)
00189 {
00190 if (histogram[png_ptr->dither_sort[j]]
00191 < histogram[png_ptr->dither_sort[j + 1]])
00192 {
00193 png_byte t;
00194
00195 t = png_ptr->dither_sort[j];
00196 png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
00197 png_ptr->dither_sort[j + 1] = t;
00198 done = 0;
00199 }
00200 }
00201 if (done)
00202 break;
00203 }
00204
00205
00206 if (full_dither)
00207 {
00208 int j = num_palette;
00209
00210
00211
00212 for (i = 0; i < maximum_colors; i++)
00213 {
00214 if ((int)png_ptr->dither_sort[i] >= maximum_colors)
00215 {
00216 do
00217 j--;
00218 while ((int)png_ptr->dither_sort[j] >= maximum_colors);
00219 palette[i] = palette[j];
00220 }
00221 }
00222 }
00223 else
00224 {
00225 int j = num_palette;
00226
00227
00228
00229 for (i = 0; i < maximum_colors; i++)
00230 {
00231
00232 if ((int)png_ptr->dither_sort[i] >= maximum_colors)
00233 {
00234 png_color tmp_color;
00235
00236 do
00237 j--;
00238 while ((int)png_ptr->dither_sort[j] >= maximum_colors);
00239
00240 tmp_color = palette[j];
00241 palette[j] = palette[i];
00242 palette[i] = tmp_color;
00243
00244 png_ptr->dither_index[j] = (png_byte)i;
00245 png_ptr->dither_index[i] = (png_byte)j;
00246 }
00247 }
00248
00249
00250 for (i = 0; i < num_palette; i++)
00251 {
00252 if ((int)png_ptr->dither_index[i] >= maximum_colors)
00253 {
00254 int min_d, k, min_k, d_index;
00255
00256
00257 d_index = png_ptr->dither_index[i];
00258 min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
00259 for (k = 1, min_k = 0; k < maximum_colors; k++)
00260 {
00261 int d;
00262
00263 d = PNG_COLOR_DIST(palette[d_index], palette[k]);
00264
00265 if (d < min_d)
00266 {
00267 min_d = d;
00268 min_k = k;
00269 }
00270 }
00271
00272 png_ptr->dither_index[i] = (png_byte)min_k;
00273 }
00274 }
00275 }
00276 png_free(png_ptr, png_ptr->dither_sort);
00277 png_ptr->dither_sort = NULL;
00278 }
00279 else
00280 {
00281
00282
00283
00284
00285
00286
00287
00288
00289 int i;
00290 int max_d;
00291 int num_new_palette;
00292 png_dsortp t;
00293 png_dsortpp hash;
00294
00295 t = NULL;
00296
00297
00298 png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
00299 (png_uint_32)(num_palette * png_sizeof(png_byte)));
00300 png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
00301 (png_uint_32)(num_palette * png_sizeof(png_byte)));
00302
00303
00304 for (i = 0; i < num_palette; i++)
00305 {
00306 png_ptr->index_to_palette[i] = (png_byte)i;
00307 png_ptr->palette_to_index[i] = (png_byte)i;
00308 }
00309
00310 hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
00311 png_sizeof(png_dsortp)));
00312 for (i = 0; i < 769; i++)
00313 hash[i] = NULL;
00314
00315
00316 num_new_palette = num_palette;
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 max_d = 96;
00327
00328 while (num_new_palette > maximum_colors)
00329 {
00330 for (i = 0; i < num_new_palette - 1; i++)
00331 {
00332 int j;
00333
00334 for (j = i + 1; j < num_new_palette; j++)
00335 {
00336 int d;
00337
00338 d = PNG_COLOR_DIST(palette[i], palette[j]);
00339
00340 if (d <= max_d)
00341 {
00342
00343 t = (png_dsortp)png_malloc_warn(png_ptr,
00344 (png_uint_32)(png_sizeof(png_dsort)));
00345 if (t == NULL)
00346 break;
00347 t->next = hash[d];
00348 t->left = (png_byte)i;
00349 t->right = (png_byte)j;
00350 hash[d] = t;
00351 }
00352 }
00353 if (t == NULL)
00354 break;
00355 }
00356
00357 if (t != NULL)
00358 for (i = 0; i <= max_d; i++)
00359 {
00360 if (hash[i] != NULL)
00361 {
00362 png_dsortp p;
00363
00364 for (p = hash[i]; p; p = p->next)
00365 {
00366 if ((int)png_ptr->index_to_palette[p->left]
00367 < num_new_palette &&
00368 (int)png_ptr->index_to_palette[p->right]
00369 < num_new_palette)
00370 {
00371 int j, next_j;
00372
00373 if (num_new_palette & 0x01)
00374 {
00375 j = p->left;
00376 next_j = p->right;
00377 }
00378 else
00379 {
00380 j = p->right;
00381 next_j = p->left;
00382 }
00383
00384 num_new_palette--;
00385 palette[png_ptr->index_to_palette[j]]
00386 = palette[num_new_palette];
00387 if (!full_dither)
00388 {
00389 int k;
00390
00391 for (k = 0; k < num_palette; k++)
00392 {
00393 if (png_ptr->dither_index[k] ==
00394 png_ptr->index_to_palette[j])
00395 png_ptr->dither_index[k] =
00396 png_ptr->index_to_palette[next_j];
00397 if ((int)png_ptr->dither_index[k] ==
00398 num_new_palette)
00399 png_ptr->dither_index[k] =
00400 png_ptr->index_to_palette[j];
00401 }
00402 }
00403
00404 png_ptr->index_to_palette[png_ptr->palette_to_index
00405 [num_new_palette]] = png_ptr->index_to_palette[j];
00406 png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
00407 = png_ptr->palette_to_index[num_new_palette];
00408
00409 png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
00410 png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
00411 }
00412 if (num_new_palette <= maximum_colors)
00413 break;
00414 }
00415 if (num_new_palette <= maximum_colors)
00416 break;
00417 }
00418 }
00419
00420 for (i = 0; i < 769; i++)
00421 {
00422 if (hash[i] != NULL)
00423 {
00424 png_dsortp p = hash[i];
00425 while (p)
00426 {
00427 t = p->next;
00428 png_free(png_ptr, p);
00429 p = t;
00430 }
00431 }
00432 hash[i] = 0;
00433 }
00434 max_d += 96;
00435 }
00436 png_free(png_ptr, hash);
00437 png_free(png_ptr, png_ptr->palette_to_index);
00438 png_free(png_ptr, png_ptr->index_to_palette);
00439 png_ptr->palette_to_index = NULL;
00440 png_ptr->index_to_palette = NULL;
00441 }
00442 num_palette = maximum_colors;
00443 }
00444 if (png_ptr->palette == NULL)
00445 {
00446 png_ptr->palette = palette;
00447 }
00448 png_ptr->num_palette = (png_uint_16)num_palette;
00449
00450 if (full_dither)
00451 {
00452 int i;
00453 png_bytep distance;
00454 int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
00455 PNG_DITHER_BLUE_BITS;
00456 int num_red = (1 << PNG_DITHER_RED_BITS);
00457 int num_green = (1 << PNG_DITHER_GREEN_BITS);
00458 int num_blue = (1 << PNG_DITHER_BLUE_BITS);
00459 png_size_t num_entries = ((png_size_t)1 << total_bits);
00460
00461 png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
00462 (png_uint_32)(num_entries * png_sizeof(png_byte)));
00463
00464 png_memset(png_ptr->palette_lookup, 0, num_entries *
00465 png_sizeof(png_byte));
00466
00467 distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
00468 png_sizeof(png_byte)));
00469
00470 png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
00471
00472 for (i = 0; i < num_palette; i++)
00473 {
00474 int ir, ig, ib;
00475 int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
00476 int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
00477 int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
00478
00479 for (ir = 0; ir < num_red; ir++)
00480 {
00481
00482 int dr = ((ir > r) ? ir - r : r - ir);
00483 int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
00484
00485 for (ig = 0; ig < num_green; ig++)
00486 {
00487
00488 int dg = ((ig > g) ? ig - g : g - ig);
00489 int dt = dr + dg;
00490 int dm = ((dr > dg) ? dr : dg);
00491 int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
00492
00493 for (ib = 0; ib < num_blue; ib++)
00494 {
00495 int d_index = index_g | ib;
00496
00497 int db = ((ib > b) ? ib - b : b - ib);
00498 int dmax = ((dm > db) ? dm : db);
00499 int d = dmax + dt + db;
00500
00501 if (d < (int)distance[d_index])
00502 {
00503 distance[d_index] = (png_byte)d;
00504 png_ptr->palette_lookup[d_index] = (png_byte)i;
00505 }
00506 }
00507 }
00508 }
00509 }
00510
00511 png_free(png_ptr, distance);
00512 }
00513 }
00514 #endif
00515
00516 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 void PNGAPI
00527 png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
00528 {
00529 png_debug(1, "in png_set_gamma\n");
00530 if (png_ptr == NULL) return;
00531 if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
00532 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
00533 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
00534 png_ptr->transformations |= PNG_GAMMA;
00535 png_ptr->gamma = (float)file_gamma;
00536 png_ptr->screen_gamma = (float)scrn_gamma;
00537 }
00538 #endif
00539
00540 #if defined(PNG_READ_EXPAND_SUPPORTED)
00541
00542
00543
00544
00545 void PNGAPI
00546 png_set_expand(png_structp png_ptr)
00547 {
00548 png_debug(1, "in png_set_expand\n");
00549 if (png_ptr == NULL) return;
00550 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
00551 png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 void PNGAPI
00573 png_set_palette_to_rgb(png_structp png_ptr)
00574 {
00575 png_debug(1, "in png_set_palette_to_rgb\n");
00576 if (png_ptr == NULL) return;
00577 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
00578 png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
00579 }
00580
00581 #if !defined(PNG_1_0_X)
00582
00583 void PNGAPI
00584 png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
00585 {
00586 png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
00587 if (png_ptr == NULL) return;
00588 png_ptr->transformations |= PNG_EXPAND;
00589 png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
00590 }
00591 #endif
00592
00593 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
00594
00595
00596 void PNGAPI
00597 png_set_gray_1_2_4_to_8(png_structp png_ptr)
00598 {
00599 png_debug(1, "in png_set_gray_1_2_4_to_8\n");
00600 if (png_ptr == NULL) return;
00601 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
00602 }
00603 #endif
00604
00605
00606
00607 void PNGAPI
00608 png_set_tRNS_to_alpha(png_structp png_ptr)
00609 {
00610 png_debug(1, "in png_set_tRNS_to_alpha\n");
00611 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
00612 png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
00613 }
00614 #endif
00615
00616 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
00617 void PNGAPI
00618 png_set_gray_to_rgb(png_structp png_ptr)
00619 {
00620 png_debug(1, "in png_set_gray_to_rgb\n");
00621 png_ptr->transformations |= PNG_GRAY_TO_RGB;
00622 png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
00623 }
00624 #endif
00625
00626 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
00627 #if defined(PNG_FLOATING_POINT_SUPPORTED)
00628
00629
00630
00631
00632 void PNGAPI
00633 png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
00634 double green)
00635 {
00636 int red_fixed = (int)((float)red*100000.0 + 0.5);
00637 int green_fixed = (int)((float)green*100000.0 + 0.5);
00638 if (png_ptr == NULL) return;
00639 png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
00640 }
00641 #endif
00642
00643 void PNGAPI
00644 png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
00645 png_fixed_point red, png_fixed_point green)
00646 {
00647 png_debug(1, "in png_set_rgb_to_gray\n");
00648 if (png_ptr == NULL) return;
00649 switch(error_action)
00650 {
00651 case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
00652 break;
00653 case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
00654 break;
00655 case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
00656 }
00657 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
00658 #if defined(PNG_READ_EXPAND_SUPPORTED)
00659 png_ptr->transformations |= PNG_EXPAND;
00660 #else
00661 {
00662 png_warning(png_ptr,
00663 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
00664 png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
00665 }
00666 #endif
00667 {
00668 png_uint_16 red_int, green_int;
00669 if (red < 0 || green < 0)
00670 {
00671 red_int = 6968;
00672 green_int = 23434;
00673 }
00674 else if (red + green < 100000L)
00675 {
00676 red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
00677 green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
00678 }
00679 else
00680 {
00681 png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
00682 red_int = 6968;
00683 green_int = 23434;
00684 }
00685 png_ptr->rgb_to_gray_red_coeff = red_int;
00686 png_ptr->rgb_to_gray_green_coeff = green_int;
00687 png_ptr->rgb_to_gray_blue_coeff =
00688 (png_uint_16)(32768 - red_int - green_int);
00689 }
00690 }
00691 #endif
00692
00693 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
00694 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
00695 defined(PNG_LEGACY_SUPPORTED)
00696 void PNGAPI
00697 png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
00698 read_user_transform_fn)
00699 {
00700 png_debug(1, "in png_set_read_user_transform_fn\n");
00701 if (png_ptr == NULL) return;
00702 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
00703 png_ptr->transformations |= PNG_USER_TRANSFORM;
00704 png_ptr->read_user_transform_fn = read_user_transform_fn;
00705 #endif
00706 #ifdef PNG_LEGACY_SUPPORTED
00707 if (read_user_transform_fn)
00708 png_warning(png_ptr,
00709 "This version of libpng does not support user transforms");
00710 #endif
00711 }
00712 #endif
00713
00714
00715
00716
00717 void
00718 png_init_read_transformations(png_structp png_ptr)
00719 {
00720 png_debug(1, "in png_init_read_transformations\n");
00721 #if defined(PNG_USELESS_TESTS_SUPPORTED)
00722 if (png_ptr != NULL)
00723 #endif
00724 {
00725 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
00726 || defined(PNG_READ_GAMMA_SUPPORTED)
00727 int color_type = png_ptr->color_type;
00728 #endif
00729
00730 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
00731
00732 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
00743 !(color_type & PNG_COLOR_MASK_COLOR))
00744 {
00745 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
00746 } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
00747 !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
00748 (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
00749 png_ptr->background.red == png_ptr->background.green &&
00750 png_ptr->background.red == png_ptr->background.blue)
00751 {
00752 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
00753 png_ptr->background.gray = png_ptr->background.red;
00754 }
00755 #endif
00756
00757 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
00758 (png_ptr->transformations & PNG_EXPAND))
00759 {
00760 if (!(color_type & PNG_COLOR_MASK_COLOR))
00761 {
00762
00763 switch (png_ptr->bit_depth)
00764 {
00765 case 1:
00766 png_ptr->background.gray *= (png_uint_16)0xff;
00767 png_ptr->background.red = png_ptr->background.green
00768 = png_ptr->background.blue = png_ptr->background.gray;
00769 if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
00770 {
00771 png_ptr->trans_values.gray *= (png_uint_16)0xff;
00772 png_ptr->trans_values.red = png_ptr->trans_values.green
00773 = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
00774 }
00775 break;
00776 case 2:
00777 png_ptr->background.gray *= (png_uint_16)0x55;
00778 png_ptr->background.red = png_ptr->background.green
00779 = png_ptr->background.blue = png_ptr->background.gray;
00780 if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
00781 {
00782 png_ptr->trans_values.gray *= (png_uint_16)0x55;
00783 png_ptr->trans_values.red = png_ptr->trans_values.green
00784 = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
00785 }
00786 break;
00787 case 4:
00788 png_ptr->background.gray *= (png_uint_16)0x11;
00789 png_ptr->background.red = png_ptr->background.green
00790 = png_ptr->background.blue = png_ptr->background.gray;
00791 if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
00792 {
00793 png_ptr->trans_values.gray *= (png_uint_16)0x11;
00794 png_ptr->trans_values.red = png_ptr->trans_values.green
00795 = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
00796 }
00797 break;
00798 case 8:
00799 case 16:
00800 png_ptr->background.red = png_ptr->background.green
00801 = png_ptr->background.blue = png_ptr->background.gray;
00802 break;
00803 }
00804 }
00805 else if (color_type == PNG_COLOR_TYPE_PALETTE)
00806 {
00807 png_ptr->background.red =
00808 png_ptr->palette[png_ptr->background.index].red;
00809 png_ptr->background.green =
00810 png_ptr->palette[png_ptr->background.index].green;
00811 png_ptr->background.blue =
00812 png_ptr->palette[png_ptr->background.index].blue;
00813
00814 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
00815 if (png_ptr->transformations & PNG_INVERT_ALPHA)
00816 {
00817 #if defined(PNG_READ_EXPAND_SUPPORTED)
00818 if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
00819 #endif
00820 {
00821
00822
00823 int i, istop;
00824 istop=(int)png_ptr->num_trans;
00825 for (i=0; i<istop; i++)
00826 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
00827 }
00828 }
00829 #endif
00830
00831 }
00832 }
00833 #endif
00834
00835 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
00836 png_ptr->background_1 = png_ptr->background;
00837 #endif
00838 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
00839
00840 if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
00841 && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
00842 < PNG_GAMMA_THRESHOLD))
00843 {
00844 int i, k;
00845 k=0;
00846 for (i=0; i<png_ptr->num_trans; i++)
00847 {
00848 if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
00849 k=1;
00850 }
00851 if (k == 0)
00852 png_ptr->transformations &= ~PNG_GAMMA;
00853 }
00854
00855 if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
00856 png_ptr->gamma != 0.0)
00857 {
00858 png_build_gamma_table(png_ptr);
00859 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
00860 if (png_ptr->transformations & PNG_BACKGROUND)
00861 {
00862 if (color_type == PNG_COLOR_TYPE_PALETTE)
00863 {
00864
00865
00866 png_color back, back_1;
00867 png_colorp palette = png_ptr->palette;
00868 int num_palette = png_ptr->num_palette;
00869 int i;
00870 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
00871 {
00872 back.red = png_ptr->gamma_table[png_ptr->background.red];
00873 back.green = png_ptr->gamma_table[png_ptr->background.green];
00874 back.blue = png_ptr->gamma_table[png_ptr->background.blue];
00875
00876 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
00877 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
00878 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
00879 }
00880 else
00881 {
00882 double g, gs;
00883
00884 switch (png_ptr->background_gamma_type)
00885 {
00886 case PNG_BACKGROUND_GAMMA_SCREEN:
00887 g = (png_ptr->screen_gamma);
00888 gs = 1.0;
00889 break;
00890 case PNG_BACKGROUND_GAMMA_FILE:
00891 g = 1.0 / (png_ptr->gamma);
00892 gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
00893 break;
00894 case PNG_BACKGROUND_GAMMA_UNIQUE:
00895 g = 1.0 / (png_ptr->background_gamma);
00896 gs = 1.0 / (png_ptr->background_gamma *
00897 png_ptr->screen_gamma);
00898 break;
00899 default:
00900 g = 1.0;
00901 gs = 1.0;
00902 }
00903
00904 if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
00905 {
00906 back.red = (png_byte)png_ptr->background.red;
00907 back.green = (png_byte)png_ptr->background.green;
00908 back.blue = (png_byte)png_ptr->background.blue;
00909 }
00910 else
00911 {
00912 back.red = (png_byte)(pow(
00913 (double)png_ptr->background.red/255, gs) * 255.0 + .5);
00914 back.green = (png_byte)(pow(
00915 (double)png_ptr->background.green/255, gs) * 255.0 + .5);
00916 back.blue = (png_byte)(pow(
00917 (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
00918 }
00919
00920 back_1.red = (png_byte)(pow(
00921 (double)png_ptr->background.red/255, g) * 255.0 + .5);
00922 back_1.green = (png_byte)(pow(
00923 (double)png_ptr->background.green/255, g) * 255.0 + .5);
00924 back_1.blue = (png_byte)(pow(
00925 (double)png_ptr->background.blue/255, g) * 255.0 + .5);
00926 }
00927 for (i = 0; i < num_palette; i++)
00928 {
00929 if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
00930 {
00931 if (png_ptr->trans[i] == 0)
00932 {
00933 palette[i] = back;
00934 }
00935 else
00936 {
00937 png_byte v, w;
00938
00939 v = png_ptr->gamma_to_1[palette[i].red];
00940 png_composite(w, v, png_ptr->trans[i], back_1.red);
00941 palette[i].red = png_ptr->gamma_from_1[w];
00942
00943 v = png_ptr->gamma_to_1[palette[i].green];
00944 png_composite(w, v, png_ptr->trans[i], back_1.green);
00945 palette[i].green = png_ptr->gamma_from_1[w];
00946
00947 v = png_ptr->gamma_to_1[palette[i].blue];
00948 png_composite(w, v, png_ptr->trans[i], back_1.blue);
00949 palette[i].blue = png_ptr->gamma_from_1[w];
00950 }
00951 }
00952 else
00953 {
00954 palette[i].red = png_ptr->gamma_table[palette[i].red];
00955 palette[i].green = png_ptr->gamma_table[palette[i].green];
00956 palette[i].blue = png_ptr->gamma_table[palette[i].blue];
00957 }
00958 }
00959
00960
00961
00962
00963
00964 png_ptr->transformations &= ~PNG_BACKGROUND;
00965 png_ptr->transformations &= ~PNG_GAMMA;
00966 png_ptr->transformations |= PNG_STRIP_ALPHA;
00967 }
00968
00969 else
00970
00971 {
00972 double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
00973 double g = 1.0;
00974 double gs = 1.0;
00975
00976 switch (png_ptr->background_gamma_type)
00977 {
00978 case PNG_BACKGROUND_GAMMA_SCREEN:
00979 g = (png_ptr->screen_gamma);
00980 gs = 1.0;
00981 break;
00982 case PNG_BACKGROUND_GAMMA_FILE:
00983 g = 1.0 / (png_ptr->gamma);
00984 gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
00985 break;
00986 case PNG_BACKGROUND_GAMMA_UNIQUE:
00987 g = 1.0 / (png_ptr->background_gamma);
00988 gs = 1.0 / (png_ptr->background_gamma *
00989 png_ptr->screen_gamma);
00990 break;
00991 }
00992
00993 png_ptr->background_1.gray = (png_uint_16)(pow(
00994 (double)png_ptr->background.gray / m, g) * m + .5);
00995 png_ptr->background.gray = (png_uint_16)(pow(
00996 (double)png_ptr->background.gray / m, gs) * m + .5);
00997
00998 if ((png_ptr->background.red != png_ptr->background.green) ||
00999 (png_ptr->background.red != png_ptr->background.blue) ||
01000 (png_ptr->background.red != png_ptr->background.gray))
01001 {
01002
01003 png_ptr->background_1.red = (png_uint_16)(pow(
01004 (double)png_ptr->background.red / m, g) * m + .5);
01005 png_ptr->background_1.green = (png_uint_16)(pow(
01006 (double)png_ptr->background.green / m, g) * m + .5);
01007 png_ptr->background_1.blue = (png_uint_16)(pow(
01008 (double)png_ptr->background.blue / m, g) * m + .5);
01009 png_ptr->background.red = (png_uint_16)(pow(
01010 (double)png_ptr->background.red / m, gs) * m + .5);
01011 png_ptr->background.green = (png_uint_16)(pow(
01012 (double)png_ptr->background.green / m, gs) * m + .5);
01013 png_ptr->background.blue = (png_uint_16)(pow(
01014 (double)png_ptr->background.blue / m, gs) * m + .5);
01015 }
01016 else
01017 {
01018
01019 png_ptr->background_1.red = png_ptr->background_1.green
01020 = png_ptr->background_1.blue = png_ptr->background_1.gray;
01021 png_ptr->background.red = png_ptr->background.green
01022 = png_ptr->background.blue = png_ptr->background.gray;
01023 }
01024 }
01025 }
01026 else
01027
01028 #endif
01029 if (color_type == PNG_COLOR_TYPE_PALETTE)
01030 {
01031 png_colorp palette = png_ptr->palette;
01032 int num_palette = png_ptr->num_palette;
01033 int i;
01034
01035 for (i = 0; i < num_palette; i++)
01036 {
01037 palette[i].red = png_ptr->gamma_table[palette[i].red];
01038 palette[i].green = png_ptr->gamma_table[palette[i].green];
01039 palette[i].blue = png_ptr->gamma_table[palette[i].blue];
01040 }
01041
01042
01043 png_ptr->transformations &= ~PNG_GAMMA;
01044 }
01045 }
01046 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
01047 else
01048 #endif
01049 #endif
01050 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
01051
01052 if ((png_ptr->transformations & PNG_BACKGROUND) &&
01053 (color_type == PNG_COLOR_TYPE_PALETTE))
01054 {
01055 int i;
01056 int istop = (int)png_ptr->num_trans;
01057 png_color back;
01058 png_colorp palette = png_ptr->palette;
01059
01060 back.red = (png_byte)png_ptr->background.red;
01061 back.green = (png_byte)png_ptr->background.green;
01062 back.blue = (png_byte)png_ptr->background.blue;
01063
01064 for (i = 0; i < istop; i++)
01065 {
01066 if (png_ptr->trans[i] == 0)
01067 {
01068 palette[i] = back;
01069 }
01070 else if (png_ptr->trans[i] != 0xff)
01071 {
01072
01073 png_composite(palette[i].red, palette[i].red,
01074 png_ptr->trans[i], back.red);
01075 png_composite(palette[i].green, palette[i].green,
01076 png_ptr->trans[i], back.green);
01077 png_composite(palette[i].blue, palette[i].blue,
01078 png_ptr->trans[i], back.blue);
01079 }
01080 }
01081
01082
01083 png_ptr->transformations &= ~PNG_BACKGROUND;
01084 png_ptr->transformations |= PNG_STRIP_ALPHA;
01085 }
01086 #endif
01087
01088 #if defined(PNG_READ_SHIFT_SUPPORTED)
01089 if ((png_ptr->transformations & PNG_SHIFT) &&
01090 (color_type == PNG_COLOR_TYPE_PALETTE))
01091 {
01092 png_uint_16 i;
01093 png_uint_16 istop = png_ptr->num_palette;
01094 int sr = 8 - png_ptr->sig_bit.red;
01095 int sg = 8 - png_ptr->sig_bit.green;
01096 int sb = 8 - png_ptr->sig_bit.blue;
01097
01098 if (sr < 0 || sr > 8)
01099 sr = 0;
01100 if (sg < 0 || sg > 8)
01101 sg = 0;
01102 if (sb < 0 || sb > 8)
01103 sb = 0;
01104 for (i = 0; i < istop; i++)
01105 {
01106 png_ptr->palette[i].red >>= sr;
01107 png_ptr->palette[i].green >>= sg;
01108 png_ptr->palette[i].blue >>= sb;
01109 }
01110 }
01111 #endif
01112 }
01113 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
01114 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
01115 if (png_ptr)
01116 return;
01117 #endif
01118 }
01119
01120
01121
01122
01123
01124 void
01125 png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
01126 {
01127 png_debug(1, "in png_read_transform_info\n");
01128 #if defined(PNG_READ_EXPAND_SUPPORTED)
01129 if (png_ptr->transformations & PNG_EXPAND)
01130 {
01131 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
01132 {
01133 if (png_ptr->num_trans &&
01134 (png_ptr->transformations & PNG_EXPAND_tRNS))
01135 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
01136 else
01137 info_ptr->color_type = PNG_COLOR_TYPE_RGB;
01138 info_ptr->bit_depth = 8;
01139 info_ptr->num_trans = 0;
01140 }
01141 else
01142 {
01143 if (png_ptr->num_trans)
01144 {
01145 if (png_ptr->transformations & PNG_EXPAND_tRNS)
01146 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
01147 #if 0
01148 else
01149 info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
01150 #endif
01151 }
01152 if (info_ptr->bit_depth < 8)
01153 info_ptr->bit_depth = 8;
01154 info_ptr->num_trans = 0;
01155 }
01156 }
01157 #endif
01158
01159 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
01160 if (png_ptr->transformations & PNG_BACKGROUND)
01161 {
01162 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
01163 info_ptr->num_trans = 0;
01164 info_ptr->background = png_ptr->background;
01165 }
01166 #endif
01167
01168 #if defined(PNG_READ_GAMMA_SUPPORTED)
01169 if (png_ptr->transformations & PNG_GAMMA)
01170 {
01171 #ifdef PNG_FLOATING_POINT_SUPPORTED
01172 info_ptr->gamma = png_ptr->gamma;
01173 #endif
01174 #ifdef PNG_FIXED_POINT_SUPPORTED
01175 info_ptr->int_gamma = png_ptr->int_gamma;
01176 #endif
01177 }
01178 #endif
01179
01180 #if defined(PNG_READ_16_TO_8_SUPPORTED)
01181 if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
01182 info_ptr->bit_depth = 8;
01183 #endif
01184
01185 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
01186 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
01187 info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
01188 #endif
01189
01190 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
01191 if (png_ptr->transformations & PNG_RGB_TO_GRAY)
01192 info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
01193 #endif
01194
01195 #if defined(PNG_READ_DITHER_SUPPORTED)
01196 if (png_ptr->transformations & PNG_DITHER)
01197 {
01198 if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
01199 (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
01200 png_ptr->palette_lookup && info_ptr->bit_depth == 8)
01201 {
01202 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
01203 }
01204 }
01205 #endif
01206
01207 #if defined(PNG_READ_PACK_SUPPORTED)
01208 if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
01209 info_ptr->bit_depth = 8;
01210 #endif
01211
01212 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
01213 info_ptr->channels = 1;
01214 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
01215 info_ptr->channels = 3;
01216 else
01217 info_ptr->channels = 1;
01218
01219 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
01220 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
01221 info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
01222 #endif
01223
01224 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
01225 info_ptr->channels++;
01226
01227 #if defined(PNG_READ_FILLER_SUPPORTED)
01228
01229 if ((png_ptr->transformations & PNG_FILLER) &&
01230 ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
01231 (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
01232 {
01233 info_ptr->channels++;
01234
01235 #if !defined(PNG_1_0_X)
01236 if (png_ptr->transformations & PNG_ADD_ALPHA)
01237 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
01238 #endif
01239 }
01240 #endif
01241
01242 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
01243 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
01244 if (png_ptr->transformations & PNG_USER_TRANSFORM)
01245 {
01246 if (info_ptr->bit_depth < png_ptr->user_transform_depth)
01247 info_ptr->bit_depth = png_ptr->user_transform_depth;
01248 if (info_ptr->channels < png_ptr->user_transform_channels)
01249 info_ptr->channels = png_ptr->user_transform_channels;
01250 }
01251 #endif
01252
01253 info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
01254 info_ptr->bit_depth);
01255
01256 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
01257
01258 #if !defined(PNG_READ_EXPAND_SUPPORTED)
01259 if (png_ptr)
01260 return;
01261 #endif
01262 }
01263
01264
01265
01266
01267
01268 void
01269 png_do_read_transformations(png_structp png_ptr)
01270 {
01271 png_debug(1, "in png_do_read_transformations\n");
01272 if (png_ptr->row_buf == NULL)
01273 {
01274 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
01275 char msg[50];
01276
01277 png_snprintf2(msg, 50,
01278 "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
01279 png_ptr->pass);
01280 png_error(png_ptr, msg);
01281 #else
01282 png_error(png_ptr, "NULL row buffer");
01283 #endif
01284 }
01285 #ifdef PNG_WARN_UNINITIALIZED_ROW
01286 if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
01287
01288
01289
01290 #if (PNG_WARN_UNINITIALIZED_ROW==1)
01291 png_error(png_ptr, "Uninitialized row");
01292 #else
01293 png_warning(png_ptr, "Uninitialized row");
01294 #endif
01295 #endif
01296
01297 #if defined(PNG_READ_EXPAND_SUPPORTED)
01298 if (png_ptr->transformations & PNG_EXPAND)
01299 {
01300 if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
01301 {
01302 png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
01303 png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
01304 }
01305 else
01306 {
01307 if (png_ptr->num_trans &&
01308 (png_ptr->transformations & PNG_EXPAND_tRNS))
01309 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
01310 &(png_ptr->trans_values));
01311 else
01312 png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
01313 NULL);
01314 }
01315 }
01316 #endif
01317
01318 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
01319 if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
01320 png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
01321 PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
01322 #endif
01323
01324 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
01325 if (png_ptr->transformations & PNG_RGB_TO_GRAY)
01326 {
01327 int rgb_error =
01328 png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
01329 if (rgb_error)
01330 {
01331 png_ptr->rgb_to_gray_status=1;
01332 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
01333 PNG_RGB_TO_GRAY_WARN)
01334 png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
01335 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
01336 PNG_RGB_TO_GRAY_ERR)
01337 png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
01338 }
01339 }
01340 #endif
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
01373
01374
01375 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
01376 !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
01377 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
01378 #endif
01379
01380 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
01381 if ((png_ptr->transformations & PNG_BACKGROUND) &&
01382 ((png_ptr->num_trans != 0 ) ||
01383 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
01384 png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
01385 &(png_ptr->trans_values), &(png_ptr->background)
01386 #if defined(PNG_READ_GAMMA_SUPPORTED)
01387 , &(png_ptr->background_1),
01388 png_ptr->gamma_table, png_ptr->gamma_from_1,
01389 png_ptr->gamma_to_1, png_ptr->gamma_16_table,
01390 png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
01391 png_ptr->gamma_shift
01392 #endif
01393 );
01394 #endif
01395
01396 #if defined(PNG_READ_GAMMA_SUPPORTED)
01397 if ((png_ptr->transformations & PNG_GAMMA) &&
01398 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
01399 !((png_ptr->transformations & PNG_BACKGROUND) &&
01400 ((png_ptr->num_trans != 0) ||
01401 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
01402 #endif
01403 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
01404 png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
01405 png_ptr->gamma_table, png_ptr->gamma_16_table,
01406 png_ptr->gamma_shift);
01407 #endif
01408
01409 #if defined(PNG_READ_16_TO_8_SUPPORTED)
01410 if (png_ptr->transformations & PNG_16_TO_8)
01411 png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
01412 #endif
01413
01414 #if defined(PNG_READ_DITHER_SUPPORTED)
01415 if (png_ptr->transformations & PNG_DITHER)
01416 {
01417 png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
01418 png_ptr->palette_lookup, png_ptr->dither_index);
01419 if (png_ptr->row_info.rowbytes == (png_uint_32)0)
01420 png_error(png_ptr, "png_do_dither returned rowbytes=0");
01421 }
01422 #endif
01423
01424 #if defined(PNG_READ_INVERT_SUPPORTED)
01425 if (png_ptr->transformations & PNG_INVERT_MONO)
01426 png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
01427 #endif
01428
01429 #if defined(PNG_READ_SHIFT_SUPPORTED)
01430 if (png_ptr->transformations & PNG_SHIFT)
01431 png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
01432 &(png_ptr->shift));
01433 #endif
01434
01435 #if defined(PNG_READ_PACK_SUPPORTED)
01436 if (png_ptr->transformations & PNG_PACK)
01437 png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
01438 #endif
01439
01440 #if defined(PNG_READ_BGR_SUPPORTED)
01441 if (png_ptr->transformations & PNG_BGR)
01442 png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
01443 #endif
01444
01445 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
01446 if (png_ptr->transformations & PNG_PACKSWAP)
01447 png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
01448 #endif
01449
01450 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
01451
01452 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
01453 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
01454 png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
01455 #endif
01456
01457 #if defined(PNG_READ_FILLER_SUPPORTED)
01458 if (png_ptr->transformations & PNG_FILLER)
01459 png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
01460 (png_uint_32)png_ptr->filler, png_ptr->flags);
01461 #endif
01462
01463 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
01464 if (png_ptr->transformations & PNG_INVERT_ALPHA)
01465 png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
01466 #endif
01467
01468 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
01469 if (png_ptr->transformations & PNG_SWAP_ALPHA)
01470 png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
01471 #endif
01472
01473 #if defined(PNG_READ_SWAP_SUPPORTED)
01474 if (png_ptr->transformations & PNG_SWAP_BYTES)
01475 png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
01476 #endif
01477
01478 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
01479 if (png_ptr->transformations & PNG_USER_TRANSFORM)
01480 {
01481 if (png_ptr->read_user_transform_fn != NULL)
01482 (*(png_ptr->read_user_transform_fn))
01483 (png_ptr,
01484 &(png_ptr->row_info),
01485
01486
01487
01488
01489
01490
01491 png_ptr->row_buf + 1);
01492 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
01493 if (png_ptr->user_transform_depth)
01494 png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
01495 if (png_ptr->user_transform_channels)
01496 png_ptr->row_info.channels = png_ptr->user_transform_channels;
01497 #endif
01498 png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
01499 png_ptr->row_info.channels);
01500 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
01501 png_ptr->row_info.width);
01502 }
01503 #endif
01504
01505 }
01506
01507 #if defined(PNG_READ_PACK_SUPPORTED)
01508
01509
01510
01511
01512
01513
01514 void
01515 png_do_unpack(png_row_infop row_info, png_bytep row)
01516 {
01517 png_debug(1, "in png_do_unpack\n");
01518 #if defined(PNG_USELESS_TESTS_SUPPORTED)
01519 if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
01520 #else
01521 if (row_info->bit_depth < 8)
01522 #endif
01523 {
01524 png_uint_32 i;
01525 png_uint_32 row_width=row_info->width;
01526
01527 switch (row_info->bit_depth)
01528 {
01529 case 1:
01530 {
01531 png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
01532 png_bytep dp = row + (png_size_t)row_width - 1;
01533 png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
01534 for (i = 0; i < row_width; i++)
01535 {
01536 *dp = (png_byte)((*sp >> shift) & 0x01);
01537 if (shift == 7)
01538 {
01539 shift = 0;
01540 sp--;
01541 }
01542 else
01543 shift++;
01544
01545 dp--;
01546 }
01547 break;
01548 }
01549 case 2:
01550 {
01551
01552 png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
01553 png_bytep dp = row + (png_size_t)row_width - 1;
01554 png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
01555 for (i = 0; i < row_width; i++)
01556 {
01557 *dp = (png_byte)((*sp >> shift) & 0x03);
01558 if (shift == 6)
01559 {
01560 shift = 0;
01561 sp--;
01562 }
01563 else
01564 shift += 2;
01565
01566 dp--;
01567 }
01568 break;
01569 }
01570 case 4:
01571 {
01572 png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
01573 png_bytep dp = row + (png_size_t)row_width - 1;
01574 png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
01575 for (i = 0; i < row_width; i++)
01576 {
01577 *dp = (png_byte)((*sp >> shift) & 0x0f);
01578 if (shift == 4)
01579 {
01580 shift = 0;
01581 sp--;
01582 }
01583 else
01584 shift = 4;
01585
01586 dp--;
01587 }
01588 break;
01589 }
01590 }
01591 row_info->bit_depth = 8;
01592 row_info->pixel_depth = (png_byte)(8 * row_info->channels);
01593 row_info->rowbytes = row_width * row_info->channels;
01594 }
01595 }
01596 #endif
01597
01598 #if defined(PNG_READ_SHIFT_SUPPORTED)
01599
01600
01601
01602
01603
01604 void
01605 png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
01606 {
01607 png_debug(1, "in png_do_unshift\n");
01608 if (
01609 #if defined(PNG_USELESS_TESTS_SUPPORTED)
01610 row != NULL && row_info != NULL && sig_bits != NULL &&
01611 #endif
01612 row_info->color_type != PNG_COLOR_TYPE_PALETTE)
01613 {
01614 int shift[4];
01615 int channels = 0;
01616 int c;
01617 png_uint_16 value = 0;
01618 png_uint_32 row_width = row_info->width;
01619
01620 if (row_info->color_type & PNG_COLOR_MASK_COLOR)
01621 {
01622 shift[channels++] = row_info->bit_depth - sig_bits->red;
01623 shift[channels++] = row_info->bit_depth - sig_bits->green;
01624 shift[channels++] = row_info->bit_depth - sig_bits->blue;
01625 }
01626 else
01627 {
01628 shift[channels++] = row_info->bit_depth - sig_bits->gray;
01629 }
01630 if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
01631 {
01632 shift[channels++] = row_info->bit_depth - sig_bits->alpha;
01633 }
01634
01635 for (c = 0; c < channels; c++)
01636 {
01637 if (shift[c] <= 0)
01638 shift[c] = 0;
01639 else
01640 value = 1;
01641 }
01642
01643 if (!value)
01644 return;
01645
01646 switch (row_info->bit_depth)
01647 {
01648 case 2:
01649 {
01650 png_bytep bp;
01651 png_uint_32 i;
01652 png_uint_32 istop = row_info->rowbytes;
01653
01654 for (bp = row, i = 0; i < istop; i++)
01655 {
01656 *bp >>= 1;
01657 *bp++ &= 0x55;
01658 }
01659 break;
01660 }
01661 case 4:
01662 {
01663 png_bytep bp = row;
01664 png_uint_32 i;
01665 png_uint_32 istop = row_info->rowbytes;
01666 png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
01667 (png_byte)((int)0xf >> shift[0]));
01668
01669 for (i = 0; i < istop; i++)
01670 {
01671 *bp >>= shift[0];
01672 *bp++ &= mask;
01673 }
01674 break;
01675 }
01676 case 8:
01677 {
01678 png_bytep bp = row;
01679 png_uint_32 i;
01680 png_uint_32 istop = row_width * channels;
01681
01682 for (i = 0; i < istop; i++)
01683 {
01684 *bp++ >>= shift[i%channels];
01685 }
01686 break;
01687 }
01688 case 16:
01689 {
01690 png_bytep bp = row;
01691 png_uint_32 i;
01692 png_uint_32 istop = channels * row_width;
01693
01694 for (i = 0; i < istop; i++)
01695 {
01696 value = (png_uint_16)((*bp << 8) + *(bp + 1));
01697 value >>= shift[i%channels];
01698 *bp++ = (png_byte)(value >> 8);
01699 *bp++ = (png_byte)(value & 0xff);
01700 }
01701 break;
01702 }
01703 }
01704 }
01705 }
01706 #endif
01707
01708 #if defined(PNG_READ_16_TO_8_SUPPORTED)
01709
01710 void
01711 png_do_chop(png_row_infop row_info, png_bytep row)
01712 {
01713 png_debug(1, "in png_do_chop\n");
01714 #if defined(PNG_USELESS_TESTS_SUPPORTED)
01715 if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
01716 #else
01717 if (row_info->bit_depth == 16)
01718 #endif
01719 {
01720 png_bytep sp = row;
01721 png_bytep dp = row;
01722 png_uint_32 i;
01723 png_uint_32 istop = row_info->width * row_info->channels;
01724
01725 for (i = 0; i<istop; i++, sp += 2, dp++)
01726 {
01727 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750 *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
01751 #else
01752
01753 *dp = *sp;
01754 #endif
01755 }
01756 row_info->bit_depth = 8;
01757 row_info->pixel_depth = (png_byte)(8 * row_info->channels);
01758 row_info->rowbytes = row_info->width * row_info->channels;
01759 }
01760 }
01761 #endif
01762
01763 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
01764 void
01765 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
01766 {
01767 png_debug(1, "in png_do_read_swap_alpha\n");
01768 #if defined(PNG_USELESS_TESTS_SUPPORTED)
01769 if (row != NULL && row_info != NULL)
01770 #endif
01771 {
01772 png_uint_32 row_width = row_info->width;
01773 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
01774 {
01775
01776 if (row_info->bit_depth == 8)
01777 {
01778 png_bytep sp = row + row_info->rowbytes;
01779 png_bytep dp = sp;
01780 png_byte save;
01781 png_uint_32 i;
01782
01783 for (i = 0; i < row_width; i++)
01784 {
01785 save = *(--sp);
01786 *(--dp) = *(--sp);
01787 *(--dp) = *(--sp);
01788 *(--dp) = *(--sp);
01789 *(--dp) = save;
01790 }
01791 }
01792
01793 else
01794 {
01795 png_bytep sp = row + row_info->rowbytes;
01796 png_bytep dp = sp;
01797 png_byte save[2];
01798 png_uint_32 i;
01799
01800 for (i = 0; i < row_width; i++)
01801 {
01802 save[0] = *(--sp);
01803 save[1] = *(--sp);
01804 *(--dp) = *(--sp);
01805 *(--dp) = *(--sp);
01806 *(--dp) = *(--sp);
01807 *(--dp) = *(--sp);
01808 *(--dp) = *(--sp);
01809 *(--dp) = *(--sp);
01810 *(--dp) = save[0];
01811 *(--dp) = save[1];
01812 }
01813 }
01814 }
01815 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
01816 {
01817
01818 if (row_info->bit_depth == 8)
01819 {
01820 png_bytep sp = row + row_info->rowbytes;
01821 png_bytep dp = sp;
01822 png_byte save;
01823 png_uint_32 i;
01824
01825 for (i = 0; i < row_width; i++)
01826 {
01827 save = *(--sp);
01828 *(--dp) = *(--sp);
01829 *(--dp) = save;
01830 }
01831 }
01832
01833 else
01834 {
01835 png_bytep sp = row + row_info->rowbytes;
01836 png_bytep dp = sp;
01837 png_byte save[2];
01838 png_uint_32 i;
01839
01840 for (i = 0; i < row_width; i++)
01841 {
01842 save[0] = *(--sp);
01843 save[1] = *(--sp);
01844 *(--dp) = *(--sp);
01845 *(--dp) = *(--sp);
01846 *(--dp) = save[0];
01847 *(--dp) = save[1];
01848 }
01849 }
01850 }
01851 }
01852 }
01853 #endif
01854
01855 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
01856 void
01857 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
01858 {
01859 png_debug(1, "in png_do_read_invert_alpha\n");
01860 #if defined(PNG_USELESS_TESTS_SUPPORTED)
01861 if (row != NULL && row_info != NULL)
01862 #endif
01863 {
01864 png_uint_32 row_width = row_info->width;
01865 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
01866 {
01867
01868 if (row_info->bit_depth == 8)
01869 {
01870 png_bytep sp = row + row_info->rowbytes;
01871 png_bytep dp = sp;
01872 png_uint_32 i;
01873
01874 for (i = 0; i < row_width; i++)
01875 {
01876 *(--dp) = (png_byte)(255 - *(--sp));
01877
01878
01879
01880
01881
01882
01883
01884 sp-=3;
01885 dp=sp;
01886 }
01887 }
01888
01889 else
01890 {
01891 png_bytep sp = row + row_info->rowbytes;
01892 png_bytep dp = sp;
01893 png_uint_32 i;
01894
01895 for (i = 0; i < row_width; i++)
01896 {
01897 *(--dp) = (png_byte)(255 - *(--sp));
01898 *(--dp) = (png_byte)(255 - *(--sp));
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909 sp-=6;
01910 dp=sp;
01911 }
01912 }
01913 }
01914 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
01915 {
01916
01917 if (row_info->bit_depth == 8)
01918 {
01919 png_bytep sp = row + row_info->rowbytes;
01920 png_bytep dp = sp;
01921 png_uint_32 i;
01922
01923 for (i = 0; i < row_width; i++)
01924 {
01925 *(--dp) = (png_byte)(255 - *(--sp));
01926 *(--dp) = *(--sp);
01927 }
01928 }
01929
01930 else
01931 {
01932 png_bytep sp = row + row_info->rowbytes;
01933 png_bytep dp = sp;
01934 png_uint_32 i;
01935
01936 for (i = 0; i < row_width; i++)
01937 {
01938 *(--dp) = (png_byte)(255 - *(--sp));
01939 *(--dp) = (png_byte)(255 - *(--sp));
01940
01941
01942
01943
01944 sp-=2;
01945 dp=sp;
01946 }
01947 }
01948 }
01949 }
01950 }
01951 #endif
01952
01953 #if defined(PNG_READ_FILLER_SUPPORTED)
01954
01955 void
01956 png_do_read_filler(png_row_infop row_info, png_bytep row,
01957 png_uint_32 filler, png_uint_32 flags)
01958 {
01959 png_uint_32 i;
01960 png_uint_32 row_width = row_info->width;
01961
01962 png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
01963 png_byte lo_filler = (png_byte)(filler & 0xff);
01964
01965 png_debug(1, "in png_do_read_filler\n");
01966 if (
01967 #if defined(PNG_USELESS_TESTS_SUPPORTED)
01968 row != NULL && row_info != NULL &&
01969 #endif
01970 row_info->color_type == PNG_COLOR_TYPE_GRAY)
01971 {
01972 if (row_info->bit_depth == 8)
01973 {
01974
01975 if (flags & PNG_FLAG_FILLER_AFTER)
01976 {
01977 png_bytep sp = row + (png_size_t)row_width;
01978 png_bytep dp = sp + (png_size_t)row_width;
01979 for (i = 1; i < row_width; i++)
01980 {
01981 *(--dp) = lo_filler;
01982 *(--dp) = *(--sp);
01983 }
01984 *(--dp) = lo_filler;
01985 row_info->channels = 2;
01986 row_info->pixel_depth = 16;
01987 row_info->rowbytes = row_width * 2;
01988 }
01989
01990 else
01991 {
01992 png_bytep sp = row + (png_size_t)row_width;
01993 png_bytep dp = sp + (png_size_t)row_width;
01994 for (i = 0; i < row_width; i++)
01995 {
01996 *(--dp) = *(--sp);
01997 *(--dp) = lo_filler;
01998 }
01999 row_info->channels = 2;
02000 row_info->pixel_depth = 16;
02001 row_info->rowbytes = row_width * 2;
02002 }
02003 }
02004 else if (row_info->bit_depth == 16)
02005 {
02006
02007 if (flags & PNG_FLAG_FILLER_AFTER)
02008 {
02009 png_bytep sp = row + (png_size_t)row_width * 2;
02010 png_bytep dp = sp + (png_size_t)row_width * 2;
02011 for (i = 1; i < row_width; i++)
02012 {
02013 *(--dp) = hi_filler;
02014 *(--dp) = lo_filler;
02015 *(--dp) = *(--sp);
02016 *(--dp) = *(--sp);
02017 }
02018 *(--dp) = hi_filler;
02019 *(--dp) = lo_filler;
02020 row_info->channels = 2;
02021 row_info->pixel_depth = 32;
02022 row_info->rowbytes = row_width * 4;
02023 }
02024
02025 else
02026 {
02027 png_bytep sp = row + (png_size_t)row_width * 2;
02028 png_bytep dp = sp + (png_size_t)row_width * 2;
02029 for (i = 0; i < row_width; i++)
02030 {
02031 *(--dp) = *(--sp);
02032 *(--dp) = *(--sp);
02033 *(--dp) = hi_filler;
02034 *(--dp) = lo_filler;
02035 }
02036 row_info->channels = 2;
02037 row_info->pixel_depth = 32;
02038 row_info->rowbytes = row_width * 4;
02039 }
02040 }
02041 }
02042 else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
02043 {
02044 if (row_info->bit_depth == 8)
02045 {
02046
02047 if (flags & PNG_FLAG_FILLER_AFTER)
02048 {
02049 png_bytep sp = row + (png_size_t)row_width * 3;
02050 png_bytep dp = sp + (png_size_t)row_width;
02051 for (i = 1; i < row_width; i++)
02052 {
02053 *(--dp) = lo_filler;
02054 *(--dp) = *(--sp);
02055 *(--dp) = *(--sp);
02056 *(--dp) = *(--sp);
02057 }
02058 *(--dp) = lo_filler;
02059 row_info->channels = 4;
02060 row_info->pixel_depth = 32;
02061 row_info->rowbytes = row_width * 4;
02062 }
02063
02064 else
02065 {
02066 png_bytep sp = row + (png_size_t)row_width * 3;
02067 png_bytep dp = sp + (png_size_t)row_width;
02068 for (i = 0; i < row_width; i++)
02069 {
02070 *(--dp) = *(--sp);
02071 *(--dp) = *(--sp);
02072 *(--dp) = *(--sp);
02073 *(--dp) = lo_filler;
02074 }
02075 row_info->channels = 4;
02076 row_info->pixel_depth = 32;
02077 row_info->rowbytes = row_width * 4;
02078 }
02079 }
02080 else if (row_info->bit_depth == 16)
02081 {
02082
02083 if (flags & PNG_FLAG_FILLER_AFTER)
02084 {
02085 png_bytep sp = row + (png_size_t)row_width * 6;
02086 png_bytep dp = sp + (png_size_t)row_width * 2;
02087 for (i = 1; i < row_width; i++)
02088 {
02089 *(--dp) = hi_filler;
02090 *(--dp) = lo_filler;
02091 *(--dp) = *(--sp);
02092 *(--dp) = *(--sp);
02093 *(--dp) = *(--sp);
02094 *(--dp) = *(--sp);
02095 *(--dp) = *(--sp);
02096 *(--dp) = *(--sp);
02097 }
02098 *(--dp) = hi_filler;
02099 *(--dp) = lo_filler;
02100 row_info->channels = 4;
02101 row_info->pixel_depth = 64;
02102 row_info->rowbytes = row_width * 8;
02103 }
02104
02105 else
02106 {
02107 png_bytep sp = row + (png_size_t)row_width * 6;
02108 png_bytep dp = sp + (png_size_t)row_width * 2;
02109 for (i = 0; i < row_width; i++)
02110 {
02111 *(--dp) = *(--sp);
02112 *(--dp) = *(--sp);
02113 *(--dp) = *(--sp);
02114 *(--dp) = *(--sp);
02115 *(--dp) = *(--sp);
02116 *(--dp) = *(--sp);
02117 *(--dp) = hi_filler;
02118 *(--dp) = lo_filler;
02119 }
02120 row_info->channels = 4;
02121 row_info->pixel_depth = 64;
02122 row_info->rowbytes = row_width * 8;
02123 }
02124 }
02125 }
02126 }
02127 #endif
02128
02129 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
02130
02131 void
02132 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
02133 {
02134 png_uint_32 i;
02135 png_uint_32 row_width = row_info->width;
02136
02137 png_debug(1, "in png_do_gray_to_rgb\n");
02138 if (row_info->bit_depth >= 8 &&
02139 #if defined(PNG_USELESS_TESTS_SUPPORTED)
02140 row != NULL && row_info != NULL &&
02141 #endif
02142 !(row_info->color_type & PNG_COLOR_MASK_COLOR))
02143 {
02144 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
02145 {
02146 if (row_info->bit_depth == 8)
02147 {
02148 png_bytep sp = row + (png_size_t)row_width - 1;
02149 png_bytep dp = sp + (png_size_t)row_width * 2;
02150 for (i = 0; i < row_width; i++)
02151 {
02152 *(dp--) = *sp;
02153 *(dp--) = *sp;
02154 *(dp--) = *(sp--);
02155 }
02156 }
02157 else
02158 {
02159 png_bytep sp = row + (png_size_t)row_width * 2 - 1;
02160 png_bytep dp = sp + (png_size_t)row_width * 4;
02161 for (i = 0; i < row_width; i++)
02162 {
02163 *(dp--) = *sp;
02164 *(dp--) = *(sp - 1);
02165 *(dp--) = *sp;
02166 *(dp--) = *(sp - 1);
02167 *(dp--) = *(sp--);
02168 *(dp--) = *(sp--);
02169 }
02170 }
02171 }
02172 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
02173 {
02174 if (row_info->bit_depth == 8)
02175 {
02176 png_bytep sp = row + (png_size_t)row_width * 2 - 1;
02177 png_bytep dp = sp + (png_size_t)row_width * 2;
02178 for (i = 0; i < row_width; i++)
02179 {
02180 *(dp--) = *(sp--);
02181 *(dp--) = *sp;
02182 *(dp--) = *sp;
02183 *(dp--) = *(sp--);
02184 }
02185 }
02186 else
02187 {
02188 png_bytep sp = row + (png_size_t)row_width * 4 - 1;
02189 png_bytep dp = sp + (png_size_t)row_width * 4;
02190 for (i = 0; i < row_width; i++)
02191 {
02192 *(dp--) = *(sp--);
02193 *(dp--) = *(sp--);
02194 *(dp--) = *sp;
02195 *(dp--) = *(sp - 1);
02196 *(dp--) = *sp;
02197 *(dp--) = *(sp - 1);
02198 *(dp--) = *(sp--);
02199 *(dp--) = *(sp--);
02200 }
02201 }
02202 }
02203 row_info->channels += (png_byte)2;
02204 row_info->color_type |= PNG_COLOR_MASK_COLOR;
02205 row_info->pixel_depth = (png_byte)(row_info->channels *
02206 row_info->bit_depth);
02207 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
02208 }
02209 }
02210 #endif
02211
02212 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234 int
02235 png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
02236
02237 {
02238 png_uint_32 i;
02239
02240 png_uint_32 row_width = row_info->width;
02241 int rgb_error = 0;
02242
02243 png_debug(1, "in png_do_rgb_to_gray\n");
02244 if (
02245 #if defined(PNG_USELESS_TESTS_SUPPORTED)
02246 row != NULL && row_info != NULL &&
02247 #endif
02248 (row_info->color_type & PNG_COLOR_MASK_COLOR))
02249 {
02250 png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
02251 png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
02252 png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
02253
02254 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
02255 {
02256 if (row_info->bit_depth == 8)
02257 {
02258 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
02259 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
02260 {
02261 png_bytep sp = row;
02262 png_bytep dp = row;
02263
02264 for (i = 0; i < row_width; i++)
02265 {
02266 png_byte red = png_ptr->gamma_to_1[*(sp++)];
02267 png_byte green = png_ptr->gamma_to_1[*(sp++)];
02268 png_byte blue = png_ptr->gamma_to_1[*(sp++)];
02269 if (red != green || red != blue)
02270 {
02271 rgb_error |= 1;
02272 *(dp++) = png_ptr->gamma_from_1[
02273 (rc*red + gc*green + bc*blue)>>15];
02274 }
02275 else
02276 *(dp++) = *(sp - 1);
02277 }
02278 }
02279 else
02280 #endif
02281 {
02282 png_bytep sp = row;
02283 png_bytep dp = row;
02284 for (i = 0; i < row_width; i++)
02285 {
02286 png_byte red = *(sp++);
02287 png_byte green = *(sp++);
02288 png_byte blue = *(sp++);
02289 if (red != green || red != blue)
02290 {
02291 rgb_error |= 1;
02292 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
02293 }
02294 else
02295 *(dp++) = *(sp - 1);
02296 }
02297 }
02298 }
02299
02300 else
02301 {
02302 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
02303 if (png_ptr->gamma_16_to_1 != NULL &&
02304 png_ptr->gamma_16_from_1 != NULL)
02305 {
02306 png_bytep sp = row;
02307 png_bytep dp = row;
02308 for (i = 0; i < row_width; i++)
02309 {
02310 png_uint_16 red, green, blue, w;
02311
02312 red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02313 green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02314 blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02315
02316 if (red == green && red == blue)
02317 w = red;
02318 else
02319 {
02320 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
02321 png_ptr->gamma_shift][red>>8];
02322 png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
02323 png_ptr->gamma_shift][green>>8];
02324 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
02325 png_ptr->gamma_shift][blue>>8];
02326 png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
02327 + bc*blue_1)>>15);
02328 w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
02329 png_ptr->gamma_shift][gray16 >> 8];
02330 rgb_error |= 1;
02331 }
02332
02333 *(dp++) = (png_byte)((w>>8) & 0xff);
02334 *(dp++) = (png_byte)(w & 0xff);
02335 }
02336 }
02337 else
02338 #endif
02339 {
02340 png_bytep sp = row;
02341 png_bytep dp = row;
02342 for (i = 0; i < row_width; i++)
02343 {
02344 png_uint_16 red, green, blue, gray16;
02345
02346 red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02347 green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02348 blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02349
02350 if (red != green || red != blue)
02351 rgb_error |= 1;
02352 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
02353 *(dp++) = (png_byte)((gray16>>8) & 0xff);
02354 *(dp++) = (png_byte)(gray16 & 0xff);
02355 }
02356 }
02357 }
02358 }
02359 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
02360 {
02361 if (row_info->bit_depth == 8)
02362 {
02363 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
02364 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
02365 {
02366 png_bytep sp = row;
02367 png_bytep dp = row;
02368 for (i = 0; i < row_width; i++)
02369 {
02370 png_byte red = png_ptr->gamma_to_1[*(sp++)];
02371 png_byte green = png_ptr->gamma_to_1[*(sp++)];
02372 png_byte blue = png_ptr->gamma_to_1[*(sp++)];
02373 if (red != green || red != blue)
02374 rgb_error |= 1;
02375 *(dp++) = png_ptr->gamma_from_1
02376 [(rc*red + gc*green + bc*blue)>>15];
02377 *(dp++) = *(sp++);
02378 }
02379 }
02380 else
02381 #endif
02382 {
02383 png_bytep sp = row;
02384 png_bytep dp = row;
02385 for (i = 0; i < row_width; i++)
02386 {
02387 png_byte red = *(sp++);
02388 png_byte green = *(sp++);
02389 png_byte blue = *(sp++);
02390 if (red != green || red != blue)
02391 rgb_error |= 1;
02392 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
02393 *(dp++) = *(sp++);
02394 }
02395 }
02396 }
02397 else
02398 {
02399 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
02400 if (png_ptr->gamma_16_to_1 != NULL &&
02401 png_ptr->gamma_16_from_1 != NULL)
02402 {
02403 png_bytep sp = row;
02404 png_bytep dp = row;
02405 for (i = 0; i < row_width; i++)
02406 {
02407 png_uint_16 red, green, blue, w;
02408
02409 red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02410 green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02411 blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
02412
02413 if (red == green && red == blue)
02414 w = red;
02415 else
02416 {
02417 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
02418 png_ptr->gamma_shift][red>>8];
02419 png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
02420 png_ptr->gamma_shift][green>>8];
02421 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
02422 png_ptr->gamma_shift][blue>>8];
02423 png_uint_16 gray16 = (png_uint_16)((rc * red_1
02424 + gc * green_1 + bc * blue_1)>>15);
02425 w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
02426 png_ptr->gamma_shift][gray16 >> 8];
02427 rgb_error |= 1;
02428 }
02429
02430 *(dp++) = (png_byte)((w>>8) & 0xff);
02431 *(dp++) = (png_byte)(w & 0xff);
02432 *(dp++) = *(sp++);
02433 *(dp++) = *(sp++);
02434 }
02435 }
02436 else
02437 #endif
02438 {
02439 png_bytep sp = row;
02440 png_bytep dp = row;
02441 for (i = 0; i < row_width; i++)
02442 {
02443 png_uint_16 red, green, blue, gray16;
02444 red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
02445 green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
02446 blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
02447 if (red != green || red != blue)
02448 rgb_error |= 1;
02449 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
02450 *(dp++) = (png_byte)((gray16>>8) & 0xff);
02451 *(dp++) = (png_byte)(gray16 & 0xff);
02452 *(dp++) = *(sp++);
02453 *(dp++) = *(sp++);
02454 }
02455 }
02456 }
02457 }
02458 row_info->channels -= (png_byte)2;
02459 row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
02460 row_info->pixel_depth = (png_byte)(row_info->channels *
02461 row_info->bit_depth);
02462 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
02463 }
02464 return rgb_error;
02465 }
02466 #endif
02467
02468
02469
02470
02471
02472
02473 void PNGAPI
02474 png_build_grayscale_palette(int bit_depth, png_colorp palette)
02475 {
02476 int num_palette;
02477 int color_inc;
02478 int i;
02479 int v;
02480
02481 png_debug(1, "in png_do_build_grayscale_palette\n");
02482 if (palette == NULL)
02483 return;
02484
02485 switch (bit_depth)
02486 {
02487 case 1:
02488 num_palette = 2;
02489 color_inc = 0xff;
02490 break;
02491 case 2:
02492 num_palette = 4;
02493 color_inc = 0x55;
02494 break;
02495 case 4:
02496 num_palette = 16;
02497 color_inc = 0x11;
02498 break;
02499 case 8:
02500 num_palette = 256;
02501 color_inc = 1;
02502 break;
02503 default:
02504 num_palette = 0;
02505 color_inc = 0;
02506 break;
02507 }
02508
02509 for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
02510 {
02511 palette[i].red = (png_byte)v;
02512 palette[i].green = (png_byte)v;
02513 palette[i].blue = (png_byte)v;
02514 }
02515 }
02516
02517
02518 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
02519 void
02520 png_correct_palette(png_structp png_ptr, png_colorp palette,
02521 int num_palette)
02522 {
02523 png_debug(1, "in png_correct_palette\n");
02524 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
02525 defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
02526 if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
02527 {
02528 png_color back, back_1;
02529
02530 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
02531 {
02532 back.red = png_ptr->gamma_table[png_ptr->background.red];
02533 back.green = png_ptr->gamma_table[png_ptr->background.green];
02534 back.blue = png_ptr->gamma_table[png_ptr->background.blue];
02535
02536 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
02537 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
02538 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
02539 }
02540 else
02541 {
02542 double g;
02543
02544 g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
02545
02546 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
02547 fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
02548 {
02549 back.red = png_ptr->background.red;
02550 back.green = png_ptr->background.green;
02551 back.blue = png_ptr->background.blue;
02552 }
02553 else
02554 {
02555 back.red =
02556 (png_byte)(pow((double)png_ptr->background.red/255, g) *
02557 255.0 + 0.5);
02558 back.green =
02559 (png_byte)(pow((double)png_ptr->background.green/255, g) *
02560 255.0 + 0.5);
02561 back.blue =
02562 (png_byte)(pow((double)png_ptr->background.blue/255, g) *
02563 255.0 + 0.5);
02564 }
02565
02566 g = 1.0 / png_ptr->background_gamma;
02567
02568 back_1.red =
02569 (png_byte)(pow((double)png_ptr->background.red/255, g) *
02570 255.0 + 0.5);
02571 back_1.green =
02572 (png_byte)(pow((double)png_ptr->background.green/255, g) *
02573 255.0 + 0.5);
02574 back_1.blue =
02575 (png_byte)(pow((double)png_ptr->background.blue/255, g) *
02576 255.0 + 0.5);
02577 }
02578
02579 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
02580 {
02581 png_uint_32 i;
02582
02583 for (i = 0; i < (png_uint_32)num_palette; i++)
02584 {
02585 if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
02586 {
02587 palette[i] = back;
02588 }
02589 else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
02590 {
02591 png_byte v, w;
02592
02593 v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
02594 png_composite(w, v, png_ptr->trans[i], back_1.red);
02595 palette[i].red = png_ptr->gamma_from_1[w];
02596
02597 v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
02598 png_composite(w, v, png_ptr->trans[i], back_1.green);
02599 palette[i].green = png_ptr->gamma_from_1[w];
02600
02601 v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
02602 png_composite(w, v, png_ptr->trans[i], back_1.blue);
02603 palette[i].blue = png_ptr->gamma_from_1[w];
02604 }
02605 else
02606 {
02607 palette[i].red = png_ptr->gamma_table[palette[i].red];
02608 palette[i].green = png_ptr->gamma_table[palette[i].green];
02609 palette[i].blue = png_ptr->gamma_table[palette[i].blue];
02610 }
02611 }
02612 }
02613 else
02614 {
02615 int i;
02616
02617 for (i = 0; i < num_palette; i++)
02618 {
02619 if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
02620 {
02621 palette[i] = back;
02622 }
02623 else
02624 {
02625 palette[i].red = png_ptr->gamma_table[palette[i].red];
02626 palette[i].green = png_ptr->gamma_table[palette[i].green];
02627 palette[i].blue = png_ptr->gamma_table[palette[i].blue];
02628 }
02629 }
02630 }
02631 }
02632 else
02633 #endif
02634 #if defined(PNG_READ_GAMMA_SUPPORTED)
02635 if (png_ptr->transformations & PNG_GAMMA)
02636 {
02637 int i;
02638
02639 for (i = 0; i < num_palette; i++)
02640 {
02641 palette[i].red = png_ptr->gamma_table[palette[i].red];
02642 palette[i].green = png_ptr->gamma_table[palette[i].green];
02643 palette[i].blue = png_ptr->gamma_table[palette[i].blue];
02644 }
02645 }
02646 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
02647 else
02648 #endif
02649 #endif
02650 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
02651 if (png_ptr->transformations & PNG_BACKGROUND)
02652 {
02653 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
02654 {
02655 png_color back;
02656
02657 back.red = (png_byte)png_ptr->background.red;
02658 back.green = (png_byte)png_ptr->background.green;
02659 back.blue = (png_byte)png_ptr->background.blue;
02660
02661 for (i = 0; i < (int)png_ptr->num_trans; i++)
02662 {
02663 if (png_ptr->trans[i] == 0)
02664 {
02665 palette[i].red = back.red;
02666 palette[i].green = back.green;
02667 palette[i].blue = back.blue;
02668 }
02669 else if (png_ptr->trans[i] != 0xff)
02670 {
02671 png_composite(palette[i].red, png_ptr->palette[i].red,
02672 png_ptr->trans[i], back.red);
02673 png_composite(palette[i].green, png_ptr->palette[i].green,
02674 png_ptr->trans[i], back.green);
02675 png_composite(palette[i].blue, png_ptr->palette[i].blue,
02676 png_ptr->trans[i], back.blue);
02677 }
02678 }
02679 }
02680 else
02681 {
02682 int i;
02683
02684 for (i = 0; i < num_palette; i++)
02685 {
02686 if (i == (png_byte)png_ptr->trans_values.gray)
02687 {
02688 palette[i].red = (png_byte)png_ptr->background.red;
02689 palette[i].green = (png_byte)png_ptr->background.green;
02690 palette[i].blue = (png_byte)png_ptr->background.blue;
02691 }
02692 }
02693 }
02694 }
02695 #endif
02696 }
02697 #endif
02698
02699 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
02700
02701
02702
02703
02704 void
02705 png_do_background(png_row_infop row_info, png_bytep row,
02706 png_color_16p trans_values, png_color_16p background
02707 #if defined(PNG_READ_GAMMA_SUPPORTED)
02708 , png_color_16p background_1,
02709 png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
02710 png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
02711 png_uint_16pp gamma_16_to_1, int gamma_shift
02712 #endif
02713 )
02714 {
02715 png_bytep sp, dp;
02716 png_uint_32 i;
02717 png_uint_32 row_width=row_info->width;
02718 int shift;
02719
02720 png_debug(1, "in png_do_background\n");
02721 if (background != NULL &&
02722 #if defined(PNG_USELESS_TESTS_SUPPORTED)
02723 row != NULL && row_info != NULL &&
02724 #endif
02725 (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
02726 (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
02727 {
02728 switch (row_info->color_type)
02729 {
02730 case PNG_COLOR_TYPE_GRAY:
02731 {
02732 switch (row_info->bit_depth)
02733 {
02734 case 1:
02735 {
02736 sp = row;
02737 shift = 7;
02738 for (i = 0; i < row_width; i++)
02739 {
02740 if ((png_uint_16)((*sp >> shift) & 0x01)
02741 == trans_values->gray)
02742 {
02743 *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
02744 *sp |= (png_byte)(background->gray << shift);
02745 }
02746 if (!shift)
02747 {
02748 shift = 7;
02749 sp++;
02750 }
02751 else
02752 shift--;
02753 }
02754 break;
02755 }
02756 case 2:
02757 {
02758 #if defined(PNG_READ_GAMMA_SUPPORTED)
02759 if (gamma_table != NULL)
02760 {
02761 sp = row;
02762 shift = 6;
02763 for (i = 0; i < row_width; i++)
02764 {
02765 if ((png_uint_16)((*sp >> shift) & 0x03)
02766 == trans_values->gray)
02767 {
02768 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
02769 *sp |= (png_byte)(background->gray << shift);
02770 }
02771 else
02772 {
02773 png_byte p = (png_byte)((*sp >> shift) & 0x03);
02774 png_byte g = (png_byte)((gamma_table [p | (p << 2) |
02775 (p << 4) | (p << 6)] >> 6) & 0x03);
02776 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
02777 *sp |= (png_byte)(g << shift);
02778 }
02779 if (!shift)
02780 {
02781 shift = 6;
02782 sp++;
02783 }
02784 else
02785 shift -= 2;
02786 }
02787 }
02788 else
02789 #endif
02790 {
02791 sp = row;
02792 shift = 6;
02793 for (i = 0; i < row_width; i++)
02794 {
02795 if ((png_uint_16)((*sp >> shift) & 0x03)
02796 == trans_values->gray)
02797 {
02798 *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
02799 *sp |= (png_byte)(background->gray << shift);
02800 }
02801 if (!shift)
02802 {
02803 shift = 6;
02804 sp++;
02805 }
02806 else
02807 shift -= 2;
02808 }
02809 }
02810 break;
02811 }
02812 case 4:
02813 {
02814 #if defined(PNG_READ_GAMMA_SUPPORTED)
02815 if (gamma_table != NULL)
02816 {
02817 sp = row;
02818 shift = 4;
02819 for (i = 0; i < row_width; i++)
02820 {
02821 if ((png_uint_16)((*sp >> shift) & 0x0f)
02822 == trans_values->gray)
02823 {
02824 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
02825 *sp |= (png_byte)(background->gray << shift);
02826 }
02827 else
02828 {
02829 png_byte p = (png_byte)((*sp >> shift) & 0x0f);
02830 png_byte g = (png_byte)((gamma_table[p |
02831 (p << 4)] >> 4) & 0x0f);
02832 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
02833 *sp |= (png_byte)(g << shift);
02834 }
02835 if (!shift)
02836 {
02837 shift = 4;
02838 sp++;
02839 }
02840 else
02841 shift -= 4;
02842 }
02843 }
02844 else
02845 #endif
02846 {
02847 sp = row;
02848 shift = 4;
02849 for (i = 0; i < row_width; i++)
02850 {
02851 if ((png_uint_16)((*sp >> shift) & 0x0f)
02852 == trans_values->gray)
02853 {
02854 *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
02855 *sp |= (png_byte)(background->gray << shift);
02856 }
02857 if (!shift)
02858 {
02859 shift = 4;
02860 sp++;
02861 }
02862 else
02863 shift -= 4;
02864 }
02865 }
02866 break;
02867 }
02868 case 8:
02869 {
02870 #if defined(PNG_READ_GAMMA_SUPPORTED)
02871 if (gamma_table != NULL)
02872 {
02873 sp = row;
02874 for (i = 0; i < row_width; i++, sp++)
02875 {
02876 if (*sp == trans_values->gray)
02877 {
02878 *sp = (png_byte)background->gray;
02879 }
02880 else
02881 {
02882 *sp = gamma_table[*sp];
02883 }
02884 }
02885 }
02886 else
02887 #endif
02888 {
02889 sp = row;
02890 for (i = 0; i < row_width; i++, sp++)
02891 {
02892 if (*sp == trans_values->gray)
02893 {
02894 *sp = (png_byte)background->gray;
02895 }
02896 }
02897 }
02898 break;
02899 }
02900 case 16:
02901 {
02902 #if defined(PNG_READ_GAMMA_SUPPORTED)
02903 if (gamma_16 != NULL)
02904 {
02905 sp = row;
02906 for (i = 0; i < row_width; i++, sp += 2)
02907 {
02908 png_uint_16 v;
02909
02910 v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
02911 if (v == trans_values->gray)
02912 {
02913
02914 *sp = (png_byte)((background->gray >> 8) & 0xff);
02915 *(sp + 1) = (png_byte)(background->gray & 0xff);
02916 }
02917 else
02918 {
02919 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
02920 *sp = (png_byte)((v >> 8) & 0xff);
02921 *(sp + 1) = (png_byte)(v & 0xff);
02922 }
02923 }
02924 }
02925 else
02926 #endif
02927 {
02928 sp = row;
02929 for (i = 0; i < row_width; i++, sp += 2)
02930 {
02931 png_uint_16 v;
02932
02933 v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
02934 if (v == trans_values->gray)
02935 {
02936 *sp = (png_byte)((background->gray >> 8) & 0xff);
02937 *(sp + 1) = (png_byte)(background->gray & 0xff);
02938 }
02939 }
02940 }
02941 break;
02942 }
02943 }
02944 break;
02945 }
02946 case PNG_COLOR_TYPE_RGB:
02947 {
02948 if (row_info->bit_depth == 8)
02949 {
02950 #if defined(PNG_READ_GAMMA_SUPPORTED)
02951 if (gamma_table != NULL)
02952 {
02953 sp = row;
02954 for (i = 0; i < row_width; i++, sp += 3)
02955 {
02956 if (*sp == trans_values->red &&
02957 *(sp + 1) == trans_values->green &&
02958 *(sp + 2) == trans_values->blue)
02959 {
02960 *sp = (png_byte)background->red;
02961 *(sp + 1) = (png_byte)background->green;
02962 *(sp + 2) = (png_byte)background->blue;
02963 }
02964 else
02965 {
02966 *sp = gamma_table[*sp];
02967 *(sp + 1) = gamma_table[*(sp + 1)];
02968 *(sp + 2) = gamma_table[*(sp + 2)];
02969 }
02970 }
02971 }
02972 else
02973 #endif
02974 {
02975 sp = row;
02976 for (i = 0; i < row_width; i++, sp += 3)
02977 {
02978 if (*sp == trans_values->red &&
02979 *(sp + 1) == trans_values->green &&
02980 *(sp + 2) == trans_values->blue)
02981 {
02982 *sp = (png_byte)background->red;
02983 *(sp + 1) = (png_byte)background->green;
02984 *(sp + 2) = (png_byte)background->blue;
02985 }
02986 }
02987 }
02988 }
02989 else
02990 {
02991 #if defined(PNG_READ_GAMMA_SUPPORTED)
02992 if (gamma_16 != NULL)
02993 {
02994 sp = row;
02995 for (i = 0; i < row_width; i++, sp += 6)
02996 {
02997 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
02998 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
02999 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
03000 if (r == trans_values->red && g == trans_values->green &&
03001 b == trans_values->blue)
03002 {
03003
03004 *sp = (png_byte)((background->red >> 8) & 0xff);
03005 *(sp + 1) = (png_byte)(background->red & 0xff);
03006 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
03007 *(sp + 3) = (png_byte)(background->green & 0xff);
03008 *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
03009 *(sp + 5) = (png_byte)(background->blue & 0xff);
03010 }
03011 else
03012 {
03013 png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
03014 *sp = (png_byte)((v >> 8) & 0xff);
03015 *(sp + 1) = (png_byte)(v & 0xff);
03016 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
03017 *(sp + 2) = (png_byte)((v >> 8) & 0xff);
03018 *(sp + 3) = (png_byte)(v & 0xff);
03019 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
03020 *(sp + 4) = (png_byte)((v >> 8) & 0xff);
03021 *(sp + 5) = (png_byte)(v & 0xff);
03022 }
03023 }
03024 }
03025 else
03026 #endif
03027 {
03028 sp = row;
03029 for (i = 0; i < row_width; i++, sp += 6)
03030 {
03031 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
03032 png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
03033 png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
03034
03035 if (r == trans_values->red && g == trans_values->green &&
03036 b == trans_values->blue)
03037 {
03038 *sp = (png_byte)((background->red >> 8) & 0xff);
03039 *(sp + 1) = (png_byte)(background->red & 0xff);
03040 *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
03041 *(sp + 3) = (png_byte)(background->green & 0xff);
03042 *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
03043 *(sp + 5) = (png_byte)(background->blue & 0xff);
03044 }
03045 }
03046 }
03047 }
03048 break;
03049 }
03050 case PNG_COLOR_TYPE_GRAY_ALPHA:
03051 {
03052 if (row_info->bit_depth == 8)
03053 {
03054 #if defined(PNG_READ_GAMMA_SUPPORTED)
03055 if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
03056 gamma_table != NULL)
03057 {
03058 sp = row;
03059 dp = row;
03060 for (i = 0; i < row_width; i++, sp += 2, dp++)
03061 {
03062 png_uint_16 a = *(sp + 1);
03063
03064 if (a == 0xff)
03065 {
03066 *dp = gamma_table[*sp];
03067 }
03068 else if (a == 0)
03069 {
03070
03071 *dp = (png_byte)background->gray;
03072 }
03073 else
03074 {
03075 png_byte v, w;
03076
03077 v = gamma_to_1[*sp];
03078 png_composite(w, v, a, background_1->gray);
03079 *dp = gamma_from_1[w];
03080 }
03081 }
03082 }
03083 else
03084 #endif
03085 {
03086 sp = row;
03087 dp = row;
03088 for (i = 0; i < row_width; i++, sp += 2, dp++)
03089 {
03090 png_byte a = *(sp + 1);
03091
03092 if (a == 0xff)
03093 {
03094 *dp = *sp;
03095 }
03096 #if defined(PNG_READ_GAMMA_SUPPORTED)
03097 else if (a == 0)
03098 {
03099 *dp = (png_byte)background->gray;
03100 }
03101 else
03102 {
03103 png_composite(*dp, *sp, a, background_1->gray);
03104 }
03105 #else
03106 *dp = (png_byte)background->gray;
03107 #endif
03108 }
03109 }
03110 }
03111 else
03112 {
03113 #if defined(PNG_READ_GAMMA_SUPPORTED)
03114 if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
03115 gamma_16_to_1 != NULL)
03116 {
03117 sp = row;
03118 dp = row;
03119 for (i = 0; i < row_width; i++, sp += 4, dp += 2)
03120 {
03121 png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
03122
03123 if (a == (png_uint_16)0xffff)
03124 {
03125 png_uint_16 v;
03126
03127 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
03128 *dp = (png_byte)((v >> 8) & 0xff);
03129 *(dp + 1) = (png_byte)(v & 0xff);
03130 }
03131 #if defined(PNG_READ_GAMMA_SUPPORTED)
03132 else if (a == 0)
03133 #else
03134 else
03135 #endif
03136 {
03137
03138 *dp = (png_byte)((background->gray >> 8) & 0xff);
03139 *(dp + 1) = (png_byte)(background->gray & 0xff);
03140 }
03141 #if defined(PNG_READ_GAMMA_SUPPORTED)
03142 else
03143 {
03144 png_uint_16 g, v, w;
03145
03146 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
03147 png_composite_16(v, g, a, background_1->gray);
03148 w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
03149 *dp = (png_byte)((w >> 8) & 0xff);
03150 *(dp + 1) = (png_byte)(w & 0xff);
03151 }
03152 #endif
03153 }
03154 }
03155 else
03156 #endif
03157 {
03158 sp = row;
03159 dp = row;
03160 for (i = 0; i < row_width; i++, sp += 4, dp += 2)
03161 {
03162 png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
03163 if (a == (png_uint_16)0xffff)
03164 {
03165 png_memcpy(dp, sp, 2);
03166 }
03167 #if defined(PNG_READ_GAMMA_SUPPORTED)
03168 else if (a == 0)
03169 #else
03170 else
03171 #endif
03172 {
03173 *dp = (png_byte)((background->gray >> 8) & 0xff);
03174 *(dp + 1) = (png_byte)(background->gray & 0xff);
03175 }
03176 #if defined(PNG_READ_GAMMA_SUPPORTED)
03177 else
03178 {
03179 png_uint_16 g, v;
03180
03181 g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
03182 png_composite_16(v, g, a, background_1->gray);
03183 *dp = (png_byte)((v >> 8) & 0xff);
03184 *(dp + 1) = (png_byte)(v & 0xff);
03185 }
03186 #endif
03187 }
03188 }
03189 }
03190 break;
03191 }
03192 case PNG_COLOR_TYPE_RGB_ALPHA:
03193 {
03194 if (row_info->bit_depth == 8)
03195 {
03196 #if defined(PNG_READ_GAMMA_SUPPORTED)
03197 if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
03198 gamma_table != NULL)
03199 {
03200 sp = row;
03201 dp = row;
03202 for (i = 0; i < row_width; i++, sp += 4, dp += 3)
03203 {
03204 png_byte a = *(sp + 3);
03205
03206 if (a == 0xff)
03207 {
03208 *dp = gamma_table[*sp];
03209 *(dp + 1) = gamma_table[*(sp + 1)];
03210 *(dp + 2) = gamma_table[*(sp + 2)];
03211 }
03212 else if (a == 0)
03213 {
03214
03215 *dp = (png_byte)background->red;
03216 *(dp + 1) = (png_byte)background->green;
03217 *(dp + 2) = (png_byte)background->blue;
03218 }
03219 else
03220 {
03221 png_byte v, w;
03222
03223 v = gamma_to_1[*sp];
03224 png_composite(w, v, a, background_1->red);
03225 *dp = gamma_from_1[w];
03226 v = gamma_to_1[*(sp + 1)];
03227 png_composite(w, v, a, background_1->green);
03228 *(dp + 1) = gamma_from_1[w];
03229 v = gamma_to_1[*(sp + 2)];
03230 png_composite(w, v, a, background_1->blue);
03231 *(dp + 2) = gamma_from_1[w];
03232 }
03233 }
03234 }
03235 else
03236 #endif
03237 {
03238 sp = row;
03239 dp = row;
03240 for (i = 0; i < row_width; i++, sp += 4, dp += 3)
03241 {
03242 png_byte a = *(sp + 3);
03243
03244 if (a == 0xff)
03245 {
03246 *dp = *sp;
03247 *(dp + 1) = *(sp + 1);
03248 *(dp + 2) = *(sp + 2);
03249 }
03250 else if (a == 0)
03251 {
03252 *dp = (png_byte)background->red;
03253 *(dp + 1) = (png_byte)background->green;
03254 *(dp + 2) = (png_byte)background->blue;
03255 }
03256 else
03257 {
03258 png_composite(*dp, *sp, a, background->red);
03259 png_composite(*(dp + 1), *(sp + 1), a,
03260 background->green);
03261 png_composite(*(dp + 2), *(sp + 2), a,
03262 background->blue);
03263 }
03264 }
03265 }
03266 }
03267 else
03268 {
03269 #if defined(PNG_READ_GAMMA_SUPPORTED)
03270 if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
03271 gamma_16_to_1 != NULL)
03272 {
03273 sp = row;
03274 dp = row;
03275 for (i = 0; i < row_width; i++, sp += 8, dp += 6)
03276 {
03277 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
03278 << 8) + (png_uint_16)(*(sp + 7)));
03279 if (a == (png_uint_16)0xffff)
03280 {
03281 png_uint_16 v;
03282
03283 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
03284 *dp = (png_byte)((v >> 8) & 0xff);
03285 *(dp + 1) = (png_byte)(v & 0xff);
03286 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
03287 *(dp + 2) = (png_byte)((v >> 8) & 0xff);
03288 *(dp + 3) = (png_byte)(v & 0xff);
03289 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
03290 *(dp + 4) = (png_byte)((v >> 8) & 0xff);
03291 *(dp + 5) = (png_byte)(v & 0xff);
03292 }
03293 else if (a == 0)
03294 {
03295
03296 *dp = (png_byte)((background->red >> 8) & 0xff);
03297 *(dp + 1) = (png_byte)(background->red & 0xff);
03298 *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
03299 *(dp + 3) = (png_byte)(background->green & 0xff);
03300 *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
03301 *(dp + 5) = (png_byte)(background->blue & 0xff);
03302 }
03303 else
03304 {
03305 png_uint_16 v, w, x;
03306
03307 v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
03308 png_composite_16(w, v, a, background_1->red);
03309 x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
03310 *dp = (png_byte)((x >> 8) & 0xff);
03311 *(dp + 1) = (png_byte)(x & 0xff);
03312 v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
03313 png_composite_16(w, v, a, background_1->green);
03314 x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
03315 *(dp + 2) = (png_byte)((x >> 8) & 0xff);
03316 *(dp + 3) = (png_byte)(x & 0xff);
03317 v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
03318 png_composite_16(w, v, a, background_1->blue);
03319 x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
03320 *(dp + 4) = (png_byte)((x >> 8) & 0xff);
03321 *(dp + 5) = (png_byte)(x & 0xff);
03322 }
03323 }
03324 }
03325 else
03326 #endif
03327 {
03328 sp = row;
03329 dp = row;
03330 for (i = 0; i < row_width; i++, sp += 8, dp += 6)
03331 {
03332 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
03333 << 8) + (png_uint_16)(*(sp + 7)));
03334 if (a == (png_uint_16)0xffff)
03335 {
03336 png_memcpy(dp, sp, 6);
03337 }
03338 else if (a == 0)
03339 {
03340 *dp = (png_byte)((background->red >> 8) & 0xff);
03341 *(dp + 1) = (png_byte)(background->red & 0xff);
03342 *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
03343 *(dp + 3) = (png_byte)(background->green & 0xff);
03344 *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
03345 *(dp + 5) = (png_byte)(background->blue & 0xff);
03346 }
03347 else
03348 {
03349 png_uint_16 v;
03350
03351 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
03352 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
03353 + *(sp + 3));
03354 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
03355 + *(sp + 5));
03356
03357 png_composite_16(v, r, a, background->red);
03358 *dp = (png_byte)((v >> 8) & 0xff);
03359 *(dp + 1) = (png_byte)(v & 0xff);
03360 png_composite_16(v, g, a, background->green);
03361 *(dp + 2) = (png_byte)((v >> 8) & 0xff);
03362 *(dp + 3) = (png_byte)(v & 0xff);
03363 png_composite_16(v, b, a, background->blue);
03364 *(dp + 4) = (png_byte)((v >> 8) & 0xff);
03365 *(dp + 5) = (png_byte)(v & 0xff);
03366 }
03367 }
03368 }
03369 }
03370 break;
03371 }
03372 }
03373
03374 if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
03375 {
03376 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
03377 row_info->channels--;
03378 row_info->pixel_depth = (png_byte)(row_info->channels *
03379 row_info->bit_depth);
03380 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
03381 }
03382 }
03383 }
03384 #endif
03385
03386 #if defined(PNG_READ_GAMMA_SUPPORTED)
03387
03388
03389
03390
03391
03392
03393 void
03394 png_do_gamma(png_row_infop row_info, png_bytep row,
03395 png_bytep gamma_table, png_uint_16pp gamma_16_table,
03396 int gamma_shift)
03397 {
03398 png_bytep sp;
03399 png_uint_32 i;
03400 png_uint_32 row_width=row_info->width;
03401
03402 png_debug(1, "in png_do_gamma\n");
03403 if (
03404 #if defined(PNG_USELESS_TESTS_SUPPORTED)
03405 row != NULL && row_info != NULL &&
03406 #endif
03407 ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
03408 (row_info->bit_depth == 16 && gamma_16_table != NULL)))
03409 {
03410 switch (row_info->color_type)
03411 {
03412 case PNG_COLOR_TYPE_RGB:
03413 {
03414 if (row_info->bit_depth == 8)
03415 {
03416 sp = row;
03417 for (i = 0; i < row_width; i++)
03418 {
03419 *sp = gamma_table[*sp];
03420 sp++;
03421 *sp = gamma_table[*sp];
03422 sp++;
03423 *sp = gamma_table[*sp];
03424 sp++;
03425 }
03426 }
03427 else
03428 {
03429 sp = row;
03430 for (i = 0; i < row_width; i++)
03431 {
03432 png_uint_16 v;
03433
03434 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03435 *sp = (png_byte)((v >> 8) & 0xff);
03436 *(sp + 1) = (png_byte)(v & 0xff);
03437 sp += 2;
03438 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03439 *sp = (png_byte)((v >> 8) & 0xff);
03440 *(sp + 1) = (png_byte)(v & 0xff);
03441 sp += 2;
03442 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03443 *sp = (png_byte)((v >> 8) & 0xff);
03444 *(sp + 1) = (png_byte)(v & 0xff);
03445 sp += 2;
03446 }
03447 }
03448 break;
03449 }
03450 case PNG_COLOR_TYPE_RGB_ALPHA:
03451 {
03452 if (row_info->bit_depth == 8)
03453 {
03454 sp = row;
03455 for (i = 0; i < row_width; i++)
03456 {
03457 *sp = gamma_table[*sp];
03458 sp++;
03459 *sp = gamma_table[*sp];
03460 sp++;
03461 *sp = gamma_table[*sp];
03462 sp++;
03463 sp++;
03464 }
03465 }
03466 else
03467 {
03468 sp = row;
03469 for (i = 0; i < row_width; i++)
03470 {
03471 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03472 *sp = (png_byte)((v >> 8) & 0xff);
03473 *(sp + 1) = (png_byte)(v & 0xff);
03474 sp += 2;
03475 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03476 *sp = (png_byte)((v >> 8) & 0xff);
03477 *(sp + 1) = (png_byte)(v & 0xff);
03478 sp += 2;
03479 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03480 *sp = (png_byte)((v >> 8) & 0xff);
03481 *(sp + 1) = (png_byte)(v & 0xff);
03482 sp += 4;
03483 }
03484 }
03485 break;
03486 }
03487 case PNG_COLOR_TYPE_GRAY_ALPHA:
03488 {
03489 if (row_info->bit_depth == 8)
03490 {
03491 sp = row;
03492 for (i = 0; i < row_width; i++)
03493 {
03494 *sp = gamma_table[*sp];
03495 sp += 2;
03496 }
03497 }
03498 else
03499 {
03500 sp = row;
03501 for (i = 0; i < row_width; i++)
03502 {
03503 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03504 *sp = (png_byte)((v >> 8) & 0xff);
03505 *(sp + 1) = (png_byte)(v & 0xff);
03506 sp += 4;
03507 }
03508 }
03509 break;
03510 }
03511 case PNG_COLOR_TYPE_GRAY:
03512 {
03513 if (row_info->bit_depth == 2)
03514 {
03515 sp = row;
03516 for (i = 0; i < row_width; i += 4)
03517 {
03518 int a = *sp & 0xc0;
03519 int b = *sp & 0x30;
03520 int c = *sp & 0x0c;
03521 int d = *sp & 0x03;
03522
03523 *sp = (png_byte)(
03524 ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
03525 ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
03526 ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
03527 ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
03528 sp++;
03529 }
03530 }
03531 if (row_info->bit_depth == 4)
03532 {
03533 sp = row;
03534 for (i = 0; i < row_width; i += 2)
03535 {
03536 int msb = *sp & 0xf0;
03537 int lsb = *sp & 0x0f;
03538
03539 *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
03540 | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
03541 sp++;
03542 }
03543 }
03544 else if (row_info->bit_depth == 8)
03545 {
03546 sp = row;
03547 for (i = 0; i < row_width; i++)
03548 {
03549 *sp = gamma_table[*sp];
03550 sp++;
03551 }
03552 }
03553 else if (row_info->bit_depth == 16)
03554 {
03555 sp = row;
03556 for (i = 0; i < row_width; i++)
03557 {
03558 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
03559 *sp = (png_byte)((v >> 8) & 0xff);
03560 *(sp + 1) = (png_byte)(v & 0xff);
03561 sp += 2;
03562 }
03563 }
03564 break;
03565 }
03566 }
03567 }
03568 }
03569 #endif
03570
03571 #if defined(PNG_READ_EXPAND_SUPPORTED)
03572
03573
03574
03575 void
03576 png_do_expand_palette(png_row_infop row_info, png_bytep row,
03577 png_colorp palette, png_bytep trans, int num_trans)
03578 {
03579 int shift, value;
03580 png_bytep sp, dp;
03581 png_uint_32 i;
03582 png_uint_32 row_width=row_info->width;
03583
03584 png_debug(1, "in png_do_expand_palette\n");
03585 if (
03586 #if defined(PNG_USELESS_TESTS_SUPPORTED)
03587 row != NULL && row_info != NULL &&
03588 #endif
03589 row_info->color_type == PNG_COLOR_TYPE_PALETTE)
03590 {
03591 if (row_info->bit_depth < 8)
03592 {
03593 switch (row_info->bit_depth)
03594 {
03595 case 1:
03596 {
03597 sp = row + (png_size_t)((row_width - 1) >> 3);
03598 dp = row + (png_size_t)row_width - 1;
03599 shift = 7 - (int)((row_width + 7) & 0x07);
03600 for (i = 0; i < row_width; i++)
03601 {
03602 if ((*sp >> shift) & 0x01)
03603 *dp = 1;
03604 else
03605 *dp = 0;
03606 if (shift == 7)
03607 {
03608 shift = 0;
03609 sp--;
03610 }
03611 else
03612 shift++;
03613
03614 dp--;
03615 }
03616 break;
03617 }
03618 case 2:
03619 {
03620 sp = row + (png_size_t)((row_width - 1) >> 2);
03621 dp = row + (png_size_t)row_width - 1;
03622 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
03623 for (i = 0; i < row_width; i++)
03624 {
03625 value = (*sp >> shift) & 0x03;
03626 *dp = (png_byte)value;
03627 if (shift == 6)
03628 {
03629 shift = 0;
03630 sp--;
03631 }
03632 else
03633 shift += 2;
03634
03635 dp--;
03636 }
03637 break;
03638 }
03639 case 4:
03640 {
03641 sp = row + (png_size_t)((row_width - 1) >> 1);
03642 dp = row + (png_size_t)row_width - 1;
03643 shift = (int)((row_width & 0x01) << 2);
03644 for (i = 0; i < row_width; i++)
03645 {
03646 value = (*sp >> shift) & 0x0f;
03647 *dp = (png_byte)value;
03648 if (shift == 4)
03649 {
03650 shift = 0;
03651 sp--;
03652 }
03653 else
03654 shift += 4;
03655
03656 dp--;
03657 }
03658 break;
03659 }
03660 }
03661 row_info->bit_depth = 8;
03662 row_info->pixel_depth = 8;
03663 row_info->rowbytes = row_width;
03664 }
03665 switch (row_info->bit_depth)
03666 {
03667 case 8:
03668 {
03669 if (trans != NULL)
03670 {
03671 sp = row + (png_size_t)row_width - 1;
03672 dp = row + (png_size_t)(row_width << 2) - 1;
03673
03674 for (i = 0; i < row_width; i++)
03675 {
03676 if ((int)(*sp) >= num_trans)
03677 *dp-- = 0xff;
03678 else
03679 *dp-- = trans[*sp];
03680 *dp-- = palette[*sp].blue;
03681 *dp-- = palette[*sp].green;
03682 *dp-- = palette[*sp].red;
03683 sp--;
03684 }
03685 row_info->bit_depth = 8;
03686 row_info->pixel_depth = 32;
03687 row_info->rowbytes = row_width * 4;
03688 row_info->color_type = 6;
03689 row_info->channels = 4;
03690 }
03691 else
03692 {
03693 sp = row + (png_size_t)row_width - 1;
03694 dp = row + (png_size_t)(row_width * 3) - 1;
03695
03696 for (i = 0; i < row_width; i++)
03697 {
03698 *dp-- = palette[*sp].blue;
03699 *dp-- = palette[*sp].green;
03700 *dp-- = palette[*sp].red;
03701 sp--;
03702 }
03703 row_info->bit_depth = 8;
03704 row_info->pixel_depth = 24;
03705 row_info->rowbytes = row_width * 3;
03706 row_info->color_type = 2;
03707 row_info->channels = 3;
03708 }
03709 break;
03710 }
03711 }
03712 }
03713 }
03714
03715
03716
03717
03718 void
03719 png_do_expand(png_row_infop row_info, png_bytep row,
03720 png_color_16p trans_value)
03721 {
03722 int shift, value;
03723 png_bytep sp, dp;
03724 png_uint_32 i;
03725 png_uint_32 row_width=row_info->width;
03726
03727 png_debug(1, "in png_do_expand\n");
03728 #if defined(PNG_USELESS_TESTS_SUPPORTED)
03729 if (row != NULL && row_info != NULL)
03730 #endif
03731 {
03732 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
03733 {
03734 png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
03735
03736 if (row_info->bit_depth < 8)
03737 {
03738 switch (row_info->bit_depth)
03739 {
03740 case 1:
03741 {
03742 gray = (png_uint_16)((gray&0x01)*0xff);
03743 sp = row + (png_size_t)((row_width - 1) >> 3);
03744 dp = row + (png_size_t)row_width - 1;
03745 shift = 7 - (int)((row_width + 7) & 0x07);
03746 for (i = 0; i < row_width; i++)
03747 {
03748 if ((*sp >> shift) & 0x01)
03749 *dp = 0xff;
03750 else
03751 *dp = 0;
03752 if (shift == 7)
03753 {
03754 shift = 0;
03755 sp--;
03756 }
03757 else
03758 shift++;
03759
03760 dp--;
03761 }
03762 break;
03763 }
03764 case 2:
03765 {
03766 gray = (png_uint_16)((gray&0x03)*0x55);
03767 sp = row + (png_size_t)((row_width - 1) >> 2);
03768 dp = row + (png_size_t)row_width - 1;
03769 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
03770 for (i = 0; i < row_width; i++)
03771 {
03772 value = (*sp >> shift) & 0x03;
03773 *dp = (png_byte)(value | (value << 2) | (value << 4) |
03774 (value << 6));
03775 if (shift == 6)
03776 {
03777 shift = 0;
03778 sp--;
03779 }
03780 else
03781 shift += 2;
03782
03783 dp--;
03784 }
03785 break;
03786 }
03787 case 4:
03788 {
03789 gray = (png_uint_16)((gray&0x0f)*0x11);
03790 sp = row + (png_size_t)((row_width - 1) >> 1);
03791 dp = row + (png_size_t)row_width - 1;
03792 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
03793 for (i = 0; i < row_width; i++)
03794 {
03795 value = (*sp >> shift) & 0x0f;
03796 *dp = (png_byte)(value | (value << 4));
03797 if (shift == 4)
03798 {
03799 shift = 0;
03800 sp--;
03801 }
03802 else
03803 shift = 4;
03804
03805 dp--;
03806 }
03807 break;
03808 }
03809 }
03810 row_info->bit_depth = 8;
03811 row_info->pixel_depth = 8;
03812 row_info->rowbytes = row_width;
03813 }
03814
03815 if (trans_value != NULL)
03816 {
03817 if (row_info->bit_depth == 8)
03818 {
03819 gray = gray & 0xff;
03820 sp = row + (png_size_t)row_width - 1;
03821 dp = row + (png_size_t)(row_width << 1) - 1;
03822 for (i = 0; i < row_width; i++)
03823 {
03824 if (*sp == gray)
03825 *dp-- = 0;
03826 else
03827 *dp-- = 0xff;
03828 *dp-- = *sp--;
03829 }
03830 }
03831 else if (row_info->bit_depth == 16)
03832 {
03833 png_byte gray_high = (gray >> 8) & 0xff;
03834 png_byte gray_low = gray & 0xff;
03835 sp = row + row_info->rowbytes - 1;
03836 dp = row + (row_info->rowbytes << 1) - 1;
03837 for (i = 0; i < row_width; i++)
03838 {
03839 if (*(sp - 1) == gray_high && *(sp) == gray_low)
03840 {
03841 *dp-- = 0;
03842 *dp-- = 0;
03843 }
03844 else
03845 {
03846 *dp-- = 0xff;
03847 *dp-- = 0xff;
03848 }
03849 *dp-- = *sp--;
03850 *dp-- = *sp--;
03851 }
03852 }
03853 row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
03854 row_info->channels = 2;
03855 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
03856 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
03857 row_width);
03858 }
03859 }
03860 else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
03861 {
03862 if (row_info->bit_depth == 8)
03863 {
03864 png_byte red = trans_value->red & 0xff;
03865 png_byte green = trans_value->green & 0xff;
03866 png_byte blue = trans_value->blue & 0xff;
03867 sp = row + (png_size_t)row_info->rowbytes - 1;
03868 dp = row + (png_size_t)(row_width << 2) - 1;
03869 for (i = 0; i < row_width; i++)
03870 {
03871 if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
03872 *dp-- = 0;
03873 else
03874 *dp-- = 0xff;
03875 *dp-- = *sp--;
03876 *dp-- = *sp--;
03877 *dp-- = *sp--;
03878 }
03879 }
03880 else if (row_info->bit_depth == 16)
03881 {
03882 png_byte red_high = (trans_value->red >> 8) & 0xff;
03883 png_byte green_high = (trans_value->green >> 8) & 0xff;
03884 png_byte blue_high = (trans_value->blue >> 8) & 0xff;
03885 png_byte red_low = trans_value->red & 0xff;
03886 png_byte green_low = trans_value->green & 0xff;
03887 png_byte blue_low = trans_value->blue & 0xff;
03888 sp = row + row_info->rowbytes - 1;
03889 dp = row + (png_size_t)(row_width << 3) - 1;
03890 for (i = 0; i < row_width; i++)
03891 {
03892 if (*(sp - 5) == red_high &&
03893 *(sp - 4) == red_low &&
03894 *(sp - 3) == green_high &&
03895 *(sp - 2) == green_low &&
03896 *(sp - 1) == blue_high &&
03897 *(sp ) == blue_low)
03898 {
03899 *dp-- = 0;
03900 *dp-- = 0;
03901 }
03902 else
03903 {
03904 *dp-- = 0xff;
03905 *dp-- = 0xff;
03906 }
03907 *dp-- = *sp--;
03908 *dp-- = *sp--;
03909 *dp-- = *sp--;
03910 *dp-- = *sp--;
03911 *dp-- = *sp--;
03912 *dp-- = *sp--;
03913 }
03914 }
03915 row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
03916 row_info->channels = 4;
03917 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
03918 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
03919 }
03920 }
03921 }
03922 #endif
03923
03924 #if defined(PNG_READ_DITHER_SUPPORTED)
03925 void
03926 png_do_dither(png_row_infop row_info, png_bytep row,
03927 png_bytep palette_lookup, png_bytep dither_lookup)
03928 {
03929 png_bytep sp, dp;
03930 png_uint_32 i;
03931 png_uint_32 row_width=row_info->width;
03932
03933 png_debug(1, "in png_do_dither\n");
03934 #if defined(PNG_USELESS_TESTS_SUPPORTED)
03935 if (row != NULL && row_info != NULL)
03936 #endif
03937 {
03938 if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
03939 palette_lookup && row_info->bit_depth == 8)
03940 {
03941 int r, g, b, p;
03942 sp = row;
03943 dp = row;
03944 for (i = 0; i < row_width; i++)
03945 {
03946 r = *sp++;
03947 g = *sp++;
03948 b = *sp++;
03949
03950
03951
03952
03953
03954
03955
03956
03957 p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
03958 ((1 << PNG_DITHER_RED_BITS) - 1)) <<
03959 (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
03960 (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
03961 ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
03962 (PNG_DITHER_BLUE_BITS)) |
03963 ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
03964 ((1 << PNG_DITHER_BLUE_BITS) - 1));
03965
03966 *dp++ = palette_lookup[p];
03967 }
03968 row_info->color_type = PNG_COLOR_TYPE_PALETTE;
03969 row_info->channels = 1;
03970 row_info->pixel_depth = row_info->bit_depth;
03971 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
03972 }
03973 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
03974 palette_lookup != NULL && row_info->bit_depth == 8)
03975 {
03976 int r, g, b, p;
03977 sp = row;
03978 dp = row;
03979 for (i = 0; i < row_width; i++)
03980 {
03981 r = *sp++;
03982 g = *sp++;
03983 b = *sp++;
03984 sp++;
03985
03986 p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
03987 ((1 << PNG_DITHER_RED_BITS) - 1)) <<
03988 (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
03989 (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
03990 ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
03991 (PNG_DITHER_BLUE_BITS)) |
03992 ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
03993 ((1 << PNG_DITHER_BLUE_BITS) - 1));
03994
03995 *dp++ = palette_lookup[p];
03996 }
03997 row_info->color_type = PNG_COLOR_TYPE_PALETTE;
03998 row_info->channels = 1;
03999 row_info->pixel_depth = row_info->bit_depth;
04000 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
04001 }
04002 else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
04003 dither_lookup && row_info->bit_depth == 8)
04004 {
04005 sp = row;
04006 for (i = 0; i < row_width; i++, sp++)
04007 {
04008 *sp = dither_lookup[*sp];
04009 }
04010 }
04011 }
04012 }
04013 #endif
04014
04015 #ifdef PNG_FLOATING_POINT_SUPPORTED
04016 #if defined(PNG_READ_GAMMA_SUPPORTED)
04017 static PNG_CONST int png_gamma_shift[] =
04018 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
04019
04020
04021
04022
04023
04024
04025 void
04026 png_build_gamma_table(png_structp png_ptr)
04027 {
04028 png_debug(1, "in png_build_gamma_table\n");
04029
04030 if (png_ptr->bit_depth <= 8)
04031 {
04032 int i;
04033 double g;
04034
04035 if (png_ptr->screen_gamma > .000001)
04036 g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
04037 else
04038 g = 1.0;
04039
04040 png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
04041 (png_uint_32)256);
04042
04043 for (i = 0; i < 256; i++)
04044 {
04045 png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
04046 g) * 255.0 + .5);
04047 }
04048
04049 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
04050 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
04051 if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
04052 {
04053
04054 g = 1.0 / (png_ptr->gamma);
04055
04056 png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
04057 (png_uint_32)256);
04058
04059 for (i = 0; i < 256; i++)
04060 {
04061 png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
04062 g) * 255.0 + .5);
04063 }
04064
04065
04066 png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
04067 (png_uint_32)256);
04068
04069 if (png_ptr->screen_gamma > 0.000001)
04070 g = 1.0 / png_ptr->screen_gamma;
04071 else
04072 g = png_ptr->gamma;
04073
04074 for (i = 0; i < 256; i++)
04075 {
04076 png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
04077 g) * 255.0 + .5);
04078
04079 }
04080 }
04081 #endif
04082 }
04083 else
04084 {
04085 double g;
04086 int i, j, shift, num;
04087 int sig_bit;
04088 png_uint_32 ig;
04089
04090 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
04091 {
04092 sig_bit = (int)png_ptr->sig_bit.red;
04093 if ((int)png_ptr->sig_bit.green > sig_bit)
04094 sig_bit = png_ptr->sig_bit.green;
04095 if ((int)png_ptr->sig_bit.blue > sig_bit)
04096 sig_bit = png_ptr->sig_bit.blue;
04097 }
04098 else
04099 {
04100 sig_bit = (int)png_ptr->sig_bit.gray;
04101 }
04102
04103 if (sig_bit > 0)
04104 shift = 16 - sig_bit;
04105 else
04106 shift = 0;
04107
04108 if (png_ptr->transformations & PNG_16_TO_8)
04109 {
04110 if (shift < (16 - PNG_MAX_GAMMA_8))
04111 shift = (16 - PNG_MAX_GAMMA_8);
04112 }
04113
04114 if (shift > 8)
04115 shift = 8;
04116 if (shift < 0)
04117 shift = 0;
04118
04119 png_ptr->gamma_shift = (png_byte)shift;
04120
04121 num = (1 << (8 - shift));
04122
04123 if (png_ptr->screen_gamma > .000001)
04124 g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
04125 else
04126 g = 1.0;
04127
04128 png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
04129 (png_uint_32)(num * png_sizeof(png_uint_16p)));
04130
04131 if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
04132 {
04133 double fin, fout;
04134 png_uint_32 last, max;
04135
04136 for (i = 0; i < num; i++)
04137 {
04138 png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
04139 (png_uint_32)(256 * png_sizeof(png_uint_16)));
04140 }
04141
04142 g = 1.0 / g;
04143 last = 0;
04144 for (i = 0; i < 256; i++)
04145 {
04146 fout = ((double)i + 0.5) / 256.0;
04147 fin = pow(fout, g);
04148 max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
04149 while (last <= max)
04150 {
04151 png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
04152 [(int)(last >> (8 - shift))] = (png_uint_16)(
04153 (png_uint_16)i | ((png_uint_16)i << 8));
04154 last++;
04155 }
04156 }
04157 while (last < ((png_uint_32)num << 8))
04158 {
04159 png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
04160 [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
04161 last++;
04162 }
04163 }
04164 else
04165 {
04166 for (i = 0; i < num; i++)
04167 {
04168 png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
04169 (png_uint_32)(256 * png_sizeof(png_uint_16)));
04170
04171 ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
04172 for (j = 0; j < 256; j++)
04173 {
04174 png_ptr->gamma_16_table[i][j] =
04175 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
04176 65535.0, g) * 65535.0 + .5);
04177 }
04178 }
04179 }
04180
04181 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
04182 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
04183 if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
04184 {
04185
04186 g = 1.0 / (png_ptr->gamma);
04187
04188 png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
04189 (png_uint_32)(num * png_sizeof(png_uint_16p )));
04190
04191 for (i = 0; i < num; i++)
04192 {
04193 png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
04194 (png_uint_32)(256 * png_sizeof(png_uint_16)));
04195
04196 ig = (((png_uint_32)i *
04197 (png_uint_32)png_gamma_shift[shift]) >> 4);
04198 for (j = 0; j < 256; j++)
04199 {
04200 png_ptr->gamma_16_to_1[i][j] =
04201 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
04202 65535.0, g) * 65535.0 + .5);
04203 }
04204 }
04205
04206 if (png_ptr->screen_gamma > 0.000001)
04207 g = 1.0 / png_ptr->screen_gamma;
04208 else
04209 g = png_ptr->gamma;
04210
04211 png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
04212 (png_uint_32)(num * png_sizeof(png_uint_16p)));
04213
04214 for (i = 0; i < num; i++)
04215 {
04216 png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
04217 (png_uint_32)(256 * png_sizeof(png_uint_16)));
04218
04219 ig = (((png_uint_32)i *
04220 (png_uint_32)png_gamma_shift[shift]) >> 4);
04221 for (j = 0; j < 256; j++)
04222 {
04223 png_ptr->gamma_16_from_1[i][j] =
04224 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
04225 65535.0, g) * 65535.0 + .5);
04226 }
04227 }
04228 }
04229 #endif
04230 }
04231 }
04232 #endif
04233
04234 #endif
04235
04236 #if defined(PNG_MNG_FEATURES_SUPPORTED)
04237
04238 void
04239 png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
04240 {
04241 png_debug(1, "in png_do_read_intrapixel\n");
04242 if (
04243 #if defined(PNG_USELESS_TESTS_SUPPORTED)
04244 row != NULL && row_info != NULL &&
04245 #endif
04246 (row_info->color_type & PNG_COLOR_MASK_COLOR))
04247 {
04248 int bytes_per_pixel;
04249 png_uint_32 row_width = row_info->width;
04250 if (row_info->bit_depth == 8)
04251 {
04252 png_bytep rp;
04253 png_uint_32 i;
04254
04255 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
04256 bytes_per_pixel = 3;
04257 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
04258 bytes_per_pixel = 4;
04259 else
04260 return;
04261
04262 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
04263 {
04264 *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
04265 *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
04266 }
04267 }
04268 else if (row_info->bit_depth == 16)
04269 {
04270 png_bytep rp;
04271 png_uint_32 i;
04272
04273 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
04274 bytes_per_pixel = 6;
04275 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
04276 bytes_per_pixel = 8;
04277 else
04278 return;
04279
04280 for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
04281 {
04282 png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
04283 png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
04284 png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
04285 png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
04286 png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
04287 *(rp ) = (png_byte)((red >> 8) & 0xff);
04288 *(rp+1) = (png_byte)(red & 0xff);
04289 *(rp+4) = (png_byte)((blue >> 8) & 0xff);
04290 *(rp+5) = (png_byte)(blue & 0xff);
04291 }
04292 }
04293 }
04294 }
04295 #endif
04296 #endif