20#ifdef PNG_ARM_NEON_IMPLEMENTATION
21# if PNG_ARM_NEON_IMPLEMENTATION == 1
22# define PNG_ARM_NEON_INTRINSICS_AVAILABLE
23# if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64)
24# include <arm64_neon.h>
31#ifdef PNG_RISCV_RVV_IMPLEMENTATION
32# if PNG_RISCV_RVV_IMPLEMENTATION == 1
33# define PNG_RISCV_RVV_INTRINSICS_AVAILABLE
37#ifdef PNG_READ_SUPPORTED
41png_set_crc_action(png_structrp png_ptr,
int crit_action,
int ancil_action)
43 png_debug(1,
"in png_set_crc_action");
51 case PNG_CRC_NO_CHANGE:
54 case PNG_CRC_WARN_USE:
55 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
56 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
59 case PNG_CRC_QUIET_USE:
60 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
61 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
62 PNG_FLAG_CRC_CRITICAL_IGNORE;
65 case PNG_CRC_WARN_DISCARD:
67 "Can't discard critical data on CRC error");
69 case PNG_CRC_ERROR_QUIT:
73 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
80 case PNG_CRC_NO_CHANGE:
83 case PNG_CRC_WARN_USE:
84 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
85 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
88 case PNG_CRC_QUIET_USE:
89 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
90 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
91 PNG_FLAG_CRC_ANCILLARY_NOWARN;
94 case PNG_CRC_ERROR_QUIT:
95 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
96 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
99 case PNG_CRC_WARN_DISCARD:
101 case PNG_CRC_DEFAULT:
103 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
108#ifdef PNG_READ_TRANSFORMS_SUPPORTED
115png_rtran_ok(png_structrp png_ptr,
int need_IHDR)
119 if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
120 png_app_error(png_ptr,
121 "invalid after png_start_read_image or png_read_update_info");
123 else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
124 png_app_error(png_ptr,
"invalid before the PNG header has been read");
129 png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
139#ifdef PNG_READ_BACKGROUND_SUPPORTED
142png_set_background_fixed(png_structrp png_ptr,
143 png_const_color_16p background_color,
int background_gamma_code,
144 int need_expand, png_fixed_point background_gamma)
146 png_debug(1,
"in png_set_background_fixed");
148 if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
151 if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
153 png_warning(png_ptr,
"Application must supply a known background gamma");
157 png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
158 png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
159 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
161 png_ptr->background = *background_color;
162 png_ptr->background_gamma = background_gamma;
163 png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
164 if (need_expand != 0)
165 png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
167 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
170# ifdef PNG_FLOATING_POINT_SUPPORTED
172png_set_background(png_structrp png_ptr,
173 png_const_color_16p background_color,
int background_gamma_code,
174 int need_expand,
double background_gamma)
176 png_set_background_fixed(png_ptr, background_color, background_gamma_code,
177 need_expand, png_fixed(png_ptr, background_gamma,
"png_set_background"));
186#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
188png_set_scale_16(png_structrp png_ptr)
190 png_debug(1,
"in png_set_scale_16");
192 if (png_rtran_ok(png_ptr, 0) == 0)
195 png_ptr->transformations |= PNG_SCALE_16_TO_8;
199#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
202png_set_strip_16(png_structrp png_ptr)
204 png_debug(1,
"in png_set_strip_16");
206 if (png_rtran_ok(png_ptr, 0) == 0)
209 png_ptr->transformations |= PNG_16_TO_8;
213#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
215png_set_strip_alpha(png_structrp png_ptr)
217 png_debug(1,
"in png_set_strip_alpha");
219 if (png_rtran_ok(png_ptr, 0) == 0)
222 png_ptr->transformations |= PNG_STRIP_ALPHA;
226#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
278static png_fixed_point
279translate_gamma_flags(png_fixed_point output_gamma,
int is_screen)
286 if (output_gamma == PNG_DEFAULT_sRGB ||
287 output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
290 output_gamma = PNG_GAMMA_sRGB;
292 output_gamma = PNG_GAMMA_sRGB_INVERSE;
295 else if (output_gamma == PNG_GAMMA_MAC_18 ||
296 output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
299 output_gamma = PNG_GAMMA_MAC_OLD;
301 output_gamma = PNG_GAMMA_MAC_INVERSE;
307# ifdef PNG_FLOATING_POINT_SUPPORTED
308static png_fixed_point
309convert_gamma_value(png_structrp png_ptr,
double output_gamma)
318 if (output_gamma > 0 && output_gamma < 128)
319 output_gamma *= PNG_FP_1;
322 output_gamma = floor(output_gamma + .5);
324 if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
325 png_fixed_error(png_ptr,
"gamma value");
327 return (png_fixed_point)output_gamma;
332unsupported_gamma(png_structrp png_ptr, png_fixed_point gamma,
int warn)
344 if (gamma < PNG_LIB_GAMMA_MIN || gamma > PNG_LIB_GAMMA_MAX)
346# define msg "gamma out of supported range"
348 png_app_warning(png_ptr, msg);
350 png_app_error(png_ptr, msg);
359#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
361png_set_alpha_mode_fixed(png_structrp png_ptr,
int mode,
362 png_fixed_point output_gamma)
364 png_fixed_point file_gamma;
367 png_debug(1,
"in png_set_alpha_mode_fixed");
369 if (png_rtran_ok(png_ptr, 0) == 0)
372 output_gamma = translate_gamma_flags(output_gamma, 1);
373 if (unsupported_gamma(png_ptr, output_gamma, 0))
381 file_gamma = png_ptr->default_gamma;
384 file_gamma = png_reciprocal(output_gamma);
385 png_ptr->default_gamma = file_gamma;
408 png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
409 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
412 case PNG_ALPHA_ASSOCIATED:
414 png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
415 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
417 output_gamma = PNG_FP_1;
420 case PNG_ALPHA_OPTIMIZED:
422 png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
423 png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
427 case PNG_ALPHA_BROKEN:
429 png_ptr->transformations |= PNG_ENCODE_ALPHA;
430 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
434 png_error(png_ptr,
"invalid alpha mode");
438 png_ptr->screen_gamma = output_gamma;
446 memset(&png_ptr->background, 0, (
sizeof png_ptr->background));
447 png_ptr->background_gamma = file_gamma;
448 png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
449 png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
451 if ((png_ptr->transformations & PNG_COMPOSE) != 0)
453 "conflicting calls to set alpha mode and background");
455 png_ptr->transformations |= PNG_COMPOSE;
459# ifdef PNG_FLOATING_POINT_SUPPORTED
461png_set_alpha_mode(png_structrp png_ptr,
int mode,
double output_gamma)
463 png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
469#ifdef PNG_READ_QUANTIZE_SUPPORTED
485typedef png_dsort * png_dsortp;
486typedef png_dsort * * png_dsortpp;
489png_set_quantize(png_structrp png_ptr, png_colorp palette,
490 int num_palette,
int maximum_colors, png_const_uint_16p histogram,
493 png_debug(1,
"in png_set_quantize");
495 if (png_rtran_ok(png_ptr, 0) == 0)
498 png_ptr->transformations |= PNG_QUANTIZE;
500 if (full_quantize == 0)
513 png_free(png_ptr, png_ptr->quantize_index);
514 png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
515 PNG_MAX_PALETTE_LENGTH);
516 for (i = 0; i < PNG_MAX_PALETTE_LENGTH; i++)
517 png_ptr->quantize_index[i] = (png_byte)i;
520 if (num_palette > maximum_colors)
522 if (histogram != NULL)
528 png_bytep quantize_sort;
532 quantize_sort = (png_bytep)png_malloc(png_ptr,
533 (png_alloc_size_t)num_palette);
534 for (i = 0; i < num_palette; i++)
535 quantize_sort[i] = (png_byte)i;
544 for (i = num_palette - 1; i >= maximum_colors; i--)
549 for (j = 0; j < i; j++)
551 if (histogram[quantize_sort[j]]
552 < histogram[quantize_sort[j + 1]])
556 t = quantize_sort[j];
557 quantize_sort[j] = quantize_sort[j + 1];
558 quantize_sort[j + 1] = t;
568 if (full_quantize != 0)
575 for (i = 0; i < maximum_colors; i++)
577 if ((
int)quantize_sort[i] >= maximum_colors)
581 while ((
int)quantize_sort[j] >= maximum_colors);
583 palette[i] = palette[j];
594 for (i = 0; i < maximum_colors; i++)
597 if ((
int)quantize_sort[i] >= maximum_colors)
603 while ((
int)quantize_sort[j] >= maximum_colors);
605 tmp_color = palette[j];
606 palette[j] = palette[i];
607 palette[i] = tmp_color;
609 png_ptr->quantize_index[j] = (png_byte)i;
610 png_ptr->quantize_index[i] = (png_byte)j;
615 for (i = 0; i < num_palette; i++)
617 if ((
int)png_ptr->quantize_index[i] >= maximum_colors)
619 int min_d, k, min_k, d_index;
622 d_index = png_ptr->quantize_index[i];
623 min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
624 for (k = 1, min_k = 0; k < maximum_colors; k++)
628 d = PNG_COLOR_DIST(palette[d_index], palette[k]);
637 png_ptr->quantize_index[i] = (png_byte)min_k;
641 png_free(png_ptr, quantize_sort);
662 png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
663 (png_alloc_size_t)num_palette);
664 png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
665 (png_alloc_size_t)num_palette);
668 for (i = 0; i < num_palette; i++)
670 png_ptr->index_to_palette[i] = (png_byte)i;
671 png_ptr->palette_to_index[i] = (png_byte)i;
674 hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
675 (
sizeof (png_dsortp))));
677 num_new_palette = num_palette;
689 while (num_new_palette > maximum_colors)
691 for (i = 0; i < num_new_palette - 1; i++)
695 for (j = i + 1; j < num_new_palette; j++)
699 d = PNG_COLOR_DIST(palette[i], palette[j]);
704 t = (png_dsortp)png_malloc_warn(png_ptr,
705 (png_alloc_size_t)(
sizeof (png_dsort)));
711 t->left = (png_byte)i;
712 t->right = (png_byte)j;
721 for (i = 0; i <= max_d; i++)
727 for (p = hash[i]; p; p = p->next)
729 if ((
int)png_ptr->index_to_palette[p->left]
731 (
int)png_ptr->index_to_palette[p->right]
736 if (num_new_palette & 0x01)
748 palette[png_ptr->index_to_palette[j]]
749 = palette[num_new_palette];
750 if (full_quantize == 0)
754 for (k = 0; k < num_palette; k++)
756 if (png_ptr->quantize_index[k] ==
757 png_ptr->index_to_palette[j])
758 png_ptr->quantize_index[k] =
759 png_ptr->index_to_palette[next_j];
761 if ((
int)png_ptr->quantize_index[k] ==
763 png_ptr->quantize_index[k] =
764 png_ptr->index_to_palette[j];
768 png_ptr->index_to_palette[png_ptr->palette_to_index
769 [num_new_palette]] = png_ptr->index_to_palette[j];
771 png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
772 = png_ptr->palette_to_index[num_new_palette];
774 png_ptr->index_to_palette[j] =
775 (png_byte)num_new_palette;
777 png_ptr->palette_to_index[num_new_palette] =
780 if (num_new_palette <= maximum_colors)
783 if (num_new_palette <= maximum_colors)
788 for (i = 0; i < 769; i++)
792 png_dsortp p = hash[i];
796 png_free(png_ptr, p);
804 png_free(png_ptr, hash);
805 png_free(png_ptr, png_ptr->palette_to_index);
806 png_free(png_ptr, png_ptr->index_to_palette);
807 png_ptr->palette_to_index = NULL;
808 png_ptr->index_to_palette = NULL;
810 num_palette = maximum_colors;
812 if (png_ptr->palette == NULL)
814 png_ptr->palette = palette;
816 png_ptr->num_palette = (png_uint_16)num_palette;
818 if (full_quantize != 0)
822 int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
823 PNG_QUANTIZE_BLUE_BITS;
824 int num_red = (1 << PNG_QUANTIZE_RED_BITS);
825 int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
826 int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
827 size_t num_entries = ((size_t)1 << total_bits);
829 png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
830 (png_alloc_size_t)(num_entries));
832 distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries);
834 memset(distance, 0xff, num_entries);
836 for (i = 0; i < num_palette; i++)
839 int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
840 int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
841 int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
843 for (ir = 0; ir < num_red; ir++)
846 int dr = ((ir > r) ? ir - r : r - ir);
847 int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
848 PNG_QUANTIZE_GREEN_BITS));
850 for (ig = 0; ig < num_green; ig++)
853 int dg = ((ig > g) ? ig - g : g - ig);
855 int dm = ((dr > dg) ? dr : dg);
856 int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
858 for (ib = 0; ib < num_blue; ib++)
860 int d_index = index_g | ib;
862 int db = ((ib > b) ? ib - b : b - ib);
863 int dmax = ((dm > db) ? dm : db);
864 int d = dmax + dt + db;
866 if (d < (
int)distance[d_index])
868 distance[d_index] = (png_byte)d;
869 png_ptr->palette_lookup[d_index] = (png_byte)i;
876 png_free(png_ptr, distance);
881#ifdef PNG_READ_GAMMA_SUPPORTED
883png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
884 png_fixed_point file_gamma)
886 png_debug(1,
"in png_set_gamma_fixed");
888 if (png_rtran_ok(png_ptr, 0) == 0)
892 scrn_gamma = translate_gamma_flags(scrn_gamma, 1);
893 file_gamma = translate_gamma_flags(file_gamma, 0);
907 png_app_error(png_ptr,
"invalid file gamma in png_set_gamma");
909 png_app_error(png_ptr,
"invalid screen gamma in png_set_gamma");
911 if (unsupported_gamma(png_ptr, file_gamma, 1) ||
912 unsupported_gamma(png_ptr, scrn_gamma, 1))
919 png_ptr->file_gamma = file_gamma;
920 png_ptr->screen_gamma = scrn_gamma;
923# ifdef PNG_FLOATING_POINT_SUPPORTED
925png_set_gamma(png_structrp png_ptr,
double scrn_gamma,
double file_gamma)
927 png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
928 convert_gamma_value(png_ptr, file_gamma));
933#ifdef PNG_READ_EXPAND_SUPPORTED
939png_set_expand(png_structrp png_ptr)
941 png_debug(1,
"in png_set_expand");
943 if (png_rtran_ok(png_ptr, 0) == 0)
946 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
969png_set_palette_to_rgb(png_structrp png_ptr)
971 png_debug(1,
"in png_set_palette_to_rgb");
973 if (png_rtran_ok(png_ptr, 0) == 0)
976 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
981png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
983 png_debug(1,
"in png_set_expand_gray_1_2_4_to_8");
985 if (png_rtran_ok(png_ptr, 0) == 0)
988 png_ptr->transformations |= PNG_EXPAND;
993png_set_tRNS_to_alpha(png_structrp png_ptr)
995 png_debug(1,
"in png_set_tRNS_to_alpha");
997 if (png_rtran_ok(png_ptr, 0) == 0)
1000 png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
1004#ifdef PNG_READ_EXPAND_16_SUPPORTED
1009png_set_expand_16(png_structrp png_ptr)
1011 png_debug(1,
"in png_set_expand_16");
1013 if (png_rtran_ok(png_ptr, 0) == 0)
1016 png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
1020#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1022png_set_gray_to_rgb(png_structrp png_ptr)
1024 png_debug(1,
"in png_set_gray_to_rgb");
1026 if (png_rtran_ok(png_ptr, 0) == 0)
1030 png_set_expand_gray_1_2_4_to_8(png_ptr);
1031 png_ptr->transformations |= PNG_GRAY_TO_RGB;
1035#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1037png_set_rgb_to_gray_fixed(png_structrp png_ptr,
int error_action,
1038 png_fixed_point red, png_fixed_point green)
1040 png_debug(1,
"in png_set_rgb_to_gray_fixed");
1044 if (png_rtran_ok(png_ptr, 1) == 0)
1047 switch (error_action)
1049 case PNG_ERROR_ACTION_NONE:
1050 png_ptr->transformations |= PNG_RGB_TO_GRAY;
1053 case PNG_ERROR_ACTION_WARN:
1054 png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
1057 case PNG_ERROR_ACTION_ERROR:
1058 png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
1062 png_error(png_ptr,
"invalid error action to rgb_to_gray");
1065 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1066#ifdef PNG_READ_EXPAND_SUPPORTED
1067 png_ptr->transformations |= PNG_EXPAND;
1074 "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
1080 if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
1082 png_uint_16 red_int, green_int;
1089 red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
1090 green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
1092 png_ptr->rgb_to_gray_red_coeff = red_int;
1093 png_ptr->rgb_to_gray_green_coeff = green_int;
1094 png_ptr->rgb_to_gray_coefficients_set = 1;
1097 else if (red >= 0 && green >= 0)
1098 png_app_warning(png_ptr,
1099 "ignoring out of range rgb_to_gray coefficients");
1103#ifdef PNG_FLOATING_POINT_SUPPORTED
1109png_set_rgb_to_gray(png_structrp png_ptr,
int error_action,
double red,
1112 png_set_rgb_to_gray_fixed(png_ptr, error_action,
1113 png_fixed(png_ptr, red,
"rgb to gray red coefficient"),
1114 png_fixed(png_ptr, green,
"rgb to gray green coefficient"));
1120#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
1121 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1123png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
1124 read_user_transform_fn)
1126 png_debug(1,
"in png_set_read_user_transform_fn");
1128#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1129 png_ptr->transformations |= PNG_USER_TRANSFORM;
1130 png_ptr->read_user_transform_fn = read_user_transform_fn;
1135#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1136#ifdef PNG_READ_GAMMA_SUPPORTED
1142png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
1151 png_fixed_point gtest;
1152 return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) ||
1153 png_gamma_significant(gtest);
1167png_init_palette_transformations(png_structrp png_ptr)
1177 int input_has_alpha = 0;
1178 int input_has_transparency = 0;
1180 if (png_ptr->num_trans > 0)
1185 for (i=0; i<png_ptr->num_trans; ++i)
1187 if (png_ptr->trans_alpha[i] == 255)
1189 else if (png_ptr->trans_alpha[i] == 0)
1190 input_has_transparency = 1;
1193 input_has_transparency = 1;
1194 input_has_alpha = 1;
1201 if (input_has_alpha == 0)
1207 png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1208 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1210 if (input_has_transparency == 0)
1211 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1214#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1223 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
1224 (png_ptr->transformations & PNG_EXPAND) != 0)
1227 png_ptr->background.red =
1228 png_ptr->palette[png_ptr->background.index].red;
1229 png_ptr->background.green =
1230 png_ptr->palette[png_ptr->background.index].green;
1231 png_ptr->background.blue =
1232 png_ptr->palette[png_ptr->background.index].blue;
1234#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1235 if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
1237 if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1242 int i, istop = png_ptr->num_trans;
1244 for (i = 0; i < istop; i++)
1245 png_ptr->trans_alpha[i] =
1246 (png_byte)(255 - png_ptr->trans_alpha[i]);
1256png_init_rgb_transformations(png_structrp png_ptr)
1262 int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1263 int input_has_transparency = png_ptr->num_trans > 0;
1266 if (input_has_alpha == 0)
1272# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1273 png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1274 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1277 if (input_has_transparency == 0)
1278 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1281#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1290 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
1291 (png_ptr->transformations & PNG_EXPAND) != 0 &&
1292 (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
1297 int gray = png_ptr->background.gray;
1298 int trans_gray = png_ptr->trans_color.gray;
1300 switch (png_ptr->bit_depth)
1327 png_ptr->background.red = png_ptr->background.green =
1328 png_ptr->background.blue = (png_uint_16)gray;
1330 if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1332 png_ptr->trans_color.red = png_ptr->trans_color.green =
1333 png_ptr->trans_color.blue = (png_uint_16)trans_gray;
1340#ifdef PNG_READ_GAMMA_SUPPORTED
1342png_resolve_file_gamma(png_const_structrp png_ptr)
1344 png_fixed_point file_gamma;
1355 file_gamma = png_ptr->file_gamma;
1356 if (file_gamma != 0)
1359 file_gamma = png_ptr->chunk_gamma;
1360 if (file_gamma != 0)
1363 file_gamma = png_ptr->default_gamma;
1364 if (file_gamma != 0)
1371 if (png_ptr->screen_gamma != 0)
1372 file_gamma = png_reciprocal(png_ptr->screen_gamma);
1378png_init_gamma_values(png_structrp png_ptr)
1383 int gamma_correction = 0;
1384 png_fixed_point file_gamma, screen_gamma;
1389 file_gamma = png_resolve_file_gamma(png_ptr);
1390 screen_gamma = png_ptr->screen_gamma;
1394 if (screen_gamma > 0)
1395 gamma_correction = png_gamma_threshold(file_gamma, screen_gamma);
1401 screen_gamma = png_reciprocal(file_gamma);
1405 file_gamma = screen_gamma = PNG_FP_1;
1407 png_ptr->file_gamma = file_gamma;
1408 png_ptr->screen_gamma = screen_gamma;
1409 return gamma_correction;
1415png_init_read_transformations(png_structrp png_ptr)
1417 png_debug(1,
"in png_init_read_transformations");
1427#ifdef PNG_READ_GAMMA_SUPPORTED
1444 if (png_init_gamma_values(png_ptr) != 0)
1445 png_ptr->transformations |= PNG_GAMMA;
1448 png_ptr->transformations &= ~PNG_GAMMA;
1480#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1481 if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
1482 (png_ptr->transformations & PNG_COMPOSE) == 0)
1489 png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
1491 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1500 png_ptr->num_trans = 0;
1504#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1508 if (png_gamma_significant(png_ptr->screen_gamma) == 0)
1510 png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1511 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1515#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1519 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
1520 png_set_rgb_coefficients(png_ptr);
1523#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1524#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1540 if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
1545 if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
1546 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1549 else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1556 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
1558 if (png_ptr->background.red == png_ptr->background.green &&
1559 png_ptr->background.red == png_ptr->background.blue)
1561 png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1562 png_ptr->background.gray = png_ptr->background.red;
1580 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1581 png_init_palette_transformations(png_ptr);
1584 png_init_rgb_transformations(png_ptr);
1586#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1587 defined(PNG_READ_EXPAND_16_SUPPORTED)
1588 if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
1589 (png_ptr->transformations & PNG_COMPOSE) != 0 &&
1590 (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
1591 png_ptr->bit_depth != 16)
1603# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
1604 CHOP(png_ptr->background.red);
1605 CHOP(png_ptr->background.green);
1606 CHOP(png_ptr->background.blue);
1607 CHOP(png_ptr->background.gray);
1612#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1613 (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
1614 defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
1615 if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
1616 (png_ptr->transformations & PNG_COMPOSE) != 0 &&
1617 (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
1618 png_ptr->bit_depth == 16)
1626 png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
1627 png_ptr->background.green =
1628 (png_uint_16)(png_ptr->background.green * 257);
1629 png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
1630 png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
1642#ifdef PNG_READ_GAMMA_SUPPORTED
1643# ifdef PNG_READ_BACKGROUND_SUPPORTED
1645 png_ptr->background_1 = png_ptr->background;
1661 if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
1662 ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
1663 (png_gamma_significant(png_ptr->file_gamma) != 0 ||
1664 png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
1665 ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
1666 (png_gamma_significant(png_ptr->file_gamma) != 0 ||
1667 png_gamma_significant(png_ptr->screen_gamma) != 0
1668# ifdef PNG_READ_BACKGROUND_SUPPORTED
1669 || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
1670 png_gamma_significant(png_ptr->background_gamma) != 0)
1672 )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
1673 png_gamma_significant(png_ptr->screen_gamma) != 0))
1675 png_build_gamma_table(png_ptr, png_ptr->bit_depth);
1677#ifdef PNG_READ_BACKGROUND_SUPPORTED
1678 if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1686 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
1687 png_warning(png_ptr,
1688 "libpng does not support gamma+background+rgb_to_gray");
1690 if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
1695 png_color back, back_1;
1696 png_colorp palette = png_ptr->palette;
1697 int num_palette = png_ptr->num_palette;
1699 if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
1702 back.red = png_ptr->gamma_table[png_ptr->background.red];
1703 back.green = png_ptr->gamma_table[png_ptr->background.green];
1704 back.blue = png_ptr->gamma_table[png_ptr->background.blue];
1706 back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
1707 back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
1708 back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
1712 png_fixed_point g, gs;
1714 switch (png_ptr->background_gamma_type)
1716 case PNG_BACKGROUND_GAMMA_SCREEN:
1717 g = (png_ptr->screen_gamma);
1721 case PNG_BACKGROUND_GAMMA_FILE:
1722 g = png_reciprocal(png_ptr->file_gamma);
1723 gs = png_reciprocal2(png_ptr->file_gamma,
1724 png_ptr->screen_gamma);
1727 case PNG_BACKGROUND_GAMMA_UNIQUE:
1728 g = png_reciprocal(png_ptr->background_gamma);
1729 gs = png_reciprocal2(png_ptr->background_gamma,
1730 png_ptr->screen_gamma);
1738 if (png_gamma_significant(gs) != 0)
1740 back.red = png_gamma_8bit_correct(png_ptr->background.red,
1742 back.green = png_gamma_8bit_correct(png_ptr->background.green,
1744 back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1750 back.red = (png_byte)png_ptr->background.red;
1751 back.green = (png_byte)png_ptr->background.green;
1752 back.blue = (png_byte)png_ptr->background.blue;
1755 if (png_gamma_significant(g) != 0)
1757 back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
1759 back_1.green = png_gamma_8bit_correct(
1760 png_ptr->background.green, g);
1761 back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1767 back_1.red = (png_byte)png_ptr->background.red;
1768 back_1.green = (png_byte)png_ptr->background.green;
1769 back_1.blue = (png_byte)png_ptr->background.blue;
1773 for (i = 0; i < num_palette; i++)
1775 if (i < (
int)png_ptr->num_trans &&
1776 png_ptr->trans_alpha[i] != 0xff)
1778 if (png_ptr->trans_alpha[i] == 0)
1784 if ((png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0)
1789 png_uint_32 component;
1791 component = png_ptr->gamma_to_1[palette[i].red];
1793 (component * png_ptr->trans_alpha[i] + 128) / 255;
1794 palette[i].red = png_ptr->gamma_from_1[component];
1796 component = png_ptr->gamma_to_1[palette[i].green];
1798 (component * png_ptr->trans_alpha[i] + 128) / 255;
1799 palette[i].green = png_ptr->gamma_from_1[component];
1801 component = png_ptr->gamma_to_1[palette[i].blue];
1803 (component * png_ptr->trans_alpha[i] + 128) / 255;
1804 palette[i].blue = png_ptr->gamma_from_1[component];
1814 v = png_ptr->gamma_to_1[palette[i].red];
1816 png_ptr->trans_alpha[i], back_1.red);
1817 palette[i].red = png_ptr->gamma_from_1[w];
1819 v = png_ptr->gamma_to_1[palette[i].green];
1821 png_ptr->trans_alpha[i], back_1.green);
1822 palette[i].green = png_ptr->gamma_from_1[w];
1824 v = png_ptr->gamma_to_1[palette[i].blue];
1826 png_ptr->trans_alpha[i], back_1.blue);
1827 palette[i].blue = png_ptr->gamma_from_1[w];
1833 palette[i].red = png_ptr->gamma_table[palette[i].red];
1834 palette[i].green = png_ptr->gamma_table[palette[i].green];
1835 palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1845 png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
1846 png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1853 png_fixed_point g = PNG_FP_1;
1854 png_fixed_point gs = PNG_FP_1;
1856 switch (png_ptr->background_gamma_type)
1858 case PNG_BACKGROUND_GAMMA_SCREEN:
1859 g = png_ptr->screen_gamma;
1863 case PNG_BACKGROUND_GAMMA_FILE:
1864 g = png_reciprocal(png_ptr->file_gamma);
1865 gs = png_reciprocal2(png_ptr->file_gamma,
1866 png_ptr->screen_gamma);
1869 case PNG_BACKGROUND_GAMMA_UNIQUE:
1870 g = png_reciprocal(png_ptr->background_gamma);
1871 gs = png_reciprocal2(png_ptr->background_gamma,
1872 png_ptr->screen_gamma);
1876 png_error(png_ptr,
"invalid background gamma type");
1879 g_sig = png_gamma_significant(g);
1880 gs_sig = png_gamma_significant(gs);
1883 png_ptr->background_1.gray = png_gamma_correct(png_ptr,
1884 png_ptr->background.gray, g);
1887 png_ptr->background.gray = png_gamma_correct(png_ptr,
1888 png_ptr->background.gray, gs);
1890 if ((png_ptr->background.red != png_ptr->background.green) ||
1891 (png_ptr->background.red != png_ptr->background.blue) ||
1892 (png_ptr->background.red != png_ptr->background.gray))
1897 png_ptr->background_1.red = png_gamma_correct(png_ptr,
1898 png_ptr->background.red, g);
1900 png_ptr->background_1.green = png_gamma_correct(png_ptr,
1901 png_ptr->background.green, g);
1903 png_ptr->background_1.blue = png_gamma_correct(png_ptr,
1904 png_ptr->background.blue, g);
1909 png_ptr->background.red = png_gamma_correct(png_ptr,
1910 png_ptr->background.red, gs);
1912 png_ptr->background.green = png_gamma_correct(png_ptr,
1913 png_ptr->background.green, gs);
1915 png_ptr->background.blue = png_gamma_correct(png_ptr,
1916 png_ptr->background.blue, gs);
1923 png_ptr->background_1.red = png_ptr->background_1.green
1924 = png_ptr->background_1.blue = png_ptr->background_1.gray;
1926 png_ptr->background.red = png_ptr->background.green
1927 = png_ptr->background.blue = png_ptr->background.gray;
1931 png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
1938 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
1939#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1941 && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
1942 (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
1946 png_colorp palette = png_ptr->palette;
1947 int num_palette = png_ptr->num_palette;
1953 for (i = 0; i < num_palette; i++)
1955 palette[i].red = png_ptr->gamma_table[palette[i].red];
1956 palette[i].green = png_ptr->gamma_table[palette[i].green];
1957 palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1961 png_ptr->transformations &= ~PNG_GAMMA;
1964#ifdef PNG_READ_BACKGROUND_SUPPORTED
1969#ifdef PNG_READ_BACKGROUND_SUPPORTED
1971 if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
1972 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1975 int istop = (int)png_ptr->num_trans;
1977 png_colorp palette = png_ptr->palette;
1979 back.red = (png_byte)png_ptr->background.red;
1980 back.green = (png_byte)png_ptr->background.green;
1981 back.blue = (png_byte)png_ptr->background.blue;
1983 for (i = 0; i < istop; i++)
1985 if (png_ptr->trans_alpha[i] == 0)
1990 else if (png_ptr->trans_alpha[i] != 0xff)
1993 png_composite(palette[i].red, palette[i].red,
1994 png_ptr->trans_alpha[i], back.red);
1996 png_composite(palette[i].green, palette[i].green,
1997 png_ptr->trans_alpha[i], back.green);
1999 png_composite(palette[i].blue, palette[i].blue,
2000 png_ptr->trans_alpha[i], back.blue);
2004 png_ptr->transformations &= ~PNG_COMPOSE;
2008#ifdef PNG_READ_SHIFT_SUPPORTED
2009 if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
2010 (png_ptr->transformations & PNG_EXPAND) == 0 &&
2011 (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
2014 int istop = png_ptr->num_palette;
2015 int shift = 8 - png_ptr->sig_bit.red;
2017 png_ptr->transformations &= ~PNG_SHIFT;
2023 if (shift > 0 && shift < 8)
2024 for (i=0; i<istop; ++i)
2026 int component = png_ptr->palette[i].red;
2028 component >>= shift;
2029 png_ptr->palette[i].red = (png_byte)component;
2032 shift = 8 - png_ptr->sig_bit.green;
2033 if (shift > 0 && shift < 8)
2034 for (i=0; i<istop; ++i)
2036 int component = png_ptr->palette[i].green;
2038 component >>= shift;
2039 png_ptr->palette[i].green = (png_byte)component;
2042 shift = 8 - png_ptr->sig_bit.blue;
2043 if (shift > 0 && shift < 8)
2044 for (i=0; i<istop; ++i)
2046 int component = png_ptr->palette[i].blue;
2048 component >>= shift;
2049 png_ptr->palette[i].blue = (png_byte)component;
2060png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
2062 png_debug(1,
"in png_read_transform_info");
2064#ifdef PNG_READ_EXPAND_SUPPORTED
2065 if ((png_ptr->transformations & PNG_EXPAND) != 0)
2067 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2073 if (png_ptr->num_trans > 0)
2074 info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
2077 info_ptr->color_type = PNG_COLOR_TYPE_RGB;
2079 info_ptr->bit_depth = 8;
2080 info_ptr->num_trans = 0;
2082 if (png_ptr->palette == NULL)
2083 png_error (png_ptr,
"Palette is NULL in indexed image");
2087 if (png_ptr->num_trans != 0)
2089 if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
2090 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
2092 if (info_ptr->bit_depth < 8)
2093 info_ptr->bit_depth = 8;
2095 info_ptr->num_trans = 0;
2100#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
2101 defined(PNG_READ_ALPHA_MODE_SUPPORTED)
2105 if ((png_ptr->transformations & PNG_COMPOSE) != 0)
2106 info_ptr->background = png_ptr->background;
2109#ifdef PNG_READ_GAMMA_SUPPORTED
2119 info_ptr->gamma = png_ptr->file_gamma;
2122 if (info_ptr->bit_depth == 16)
2124# ifdef PNG_READ_16BIT_SUPPORTED
2125# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2126 if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
2127 info_ptr->bit_depth = 8;
2130# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2131 if ((png_ptr->transformations & PNG_16_TO_8) != 0)
2132 info_ptr->bit_depth = 8;
2140# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2145 png_ptr->transformations |= PNG_16_TO_8;
2146 info_ptr->bit_depth = 8;
2149# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2150 png_ptr->transformations |= PNG_SCALE_16_TO_8;
2151 info_ptr->bit_depth = 8;
2154 CONFIGURATION ERROR: you must enable at least one 16 to 8 method
2160#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2161 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
2162 info_ptr->color_type = (png_byte)(info_ptr->color_type |
2163 PNG_COLOR_MASK_COLOR);
2166#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2167 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
2168 info_ptr->color_type = (png_byte)(info_ptr->color_type &
2169 ~PNG_COLOR_MASK_COLOR);
2172#ifdef PNG_READ_QUANTIZE_SUPPORTED
2173 if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
2175 if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
2176 (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
2177 png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
2179 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
2184#ifdef PNG_READ_EXPAND_16_SUPPORTED
2185 if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
2186 info_ptr->bit_depth == 8 &&
2187 info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
2189 info_ptr->bit_depth = 16;
2193#ifdef PNG_READ_PACK_SUPPORTED
2194 if ((png_ptr->transformations & PNG_PACK) != 0 &&
2195 (info_ptr->bit_depth < 8))
2196 info_ptr->bit_depth = 8;
2199 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2200 info_ptr->channels = 1;
2202 else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
2203 info_ptr->channels = 3;
2206 info_ptr->channels = 1;
2208#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
2209 if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
2211 info_ptr->color_type = (png_byte)(info_ptr->color_type &
2212 ~PNG_COLOR_MASK_ALPHA);
2213 info_ptr->num_trans = 0;
2217 if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
2218 info_ptr->channels++;
2220#ifdef PNG_READ_FILLER_SUPPORTED
2222 if ((png_ptr->transformations & PNG_FILLER) != 0 &&
2223 (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
2224 info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
2226 info_ptr->channels++;
2228 if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
2229 info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
2233#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
2234defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
2235 if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
2237 if (png_ptr->user_transform_depth != 0)
2238 info_ptr->bit_depth = png_ptr->user_transform_depth;
2240 if (png_ptr->user_transform_channels != 0)
2241 info_ptr->channels = png_ptr->user_transform_channels;
2245 info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
2246 info_ptr->bit_depth);
2248 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
2256 png_ptr->info_rowbytes = info_ptr->rowbytes;
2258#ifndef PNG_READ_EXPAND_SUPPORTED
2259 if (png_ptr != NULL)
2264#ifdef PNG_READ_PACK_SUPPORTED
2272png_do_unpack(png_row_infop row_info, png_bytep row)
2274 png_debug(1,
"in png_do_unpack");
2276 if (row_info->bit_depth < 8)
2279 png_uint_32 row_width=row_info->width;
2281 switch (row_info->bit_depth)
2285 png_bytep sp = row + (size_t)((row_width - 1) >> 3);
2286 png_bytep dp = row + (size_t)row_width - 1;
2287 png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
2288 for (i = 0; i < row_width; i++)
2290 *dp = (png_byte)((*sp >> shift) & 0x01);
2309 png_bytep sp = row + (size_t)((row_width - 1) >> 2);
2310 png_bytep dp = row + (size_t)row_width - 1;
2311 png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
2312 for (i = 0; i < row_width; i++)
2314 *dp = (png_byte)((*sp >> shift) & 0x03);
2332 png_bytep sp = row + (size_t)((row_width - 1) >> 1);
2333 png_bytep dp = row + (size_t)row_width - 1;
2334 png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
2335 for (i = 0; i < row_width; i++)
2337 *dp = (png_byte)((*sp >> shift) & 0x0f);
2356 row_info->bit_depth = 8;
2357 row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2358 row_info->rowbytes = row_width * row_info->channels;
2363#ifdef PNG_READ_SHIFT_SUPPORTED
2370png_do_unshift(png_row_infop row_info, png_bytep row,
2371 png_const_color_8p sig_bits)
2375 png_debug(1,
"in png_do_unshift");
2378 color_type = row_info->color_type;
2380 if (color_type != PNG_COLOR_TYPE_PALETTE)
2384 int bit_depth = row_info->bit_depth;
2386 if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
2388 shift[channels++] = bit_depth - sig_bits->red;
2389 shift[channels++] = bit_depth - sig_bits->green;
2390 shift[channels++] = bit_depth - sig_bits->blue;
2395 shift[channels++] = bit_depth - sig_bits->gray;
2398 if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
2400 shift[channels++] = bit_depth - sig_bits->alpha;
2406 for (c = have_shift = 0; c < channels; ++c)
2411 if (shift[c] <= 0 || shift[c] >= bit_depth)
2418 if (have_shift == 0)
2434 png_bytep bp_end = bp + row_info->rowbytes;
2438 int b = (*bp >> 1) & 0x55;
2439 *bp++ = (png_byte)b;
2449 png_bytep bp_end = bp + row_info->rowbytes;
2450 int gray_shift = shift[0];
2451 int mask = 0xf >> gray_shift;
2457 int b = (*bp >> gray_shift) & mask;
2458 *bp++ = (png_byte)b;
2467 png_bytep bp_end = bp + row_info->rowbytes;
2472 int b = *bp >> shift[channel];
2473 if (++channel >= channels)
2475 *bp++ = (png_byte)b;
2480#ifdef PNG_READ_16BIT_SUPPORTED
2485 png_bytep bp_end = bp + row_info->rowbytes;
2490 int value = (bp[0] << 8) + bp[1];
2492 value >>= shift[channel];
2493 if (++channel >= channels)
2495 *bp++ = (png_byte)(value >> 8);
2496 *bp++ = (png_byte)value;
2506#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2509png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
2511 png_debug(1,
"in png_do_scale_16_to_8");
2513 if (row_info->bit_depth == 16)
2517 png_bytep ep = sp + row_info->rowbytes;
2553 png_int_32 tmp = *sp++;
2554 tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
2555 *dp++ = (png_byte)tmp;
2558 row_info->bit_depth = 8;
2559 row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2560 row_info->rowbytes = row_info->width * row_info->channels;
2565#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2570png_do_chop(png_row_infop row_info, png_bytep row)
2572 png_debug(1,
"in png_do_chop");
2574 if (row_info->bit_depth == 16)
2578 png_bytep ep = sp + row_info->rowbytes;
2586 row_info->bit_depth = 8;
2587 row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2588 row_info->rowbytes = row_info->width * row_info->channels;
2593#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
2595png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
2597 png_uint_32 row_width = row_info->width;
2599 png_debug(1,
"in png_do_read_swap_alpha");
2601 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2604 if (row_info->bit_depth == 8)
2606 png_bytep sp = row + row_info->rowbytes;
2611 for (i = 0; i < row_width; i++)
2621#ifdef PNG_READ_16BIT_SUPPORTED
2625 png_bytep sp = row + row_info->rowbytes;
2630 for (i = 0; i < row_width; i++)
2647 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2650 if (row_info->bit_depth == 8)
2652 png_bytep sp = row + row_info->rowbytes;
2657 for (i = 0; i < row_width; i++)
2665#ifdef PNG_READ_16BIT_SUPPORTED
2669 png_bytep sp = row + row_info->rowbytes;
2674 for (i = 0; i < row_width; i++)
2689#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
2691png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
2693 png_uint_32 row_width;
2694 png_debug(1,
"in png_do_read_invert_alpha");
2696 row_width = row_info->width;
2697 if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2699 if (row_info->bit_depth == 8)
2702 png_bytep sp = row + row_info->rowbytes;
2706 for (i = 0; i < row_width; i++)
2708 *(--dp) = (png_byte)(255 - *(--sp));
2721#ifdef PNG_READ_16BIT_SUPPORTED
2725 png_bytep sp = row + row_info->rowbytes;
2729 for (i = 0; i < row_width; i++)
2731 *(--dp) = (png_byte)(255 - *(--sp));
2732 *(--dp) = (png_byte)(255 - *(--sp));
2749 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2751 if (row_info->bit_depth == 8)
2754 png_bytep sp = row + row_info->rowbytes;
2758 for (i = 0; i < row_width; i++)
2760 *(--dp) = (png_byte)(255 - *(--sp));
2765#ifdef PNG_READ_16BIT_SUPPORTED
2769 png_bytep sp = row + row_info->rowbytes;
2773 for (i = 0; i < row_width; i++)
2775 *(--dp) = (png_byte)(255 - *(--sp));
2776 *(--dp) = (png_byte)(255 - *(--sp));
2790#ifdef PNG_READ_FILLER_SUPPORTED
2793png_do_read_filler(png_row_infop row_info, png_bytep row,
2794 png_uint_32 filler, png_uint_32 flags)
2797 png_uint_32 row_width = row_info->width;
2799#ifdef PNG_READ_16BIT_SUPPORTED
2800 png_byte hi_filler = (png_byte)(filler>>8);
2802 png_byte lo_filler = (png_byte)filler;
2804 png_debug(1,
"in png_do_read_filler");
2807 row_info->color_type == PNG_COLOR_TYPE_GRAY)
2809 if (row_info->bit_depth == 8)
2811 if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2814 png_bytep sp = row + (size_t)row_width;
2815 png_bytep dp = sp + (size_t)row_width;
2816 for (i = 1; i < row_width; i++)
2818 *(--dp) = lo_filler;
2821 *(--dp) = lo_filler;
2822 row_info->channels = 2;
2823 row_info->pixel_depth = 16;
2824 row_info->rowbytes = row_width * 2;
2830 png_bytep sp = row + (size_t)row_width;
2831 png_bytep dp = sp + (size_t)row_width;
2832 for (i = 0; i < row_width; i++)
2835 *(--dp) = lo_filler;
2837 row_info->channels = 2;
2838 row_info->pixel_depth = 16;
2839 row_info->rowbytes = row_width * 2;
2843#ifdef PNG_READ_16BIT_SUPPORTED
2844 else if (row_info->bit_depth == 16)
2846 if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2849 png_bytep sp = row + (size_t)row_width * 2;
2850 png_bytep dp = sp + (size_t)row_width * 2;
2851 for (i = 1; i < row_width; i++)
2853 *(--dp) = lo_filler;
2854 *(--dp) = hi_filler;
2858 *(--dp) = lo_filler;
2859 *(--dp) = hi_filler;
2860 row_info->channels = 2;
2861 row_info->pixel_depth = 32;
2862 row_info->rowbytes = row_width * 4;
2868 png_bytep sp = row + (size_t)row_width * 2;
2869 png_bytep dp = sp + (size_t)row_width * 2;
2870 for (i = 0; i < row_width; i++)
2874 *(--dp) = lo_filler;
2875 *(--dp) = hi_filler;
2877 row_info->channels = 2;
2878 row_info->pixel_depth = 32;
2879 row_info->rowbytes = row_width * 4;
2884 else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2886 if (row_info->bit_depth == 8)
2888 if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2891 png_bytep sp = row + (size_t)row_width * 3;
2892 png_bytep dp = sp + (size_t)row_width;
2893 for (i = 1; i < row_width; i++)
2895 *(--dp) = lo_filler;
2900 *(--dp) = lo_filler;
2901 row_info->channels = 4;
2902 row_info->pixel_depth = 32;
2903 row_info->rowbytes = row_width * 4;
2909 png_bytep sp = row + (size_t)row_width * 3;
2910 png_bytep dp = sp + (size_t)row_width;
2911 for (i = 0; i < row_width; i++)
2916 *(--dp) = lo_filler;
2918 row_info->channels = 4;
2919 row_info->pixel_depth = 32;
2920 row_info->rowbytes = row_width * 4;
2924#ifdef PNG_READ_16BIT_SUPPORTED
2925 else if (row_info->bit_depth == 16)
2927 if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2930 png_bytep sp = row + (size_t)row_width * 6;
2931 png_bytep dp = sp + (size_t)row_width * 2;
2932 for (i = 1; i < row_width; i++)
2934 *(--dp) = lo_filler;
2935 *(--dp) = hi_filler;
2943 *(--dp) = lo_filler;
2944 *(--dp) = hi_filler;
2945 row_info->channels = 4;
2946 row_info->pixel_depth = 64;
2947 row_info->rowbytes = row_width * 8;
2953 png_bytep sp = row + (size_t)row_width * 6;
2954 png_bytep dp = sp + (size_t)row_width * 2;
2955 for (i = 0; i < row_width; i++)
2963 *(--dp) = lo_filler;
2964 *(--dp) = hi_filler;
2967 row_info->channels = 4;
2968 row_info->pixel_depth = 64;
2969 row_info->rowbytes = row_width * 8;
2977#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2980png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
2983 png_uint_32 row_width = row_info->width;
2985 png_debug(1,
"in png_do_gray_to_rgb");
2987 if (row_info->bit_depth >= 8 &&
2988 (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
2990 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2992 if (row_info->bit_depth == 8)
2995 png_bytep sp = row + (size_t)row_width - 1;
2996 png_bytep dp = sp + (size_t)row_width * 2;
2997 for (i = 0; i < row_width; i++)
3008 png_bytep sp = row + (size_t)row_width * 2 - 1;
3009 png_bytep dp = sp + (size_t)row_width * 4;
3010 for (i = 0; i < row_width; i++)
3013 *(dp--) = *(sp - 1);
3015 *(dp--) = *(sp - 1);
3022 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3024 if (row_info->bit_depth == 8)
3027 png_bytep sp = row + (size_t)row_width * 2 - 1;
3028 png_bytep dp = sp + (size_t)row_width * 2;
3029 for (i = 0; i < row_width; i++)
3041 png_bytep sp = row + (size_t)row_width * 4 - 1;
3042 png_bytep dp = sp + (size_t)row_width * 4;
3043 for (i = 0; i < row_width; i++)
3048 *(dp--) = *(sp - 1);
3050 *(dp--) = *(sp - 1);
3056 row_info->channels = (png_byte)(row_info->channels + 2);
3057 row_info->color_type |= PNG_COLOR_MASK_COLOR;
3058 row_info->pixel_depth = (png_byte)(row_info->channels *
3059 row_info->bit_depth);
3060 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3065#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
3119png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
3123 png_debug(1,
"in png_do_rgb_to_gray");
3125 if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
3126 (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
3128 png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
3129 png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
3130 png_uint_32 bc = 32768 - rc - gc;
3131 png_uint_32 row_width = row_info->width;
3132 int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
3134 if (row_info->bit_depth == 8)
3136#ifdef PNG_READ_GAMMA_SUPPORTED
3142 if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3148 for (i = 0; i < row_width; i++)
3150 png_byte red = *(sp++);
3151 png_byte green = *(sp++);
3152 png_byte blue = *(sp++);
3154 if (red != green || red != blue)
3156 red = png_ptr->gamma_to_1[red];
3157 green = png_ptr->gamma_to_1[green];
3158 blue = png_ptr->gamma_to_1[blue];
3161 *(dp++) = png_ptr->gamma_from_1[
3162 (rc*red + gc*green + bc*blue + 16384)>>15];
3170 if (png_ptr->gamma_table != NULL)
3171 red = png_ptr->gamma_table[red];
3176 if (have_alpha != 0)
3187 for (i = 0; i < row_width; i++)
3189 png_byte red = *(sp++);
3190 png_byte green = *(sp++);
3191 png_byte blue = *(sp++);
3193 if (red != green || red != blue)
3199 *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
3205 if (have_alpha != 0)
3213#ifdef PNG_READ_GAMMA_SUPPORTED
3214 if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
3220 for (i = 0; i < row_width; i++)
3222 png_uint_16 red, green, blue, w;
3225 hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
3226 hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3227 hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
3229 if (red == green && red == blue)
3231 if (png_ptr->gamma_16_table != NULL)
3232 w = png_ptr->gamma_16_table[(red & 0xff)
3233 >> png_ptr->gamma_shift][red >> 8];
3241 png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff)
3242 >> png_ptr->gamma_shift][red>>8];
3243 png_uint_16 green_1 =
3244 png_ptr->gamma_16_to_1[(green & 0xff) >>
3245 png_ptr->gamma_shift][green>>8];
3246 png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff)
3247 >> png_ptr->gamma_shift][blue>>8];
3248 png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
3249 + bc*blue_1 + 16384)>>15);
3250 w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
3251 png_ptr->gamma_shift][gray16 >> 8];
3255 *(dp++) = (png_byte)((w>>8) & 0xff);
3256 *(dp++) = (png_byte)(w & 0xff);
3258 if (have_alpha != 0)
3272 for (i = 0; i < row_width; i++)
3274 png_uint_16 red, green, blue, gray16;
3277 hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
3278 hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3279 hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
3281 if (red != green || red != blue)
3288 gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
3290 *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
3291 *(dp++) = (png_byte)(gray16 & 0xff);
3293 if (have_alpha != 0)
3302 row_info->channels = (png_byte)(row_info->channels - 2);
3303 row_info->color_type = (png_byte)(row_info->color_type &
3304 ~PNG_COLOR_MASK_COLOR);
3305 row_info->pixel_depth = (png_byte)(row_info->channels *
3306 row_info->bit_depth);
3307 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3313#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
3314 defined(PNG_READ_ALPHA_MODE_SUPPORTED)
3320png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3322#ifdef PNG_READ_GAMMA_SUPPORTED
3323 png_const_bytep gamma_table = png_ptr->gamma_table;
3324 png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
3325 png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
3326 png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
3327 png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
3328 png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
3329 int gamma_shift = png_ptr->gamma_shift;
3330 int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
3335 png_uint_32 row_width = row_info->width;
3338 png_debug(1,
"in png_do_compose");
3340 switch (row_info->color_type)
3342 case PNG_COLOR_TYPE_GRAY:
3344 switch (row_info->bit_depth)
3350 for (i = 0; i < row_width; i++)
3352 if ((png_uint_16)((*sp >> shift) & 0x01)
3353 == png_ptr->trans_color.gray)
3355 unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
3357 (
unsigned int)(png_ptr->background.gray << shift);
3358 *sp = (png_byte)(tmp & 0xff);
3375#ifdef PNG_READ_GAMMA_SUPPORTED
3376 if (gamma_table != NULL)
3380 for (i = 0; i < row_width; i++)
3382 if ((png_uint_16)((*sp >> shift) & 0x03)
3383 == png_ptr->trans_color.gray)
3385 unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3387 (
unsigned int)png_ptr->background.gray << shift;
3388 *sp = (png_byte)(tmp & 0xff);
3393 unsigned int p = (*sp >> shift) & 0x03;
3394 unsigned int g = (gamma_table [p | (p << 2) |
3395 (p << 4) | (p << 6)] >> 6) & 0x03;
3396 unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3397 tmp |= (
unsigned int)(g << shift);
3398 *sp = (png_byte)(tmp & 0xff);
3417 for (i = 0; i < row_width; i++)
3419 if ((png_uint_16)((*sp >> shift) & 0x03)
3420 == png_ptr->trans_color.gray)
3422 unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3424 (
unsigned int)png_ptr->background.gray << shift;
3425 *sp = (png_byte)(tmp & 0xff);
3443#ifdef PNG_READ_GAMMA_SUPPORTED
3444 if (gamma_table != NULL)
3448 for (i = 0; i < row_width; i++)
3450 if ((png_uint_16)((*sp >> shift) & 0x0f)
3451 == png_ptr->trans_color.gray)
3453 unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3455 (
unsigned int)(png_ptr->background.gray << shift);
3456 *sp = (png_byte)(tmp & 0xff);
3461 unsigned int p = (*sp >> shift) & 0x0f;
3462 unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
3464 unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3465 tmp |= (
unsigned int)(g << shift);
3466 *sp = (png_byte)(tmp & 0xff);
3485 for (i = 0; i < row_width; i++)
3487 if ((png_uint_16)((*sp >> shift) & 0x0f)
3488 == png_ptr->trans_color.gray)
3490 unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3492 (
unsigned int)(png_ptr->background.gray << shift);
3493 *sp = (png_byte)(tmp & 0xff);
3511#ifdef PNG_READ_GAMMA_SUPPORTED
3512 if (gamma_table != NULL)
3515 for (i = 0; i < row_width; i++, sp++)
3517 if (*sp == png_ptr->trans_color.gray)
3518 *sp = (png_byte)png_ptr->background.gray;
3521 *sp = gamma_table[*sp];
3528 for (i = 0; i < row_width; i++, sp++)
3530 if (*sp == png_ptr->trans_color.gray)
3531 *sp = (png_byte)png_ptr->background.gray;
3539#ifdef PNG_READ_GAMMA_SUPPORTED
3540 if (gamma_16 != NULL)
3543 for (i = 0; i < row_width; i++, sp += 2)
3547 v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3549 if (v == png_ptr->trans_color.gray)
3552 *sp = (png_byte)((png_ptr->background.gray >> 8)
3554 *(sp + 1) = (png_byte)(png_ptr->background.gray
3560 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3561 *sp = (png_byte)((v >> 8) & 0xff);
3562 *(sp + 1) = (png_byte)(v & 0xff);
3570 for (i = 0; i < row_width; i++, sp += 2)
3574 v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3576 if (v == png_ptr->trans_color.gray)
3578 *sp = (png_byte)((png_ptr->background.gray >> 8)
3580 *(sp + 1) = (png_byte)(png_ptr->background.gray
3594 case PNG_COLOR_TYPE_RGB:
3596 if (row_info->bit_depth == 8)
3598#ifdef PNG_READ_GAMMA_SUPPORTED
3599 if (gamma_table != NULL)
3602 for (i = 0; i < row_width; i++, sp += 3)
3604 if (*sp == png_ptr->trans_color.red &&
3605 *(sp + 1) == png_ptr->trans_color.green &&
3606 *(sp + 2) == png_ptr->trans_color.blue)
3608 *sp = (png_byte)png_ptr->background.red;
3609 *(sp + 1) = (png_byte)png_ptr->background.green;
3610 *(sp + 2) = (png_byte)png_ptr->background.blue;
3615 *sp = gamma_table[*sp];
3616 *(sp + 1) = gamma_table[*(sp + 1)];
3617 *(sp + 2) = gamma_table[*(sp + 2)];
3625 for (i = 0; i < row_width; i++, sp += 3)
3627 if (*sp == png_ptr->trans_color.red &&
3628 *(sp + 1) == png_ptr->trans_color.green &&
3629 *(sp + 2) == png_ptr->trans_color.blue)
3631 *sp = (png_byte)png_ptr->background.red;
3632 *(sp + 1) = (png_byte)png_ptr->background.green;
3633 *(sp + 2) = (png_byte)png_ptr->background.blue;
3640#ifdef PNG_READ_GAMMA_SUPPORTED
3641 if (gamma_16 != NULL)
3644 for (i = 0; i < row_width; i++, sp += 6)
3646 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3648 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3651 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3654 if (r == png_ptr->trans_color.red &&
3655 g == png_ptr->trans_color.green &&
3656 b == png_ptr->trans_color.blue)
3659 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3660 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3661 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3663 *(sp + 3) = (png_byte)(png_ptr->background.green
3665 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3667 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3672 png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3673 *sp = (png_byte)((v >> 8) & 0xff);
3674 *(sp + 1) = (png_byte)(v & 0xff);
3676 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3677 *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3678 *(sp + 3) = (png_byte)(v & 0xff);
3680 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3681 *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3682 *(sp + 5) = (png_byte)(v & 0xff);
3691 for (i = 0; i < row_width; i++, sp += 6)
3693 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3695 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3698 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3701 if (r == png_ptr->trans_color.red &&
3702 g == png_ptr->trans_color.green &&
3703 b == png_ptr->trans_color.blue)
3705 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3706 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3707 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3709 *(sp + 3) = (png_byte)(png_ptr->background.green
3711 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3713 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3721 case PNG_COLOR_TYPE_GRAY_ALPHA:
3723 if (row_info->bit_depth == 8)
3725#ifdef PNG_READ_GAMMA_SUPPORTED
3726 if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3727 gamma_table != NULL)
3730 for (i = 0; i < row_width; i++, sp += 2)
3732 png_uint_16 a = *(sp + 1);
3735 *sp = gamma_table[*sp];
3740 *sp = (png_byte)png_ptr->background.gray;
3747 v = gamma_to_1[*sp];
3748 png_composite(w, v, a, png_ptr->background_1.gray);
3750 w = gamma_from_1[w];
3759 for (i = 0; i < row_width; i++, sp += 2)
3761 png_byte a = *(sp + 1);
3764 *sp = (png_byte)png_ptr->background.gray;
3767 png_composite(*sp, *sp, a, png_ptr->background.gray);
3773#ifdef PNG_READ_GAMMA_SUPPORTED
3774 if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3775 gamma_16_to_1 != NULL)
3778 for (i = 0; i < row_width; i++, sp += 4)
3780 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3783 if (a == (png_uint_16)0xffff)
3787 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3788 *sp = (png_byte)((v >> 8) & 0xff);
3789 *(sp + 1) = (png_byte)(v & 0xff);
3795 *sp = (png_byte)((png_ptr->background.gray >> 8)
3797 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3802 png_uint_16 g, v, w;
3804 g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3805 png_composite_16(v, g, a, png_ptr->background_1.gray);
3809 w = gamma_16_from_1[(v & 0xff) >>
3810 gamma_shift][v >> 8];
3811 *sp = (png_byte)((w >> 8) & 0xff);
3812 *(sp + 1) = (png_byte)(w & 0xff);
3820 for (i = 0; i < row_width; i++, sp += 4)
3822 png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3827 *sp = (png_byte)((png_ptr->background.gray >> 8)
3829 *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3832 else if (a < 0xffff)
3836 g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3837 png_composite_16(v, g, a, png_ptr->background.gray);
3838 *sp = (png_byte)((v >> 8) & 0xff);
3839 *(sp + 1) = (png_byte)(v & 0xff);
3847 case PNG_COLOR_TYPE_RGB_ALPHA:
3849 if (row_info->bit_depth == 8)
3851#ifdef PNG_READ_GAMMA_SUPPORTED
3852 if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3853 gamma_table != NULL)
3856 for (i = 0; i < row_width; i++, sp += 4)
3858 png_byte a = *(sp + 3);
3862 *sp = gamma_table[*sp];
3863 *(sp + 1) = gamma_table[*(sp + 1)];
3864 *(sp + 2) = gamma_table[*(sp + 2)];
3870 *sp = (png_byte)png_ptr->background.red;
3871 *(sp + 1) = (png_byte)png_ptr->background.green;
3872 *(sp + 2) = (png_byte)png_ptr->background.blue;
3879 v = gamma_to_1[*sp];
3880 png_composite(w, v, a, png_ptr->background_1.red);
3881 if (optimize == 0) w = gamma_from_1[w];
3884 v = gamma_to_1[*(sp + 1)];
3885 png_composite(w, v, a, png_ptr->background_1.green);
3886 if (optimize == 0) w = gamma_from_1[w];
3889 v = gamma_to_1[*(sp + 2)];
3890 png_composite(w, v, a, png_ptr->background_1.blue);
3891 if (optimize == 0) w = gamma_from_1[w];
3900 for (i = 0; i < row_width; i++, sp += 4)
3902 png_byte a = *(sp + 3);
3906 *sp = (png_byte)png_ptr->background.red;
3907 *(sp + 1) = (png_byte)png_ptr->background.green;
3908 *(sp + 2) = (png_byte)png_ptr->background.blue;
3913 png_composite(*sp, *sp, a, png_ptr->background.red);
3915 png_composite(*(sp + 1), *(sp + 1), a,
3916 png_ptr->background.green);
3918 png_composite(*(sp + 2), *(sp + 2), a,
3919 png_ptr->background.blue);
3926#ifdef PNG_READ_GAMMA_SUPPORTED
3927 if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3928 gamma_16_to_1 != NULL)
3931 for (i = 0; i < row_width; i++, sp += 8)
3933 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3934 << 8) + (png_uint_16)(*(sp + 7)));
3936 if (a == (png_uint_16)0xffff)
3940 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3941 *sp = (png_byte)((v >> 8) & 0xff);
3942 *(sp + 1) = (png_byte)(v & 0xff);
3944 v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3945 *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3946 *(sp + 3) = (png_byte)(v & 0xff);
3948 v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3949 *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3950 *(sp + 5) = (png_byte)(v & 0xff);
3956 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3957 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3958 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3960 *(sp + 3) = (png_byte)(png_ptr->background.green
3962 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3964 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3971 v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3972 png_composite_16(w, v, a, png_ptr->background_1.red);
3974 w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3976 *sp = (png_byte)((w >> 8) & 0xff);
3977 *(sp + 1) = (png_byte)(w & 0xff);
3979 v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3980 png_composite_16(w, v, a, png_ptr->background_1.green);
3982 w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3985 *(sp + 2) = (png_byte)((w >> 8) & 0xff);
3986 *(sp + 3) = (png_byte)(w & 0xff);
3988 v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3989 png_composite_16(w, v, a, png_ptr->background_1.blue);
3991 w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3994 *(sp + 4) = (png_byte)((w >> 8) & 0xff);
3995 *(sp + 5) = (png_byte)(w & 0xff);
4004 for (i = 0; i < row_width; i++, sp += 8)
4006 png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
4007 << 8) + (png_uint_16)(*(sp + 7)));
4011 *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
4012 *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
4013 *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
4015 *(sp + 3) = (png_byte)(png_ptr->background.green
4017 *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
4019 *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
4022 else if (a < 0xffff)
4026 png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
4027 png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
4029 png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
4032 png_composite_16(v, r, a, png_ptr->background.red);
4033 *sp = (png_byte)((v >> 8) & 0xff);
4034 *(sp + 1) = (png_byte)(v & 0xff);
4036 png_composite_16(v, g, a, png_ptr->background.green);
4037 *(sp + 2) = (png_byte)((v >> 8) & 0xff);
4038 *(sp + 3) = (png_byte)(v & 0xff);
4040 png_composite_16(v, b, a, png_ptr->background.blue);
4041 *(sp + 4) = (png_byte)((v >> 8) & 0xff);
4042 *(sp + 5) = (png_byte)(v & 0xff);
4056#ifdef PNG_READ_GAMMA_SUPPORTED
4064png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4066 png_const_bytep gamma_table = png_ptr->gamma_table;
4067 png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
4068 int gamma_shift = png_ptr->gamma_shift;
4072 png_uint_32 row_width=row_info->width;
4074 png_debug(1,
"in png_do_gamma");
4076 if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
4077 (row_info->bit_depth == 16 && gamma_16_table != NULL)))
4079 switch (row_info->color_type)
4081 case PNG_COLOR_TYPE_RGB:
4083 if (row_info->bit_depth == 8)
4086 for (i = 0; i < row_width; i++)
4088 *sp = gamma_table[*sp];
4090 *sp = gamma_table[*sp];
4092 *sp = gamma_table[*sp];
4100 for (i = 0; i < row_width; i++)
4104 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4105 *sp = (png_byte)((v >> 8) & 0xff);
4106 *(sp + 1) = (png_byte)(v & 0xff);
4109 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4110 *sp = (png_byte)((v >> 8) & 0xff);
4111 *(sp + 1) = (png_byte)(v & 0xff);
4114 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4115 *sp = (png_byte)((v >> 8) & 0xff);
4116 *(sp + 1) = (png_byte)(v & 0xff);
4123 case PNG_COLOR_TYPE_RGB_ALPHA:
4125 if (row_info->bit_depth == 8)
4128 for (i = 0; i < row_width; i++)
4130 *sp = gamma_table[*sp];
4133 *sp = gamma_table[*sp];
4136 *sp = gamma_table[*sp];
4146 for (i = 0; i < row_width; i++)
4148 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4149 *sp = (png_byte)((v >> 8) & 0xff);
4150 *(sp + 1) = (png_byte)(v & 0xff);
4153 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4154 *sp = (png_byte)((v >> 8) & 0xff);
4155 *(sp + 1) = (png_byte)(v & 0xff);
4158 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4159 *sp = (png_byte)((v >> 8) & 0xff);
4160 *(sp + 1) = (png_byte)(v & 0xff);
4167 case PNG_COLOR_TYPE_GRAY_ALPHA:
4169 if (row_info->bit_depth == 8)
4172 for (i = 0; i < row_width; i++)
4174 *sp = gamma_table[*sp];
4182 for (i = 0; i < row_width; i++)
4184 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4185 *sp = (png_byte)((v >> 8) & 0xff);
4186 *(sp + 1) = (png_byte)(v & 0xff);
4193 case PNG_COLOR_TYPE_GRAY:
4195 if (row_info->bit_depth == 2)
4198 for (i = 0; i < row_width; i += 4)
4206 ((((
int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
4207 ((((
int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
4208 ((((
int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
4209 ((((
int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
4214 if (row_info->bit_depth == 4)
4217 for (i = 0; i < row_width; i += 2)
4219 int msb = *sp & 0xf0;
4220 int lsb = *sp & 0x0f;
4222 *sp = (png_byte)((((
int)gamma_table[msb | (msb >> 4)]) & 0xf0)
4223 | (((
int)gamma_table[(lsb << 4) | lsb]) >> 4));
4228 else if (row_info->bit_depth == 8)
4231 for (i = 0; i < row_width; i++)
4233 *sp = gamma_table[*sp];
4238 else if (row_info->bit_depth == 16)
4241 for (i = 0; i < row_width; i++)
4243 png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4244 *sp = (png_byte)((v >> 8) & 0xff);
4245 *(sp + 1) = (png_byte)(v & 0xff);
4259#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4265png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4267 png_uint_32 row_width = row_info->width;
4269 png_debug(1,
"in png_do_encode_alpha");
4271 if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4273 if (row_info->bit_depth == 8)
4275 png_bytep table = png_ptr->gamma_from_1;
4279 int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
4284 for (; row_width > 0; --row_width, row += step)
4291 else if (row_info->bit_depth == 16)
4293 png_uint_16pp table = png_ptr->gamma_16_from_1;
4294 int gamma_shift = png_ptr->gamma_shift;
4298 int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
4303 for (; row_width > 0; --row_width, row += step)
4307 v = table[*(row + 1) >> gamma_shift][*row];
4308 *row = (png_byte)((v >> 8) & 0xff);
4309 *(row + 1) = (png_byte)(v & 0xff);
4320 png_warning(png_ptr,
"png_do_encode_alpha: unexpected call");
4324#ifdef PNG_READ_EXPAND_SUPPORTED
4329png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
4330 png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
4336 png_uint_32 row_width=row_info->width;
4338 png_debug(1,
"in png_do_expand_palette");
4340 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4342 if (row_info->bit_depth < 8)
4344 switch (row_info->bit_depth)
4348 sp = row + (size_t)((row_width - 1) >> 3);
4349 dp = row + (size_t)row_width - 1;
4350 shift = 7 - (int)((row_width + 7) & 0x07);
4351 for (i = 0; i < row_width; i++)
4353 if ((*sp >> shift) & 0x01)
4375 sp = row + (size_t)((row_width - 1) >> 2);
4376 dp = row + (size_t)row_width - 1;
4377 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4378 for (i = 0; i < row_width; i++)
4380 value = (*sp >> shift) & 0x03;
4381 *dp = (png_byte)value;
4398 sp = row + (size_t)((row_width - 1) >> 1);
4399 dp = row + (size_t)row_width - 1;
4400 shift = (int)((row_width & 0x01) << 2);
4401 for (i = 0; i < row_width; i++)
4403 value = (*sp >> shift) & 0x0f;
4404 *dp = (png_byte)value;
4422 row_info->bit_depth = 8;
4423 row_info->pixel_depth = 8;
4424 row_info->rowbytes = row_width;
4427 if (row_info->bit_depth == 8)
4432 sp = row + (size_t)row_width - 1;
4433 dp = row + ((size_t)row_width << 2) - 1;
4436#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
4437 if (png_ptr->riffled_palette != NULL)
4443 i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row,
4450 for (; i < row_width; i++)
4452 if ((
int)(*sp) >= num_trans)
4455 *dp-- = trans_alpha[*sp];
4456 *dp-- = palette[*sp].blue;
4457 *dp-- = palette[*sp].green;
4458 *dp-- = palette[*sp].red;
4461 row_info->bit_depth = 8;
4462 row_info->pixel_depth = 32;
4463 row_info->rowbytes = row_width * 4;
4464 row_info->color_type = 6;
4465 row_info->channels = 4;
4470 sp = row + (size_t)row_width - 1;
4471 dp = row + (size_t)(row_width * 3) - 1;
4473#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
4474 i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row,
4480 for (; i < row_width; i++)
4482 *dp-- = palette[*sp].blue;
4483 *dp-- = palette[*sp].green;
4484 *dp-- = palette[*sp].red;
4488 row_info->bit_depth = 8;
4489 row_info->pixel_depth = 24;
4490 row_info->rowbytes = row_width * 3;
4491 row_info->color_type = 2;
4492 row_info->channels = 3;
4503png_do_expand(png_row_infop row_info, png_bytep row,
4504 png_const_color_16p trans_color)
4509 png_uint_32 row_width=row_info->width;
4511 png_debug(1,
"in png_do_expand");
4513 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
4515 unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
4517 if (row_info->bit_depth < 8)
4519 switch (row_info->bit_depth)
4523 gray = (gray & 0x01) * 0xff;
4524 sp = row + (size_t)((row_width - 1) >> 3);
4525 dp = row + (size_t)row_width - 1;
4526 shift = 7 - (int)((row_width + 7) & 0x07);
4527 for (i = 0; i < row_width; i++)
4529 if ((*sp >> shift) & 0x01)
4551 gray = (gray & 0x03) * 0x55;
4552 sp = row + (size_t)((row_width - 1) >> 2);
4553 dp = row + (size_t)row_width - 1;
4554 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4555 for (i = 0; i < row_width; i++)
4557 value = (*sp >> shift) & 0x03;
4558 *dp = (png_byte)(value | (value << 2) | (value << 4) |
4576 gray = (gray & 0x0f) * 0x11;
4577 sp = row + (size_t)((row_width - 1) >> 1);
4578 dp = row + (size_t)row_width - 1;
4579 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
4580 for (i = 0; i < row_width; i++)
4582 value = (*sp >> shift) & 0x0f;
4583 *dp = (png_byte)(value | (value << 4));
4602 row_info->bit_depth = 8;
4603 row_info->pixel_depth = 8;
4604 row_info->rowbytes = row_width;
4607 if (trans_color != NULL)
4609 if (row_info->bit_depth == 8)
4612 sp = row + (size_t)row_width - 1;
4613 dp = row + ((size_t)row_width << 1) - 1;
4615 for (i = 0; i < row_width; i++)
4617 if ((*sp & 0xffU) == gray)
4627 else if (row_info->bit_depth == 16)
4629 unsigned int gray_high = (gray >> 8) & 0xff;
4630 unsigned int gray_low = gray & 0xff;
4631 sp = row + row_info->rowbytes - 1;
4632 dp = row + (row_info->rowbytes << 1) - 1;
4633 for (i = 0; i < row_width; i++)
4635 if ((*(sp - 1) & 0xffU) == gray_high &&
4636 (*(sp) & 0xffU) == gray_low)
4653 row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
4654 row_info->channels = 2;
4655 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
4656 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
4660 else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
4661 trans_color != NULL)
4663 if (row_info->bit_depth == 8)
4665 png_byte red = (png_byte)(trans_color->red & 0xff);
4666 png_byte green = (png_byte)(trans_color->green & 0xff);
4667 png_byte blue = (png_byte)(trans_color->blue & 0xff);
4668 sp = row + (size_t)row_info->rowbytes - 1;
4669 dp = row + ((size_t)row_width << 2) - 1;
4670 for (i = 0; i < row_width; i++)
4672 if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
4683 else if (row_info->bit_depth == 16)
4685 png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
4686 png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
4687 png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
4688 png_byte red_low = (png_byte)(trans_color->red & 0xff);
4689 png_byte green_low = (png_byte)(trans_color->green & 0xff);
4690 png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
4691 sp = row + row_info->rowbytes - 1;
4692 dp = row + ((size_t)row_width << 3) - 1;
4693 for (i = 0; i < row_width; i++)
4695 if (*(sp - 5) == red_high &&
4696 *(sp - 4) == red_low &&
4697 *(sp - 3) == green_high &&
4698 *(sp - 2) == green_low &&
4699 *(sp - 1) == blue_high &&
4720 row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
4721 row_info->channels = 4;
4722 row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
4723 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4728#ifdef PNG_READ_EXPAND_16_SUPPORTED
4733png_do_expand_16(png_row_infop row_info, png_bytep row)
4735 if (row_info->bit_depth == 8 &&
4736 row_info->color_type != PNG_COLOR_TYPE_PALETTE)
4747 png_byte *sp = row + row_info->rowbytes;
4748 png_byte *dp = sp + row_info->rowbytes;
4751 dp[-2] = dp[-1] = *--sp; dp -= 2;
4754 row_info->rowbytes *= 2;
4755 row_info->bit_depth = 16;
4756 row_info->pixel_depth = (png_byte)(row_info->channels * 16);
4761#ifdef PNG_READ_QUANTIZE_SUPPORTED
4763png_do_quantize(png_row_infop row_info, png_bytep row,
4764 png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
4768 png_uint_32 row_width=row_info->width;
4770 png_debug(1,
"in png_do_quantize");
4772 if (row_info->bit_depth == 8)
4774 if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
4779 for (i = 0; i < row_width; i++)
4792 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4793 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4794 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4795 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4796 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4797 (PNG_QUANTIZE_BLUE_BITS)) |
4798 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4799 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4801 *dp++ = palette_lookup[p];
4804 row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4805 row_info->channels = 1;
4806 row_info->pixel_depth = row_info->bit_depth;
4807 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4810 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
4811 palette_lookup != NULL)
4816 for (i = 0; i < row_width; i++)
4823 p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4824 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4825 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4826 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4827 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4828 (PNG_QUANTIZE_BLUE_BITS)) |
4829 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4830 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4832 *dp++ = palette_lookup[p];
4835 row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4836 row_info->channels = 1;
4837 row_info->pixel_depth = row_info->bit_depth;
4838 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4841 else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4846 for (i = 0; i < row_width; i++, sp++)
4848 *sp = quantize_lookup[*sp];
4860png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
4862 png_debug(1,
"in png_do_read_transformations");
4864 if (png_ptr->row_buf == NULL)
4870 png_error(png_ptr,
"NULL row buffer");
4879 if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
4880 (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
4886 png_error(png_ptr,
"Uninitialized row");
4889#ifdef PNG_READ_EXPAND_SUPPORTED
4890 if ((png_ptr->transformations & PNG_EXPAND) != 0)
4892 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4894#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
4895 if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8))
4897 if (png_ptr->riffled_palette == NULL)
4900 png_ptr->riffled_palette =
4901 (png_bytep)png_malloc(png_ptr, 256 * 4);
4902 png_riffle_palette_neon(png_ptr);
4906 png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
4907 png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
4912 if (png_ptr->num_trans != 0 &&
4913 (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
4914 png_do_expand(row_info, png_ptr->row_buf + 1,
4915 &(png_ptr->trans_color));
4918 png_do_expand(row_info, png_ptr->row_buf + 1, NULL);
4923#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4924 if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4925 (png_ptr->transformations & PNG_COMPOSE) == 0 &&
4926 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
4927 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
4928 png_do_strip_channel(row_info, png_ptr->row_buf + 1,
4932#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
4933 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
4936 png_do_rgb_to_gray(png_ptr, row_info,
4937 png_ptr->row_buf + 1);
4941 png_ptr->rgb_to_gray_status=1;
4942 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4943 PNG_RGB_TO_GRAY_WARN)
4944 png_warning(png_ptr,
"png_do_rgb_to_gray found nongray pixel");
4946 if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4947 PNG_RGB_TO_GRAY_ERR)
4948 png_error(png_ptr,
"png_do_rgb_to_gray found nongray pixel");
4984#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4988 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
4989 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
4990 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
4993#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
4994 defined(PNG_READ_ALPHA_MODE_SUPPORTED)
4995 if ((png_ptr->transformations & PNG_COMPOSE) != 0)
4996 png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
4999#ifdef PNG_READ_GAMMA_SUPPORTED
5000 if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
5001#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
5003 (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
5005#
if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
5006 defined(PNG_READ_ALPHA_MODE_SUPPORTED)
5010 !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
5011 ((png_ptr->num_trans != 0) ||
5012 (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
5017 (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
5018 png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
5021#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
5022 if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
5023 (png_ptr->transformations & PNG_COMPOSE) != 0 &&
5024 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
5025 row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
5026 png_do_strip_channel(row_info, png_ptr->row_buf + 1,
5030#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
5031 if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
5032 (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
5033 png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
5036#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
5037 if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
5038 png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
5041#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
5046 if ((png_ptr->transformations & PNG_16_TO_8) != 0)
5047 png_do_chop(row_info, png_ptr->row_buf + 1);
5050#ifdef PNG_READ_QUANTIZE_SUPPORTED
5051 if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
5052 png_do_quantize(row_info, png_ptr->row_buf + 1,
5053 png_ptr->palette_lookup, png_ptr->quantize_index);
5056#ifdef PNG_READ_EXPAND_16_SUPPORTED
5062 if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
5063 png_do_expand_16(row_info, png_ptr->row_buf + 1);
5066#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
5068 if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
5069 (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
5070 png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
5073#ifdef PNG_READ_INVERT_SUPPORTED
5074 if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
5075 png_do_invert(row_info, png_ptr->row_buf + 1);
5078#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
5079 if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
5080 png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
5083#ifdef PNG_READ_SHIFT_SUPPORTED
5084 if ((png_ptr->transformations & PNG_SHIFT) != 0)
5085 png_do_unshift(row_info, png_ptr->row_buf + 1,
5089#ifdef PNG_READ_PACK_SUPPORTED
5090 if ((png_ptr->transformations & PNG_PACK) != 0)
5091 png_do_unpack(row_info, png_ptr->row_buf + 1);
5094#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
5096 if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
5097 png_ptr->num_palette_max >= 0)
5098 png_do_check_palette_indexes(png_ptr, row_info);
5101#ifdef PNG_READ_BGR_SUPPORTED
5102 if ((png_ptr->transformations & PNG_BGR) != 0)
5103 png_do_bgr(row_info, png_ptr->row_buf + 1);
5106#ifdef PNG_READ_PACKSWAP_SUPPORTED
5107 if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
5108 png_do_packswap(row_info, png_ptr->row_buf + 1);
5111#ifdef PNG_READ_FILLER_SUPPORTED
5112 if ((png_ptr->transformations & PNG_FILLER) != 0)
5113 png_do_read_filler(row_info, png_ptr->row_buf + 1,
5114 (png_uint_32)png_ptr->filler, png_ptr->flags);
5117#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
5118 if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
5119 png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
5122#ifdef PNG_READ_16BIT_SUPPORTED
5123#ifdef PNG_READ_SWAP_SUPPORTED
5124 if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
5125 png_do_swap(row_info, png_ptr->row_buf + 1);
5129#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
5130 if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
5132 if (png_ptr->read_user_transform_fn != NULL)
5133 (*(png_ptr->read_user_transform_fn))
5142 png_ptr->row_buf + 1);
5143#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
5144 if (png_ptr->user_transform_depth != 0)
5145 row_info->bit_depth = png_ptr->user_transform_depth;
5147 if (png_ptr->user_transform_channels != 0)
5148 row_info->channels = png_ptr->user_transform_channels;
5150 row_info->pixel_depth = (png_byte)(row_info->bit_depth *
5151 row_info->channels);
5153 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);