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