📄 pngrtran.c
字号:
num_new_palette--; palette[png_ptr->index_to_palette[j]] = palette[num_new_palette]; if (!full_dither) { int k; for (k = 0; k < num_palette; k++) { if (png_ptr->dither_index[k] == png_ptr->index_to_palette[j]) png_ptr->dither_index[k] = png_ptr->index_to_palette[next_j]; if ((int)png_ptr->dither_index[k] == num_new_palette) png_ptr->dither_index[k] = png_ptr->index_to_palette[j]; } } png_ptr->index_to_palette[png_ptr->palette_to_index [num_new_palette]] = png_ptr->index_to_palette[j]; png_ptr->palette_to_index[png_ptr->index_to_palette[j]] = png_ptr->palette_to_index[num_new_palette]; png_ptr->index_to_palette[j] = (png_byte)num_new_palette; png_ptr->palette_to_index[num_new_palette] = (png_byte)j; } if (num_new_palette <= maximum_colors) break; } if (num_new_palette <= maximum_colors) break; } } for (i = 0; i < 769; i++) { if (hash[i] != NULL) { png_dsortp p = hash[i]; while (p) { t = p->next; png_free(png_ptr, p); p = t; } } hash[i] = 0; } max_d += 96; } png_free(png_ptr, hash); png_free(png_ptr, png_ptr->palette_to_index); png_free(png_ptr, png_ptr->index_to_palette); png_ptr->palette_to_index=NULL; png_ptr->index_to_palette=NULL; } num_palette = maximum_colors; } if (png_ptr->palette == NULL) { png_ptr->palette = palette; } png_ptr->num_palette = (png_uint_16)num_palette; if (full_dither) { int i; png_bytep distance; int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS; int num_red = (1 << PNG_DITHER_RED_BITS); int num_green = (1 << PNG_DITHER_GREEN_BITS); int num_blue = (1 << PNG_DITHER_BLUE_BITS); png_size_t num_entries = ((png_size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, (png_uint_32)(num_entries * png_sizeof (png_byte))); png_memset(png_ptr->palette_lookup, 0, num_entries * png_sizeof (png_byte)); distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * png_sizeof(png_byte))); png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); for (i = 0; i < num_palette; i++) { int ir, ig, ib; int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS)); int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS)); int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS)); for (ir = 0; ir < num_red; ir++) { /* int dr = abs(ir - r); */ int dr = ((ir > r) ? ir - r : r - ir); int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS)); for (ig = 0; ig < num_green; ig++) { /* int dg = abs(ig - g); */ int dg = ((ig > g) ? ig - g : g - ig); int dt = dr + dg; int dm = ((dr > dg) ? dr : dg); int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS); for (ib = 0; ib < num_blue; ib++) { int d_index = index_g | ib; /* int db = abs(ib - b); */ int db = ((ib > b) ? ib - b : b - ib); int dmax = ((dm > db) ? dm : db); int d = dmax + dt + db; if (d < (int)distance[d_index]) { distance[d_index] = (png_byte)d; png_ptr->palette_lookup[d_index] = (png_byte)i; } } } } } png_free(png_ptr, distance); }}#endif#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)/* Transform the image from the file_gamma to the screen_gamma. We * only do transformations on images where the file_gamma and screen_gamma * are not close reciprocals, otherwise it slows things down slightly, and * also needlessly introduces small errors. * * We will turn off gamma transformation later if no semitransparent entries * are present in the tRNS array for palette images. We can't do it here * because we don't necessarily have the tRNS chunk yet. */void PNGAPIpng_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma){ png_debug(1, "in png_set_gamma\n"); if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) png_ptr->transformations |= PNG_GAMMA; png_ptr->gamma = (float)file_gamma; png_ptr->screen_gamma = (float)scrn_gamma;}#endif#if defined(PNG_READ_EXPAND_SUPPORTED)/* Expand paletted images to RGB, expand grayscale images of * less than 8-bit depth to 8-bit depth, and expand tRNS chunks * to alpha channels. */void PNGAPIpng_set_expand(png_structp png_ptr){ png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND;}/* GRR 19990627: the following three functions currently are identical * to png_set_expand(). However, it is entirely reasonable that someone * might wish to expand an indexed image to RGB but *not* expand a single, * fully transparent palette entry to a full alpha channel--perhaps instead * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace * the transparent color with a particular RGB value, or drop tRNS entirely. * IOW, a future version of the library may make the transformations flag * a bit more fine-grained, with separate bits for each of these three * functions. * * More to the point, these functions make it obvious what libpng will be * doing, whereas "expand" can (and does) mean any number of things. *//* Expand paletted images to RGB. */void PNGAPIpng_set_palette_to_rgb(png_structp png_ptr){ png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND;}/* Expand grayscale images of less than 8-bit depth to 8 bits. */void PNGAPIpng_set_gray_1_2_4_to_8(png_structp png_ptr){ png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND;}/* Expand tRNS chunks to alpha channels. */void PNGAPIpng_set_tRNS_to_alpha(png_structp png_ptr){ png_debug(1, "in png_set_expand\n"); png_ptr->transformations |= PNG_EXPAND;}#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)void PNGAPIpng_set_gray_to_rgb(png_structp png_ptr){ png_debug(1, "in png_set_gray_to_rgb\n"); png_ptr->transformations |= PNG_GRAY_TO_RGB;}#endif#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)#if defined(PNG_FLOATING_POINT_SUPPORTED)/* Convert a RGB image to a grayscale of the same width. This allows us, * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. */void PNGAPIpng_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, double green){ int red_fixed = (int)((float)red*100000.0 + 0.5); int green_fixed = (int)((float)green*100000.0 + 0.5); png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);}#endifvoid PNGAPIpng_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, png_fixed_point red, png_fixed_point green){ png_debug(1, "in png_set_rgb_to_gray\n"); switch(error_action) { case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; break; case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; break; case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)#if defined(PNG_READ_EXPAND_SUPPORTED) png_ptr->transformations |= PNG_EXPAND;#else { png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); png_ptr->transformations &= ~PNG_RGB_TO_GRAY; }#endif { png_uint_16 red_int, green_int; if(red < 0 || green < 0) { red_int = 6968; /* .212671 * 32768 + .5 */ green_int = 23434; /* .715160 * 32768 + .5 */ } else if(red + green < 100000L) { red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); } else { png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); red_int = 6968; green_int = 23434; } png_ptr->rgb_to_gray_red_coeff = red_int; png_ptr->rgb_to_gray_green_coeff = green_int; png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int); }}#endif#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_LEGACY_SUPPORTED)void PNGAPIpng_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr read_user_transform_fn){ png_debug(1, "in png_set_read_user_transform_fn\n");#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_ptr->transformations |= PNG_USER_TRANSFORM; png_ptr->read_user_transform_fn = read_user_transform_fn;#endif#ifdef PNG_LEGACY_SUPPORTED if(read_user_transform_fn) png_warning(png_ptr, "This version of libpng does not support user transforms");#endif}#endif/* Initialize everything needed for the read. This includes modifying * the palette. */void /* PRIVATE */png_init_read_transformations(png_structp png_ptr){ png_debug(1, "in png_init_read_transformations\n");#if defined(PNG_USELESS_TESTS_SUPPORTED) if(png_ptr != NULL)#endif {#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \ || defined(PNG_READ_GAMMA_SUPPORTED) int color_type = png_ptr->color_type;#endif#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && (png_ptr->transformations & PNG_EXPAND)) { if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */ { /* expand background chunk. */ switch (png_ptr->bit_depth) { case 1: png_ptr->background.gray *= (png_uint_16)0xff; png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; case 2: png_ptr->background.gray *= (png_uint_16)0x55; png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; case 4: png_ptr->background.gray *= (png_uint_16)0x11; png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; case 8: case 16: png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; break; } } else if (color_type == PNG_COLOR_TYPE_PALETTE) { png_ptr->background.red = png_ptr->palette[png_ptr->background.index].red; png_ptr->background.green = png_ptr->palette[png_ptr->background.index].green; png_ptr->background.blue = png_ptr->palette[png_ptr->background.index].blue;#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_ALPHA) {#if defined(PNG_READ_EXPAND_SUPPORTED) if (!(png_ptr->transformations & PNG_EXPAND))#endif { /* invert the alpha channel (in tRNS) unless the pixels are going to be expanded, in which case leave it for later */ int i,istop; istop=(int)png_ptr->num_trans; for (i=0; i<istop; i++) png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]); } }#endif } }#endif#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) png_ptr->background_1 = png_ptr->background;#endif#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) < PNG_GAMMA_THRESHOLD)) { int i,k; k=0; for (i=0; i<png_ptr->num_trans; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -