diff options
Diffstat (limited to 'pngrtran.c')
-rw-r--r-- | pngrtran.c | 294 |
1 files changed, 166 insertions, 128 deletions
diff --git a/pngrtran.c b/pngrtran.c index 0adf311b7..fa9fe95b9 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,10 +1,10 @@ /* pngrtran.c - transforms the data in a row for png readers - libpng 1.0 beta 3 - version 0.89 + libpng 1.0 beta 4 - version 0.90 For conditions of distribution and use, see copyright notice in png.h Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. - May 25, 1996 + January 10, 1997 */ #define PNG_INTERNAL @@ -17,6 +17,12 @@ png_set_background(png_structp png_ptr, png_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma) { + if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) + { + png_warning(png_ptr, "Application must supply a known background gamma"); + return; + } + png_ptr->transformations |= PNG_BACKGROUND; png_memcpy(&(png_ptr->background), background_color, sizeof(png_color_16)); @@ -63,7 +69,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette, { int i; - png_ptr->dither_index = (png_bytep)png_large_malloc(png_ptr, + png_ptr->dither_index = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte)); for (i = 0; i < num_palette; i++) png_ptr->dither_index[i] = (png_byte)i; @@ -80,7 +86,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette, png_bytep sort; /* initialize an array to sort colors */ - sort = (png_bytep)png_large_malloc(png_ptr, num_palette * sizeof (png_byte)); + sort = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte)); /* initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -190,7 +196,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette, } } } - png_large_free(png_ptr, sort); + png_free(png_ptr, sort); } else { @@ -210,9 +216,9 @@ png_set_dither(png_structp png_ptr, png_colorp palette, /* which original index points to this palette color */ /* initialize palette index arrays */ - index_to_palette = (png_bytep)png_large_malloc(png_ptr, + index_to_palette = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte)); - palette_to_index = (png_bytep)png_large_malloc(png_ptr, + palette_to_index = (png_bytep)png_malloc(png_ptr, num_palette * sizeof (png_byte)); /* initialize the sort array */ @@ -222,7 +228,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette, palette_to_index[i] = (png_byte)i; } - hash = (png_dsortpp)png_large_malloc(png_ptr, 769 * sizeof (png_dsortp)); + hash = (png_dsortpp)png_malloc(png_ptr, 769 * sizeof (png_dsortp)); for (i = 0; i < 769; i++) hash[i] = (png_dsortp)0; /* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */ @@ -255,7 +261,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette, { png_dsortp t; - t = png_large_malloc(png_ptr, sizeof (png_dsort)); + t = png_malloc(png_ptr, sizeof (png_dsort)); t->next = hash[d]; t->left = (png_byte)i; t->right = (png_byte)j; @@ -336,7 +342,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette, png_dsortp t; t = p->next; - png_large_free(png_ptr, p); + png_free(png_ptr, p); p = t; } } @@ -344,9 +350,9 @@ png_set_dither(png_structp png_ptr, png_colorp palette, } max_d += 96; } - png_large_free(png_ptr, hash); - png_large_free(png_ptr, palette_to_index); - png_large_free(png_ptr, index_to_palette); + png_free(png_ptr, hash); + png_free(png_ptr, palette_to_index); + png_free(png_ptr, index_to_palette); } num_palette = maximum_colors; } @@ -371,12 +377,12 @@ png_set_dither(png_structp png_ptr, png_colorp palette, num_blue = (1 << PNG_DITHER_BLUE_BITS); num_entries = ((png_uint_32)1 << total_bits); - png_ptr->palette_lookup = (png_bytep )png_large_malloc(png_ptr, + png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, (png_size_t)num_entries * sizeof (png_byte)); png_memset(png_ptr->palette_lookup, 0, (png_size_t)num_entries * sizeof (png_byte)); - distance = (png_bytep )png_large_malloc(png_ptr, + distance = (png_bytep )png_malloc(png_ptr, (png_size_t)num_entries * sizeof (png_byte)); png_memset(distance, 0xff, (png_size_t)num_entries * sizeof (png_byte)); @@ -422,27 +428,30 @@ png_set_dither(png_structp png_ptr, png_colorp palette, } } - png_large_free(png_ptr, distance); + png_free(png_ptr, distance); } } #endif #if defined(PNG_READ_GAMMA_SUPPORTED) -/* transform the image from the file_gamma to the screen_gamma */ +/* 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 introduces small errors. */ void -png_set_gamma(png_structp png_ptr, double screen_gamma, - double file_gamma) +png_set_gamma(png_structp png_ptr, double screen_gamma, double file_gamma) { - png_ptr->transformations |= PNG_GAMMA; + if (fabs(screen_gamma * file_gamma - 1.0) > 0.05) + png_ptr->transformations |= PNG_GAMMA; png_ptr->gamma = (float)file_gamma; png_ptr->display_gamma = (float)screen_gamma; } #endif #if defined(PNG_READ_EXPAND_SUPPORTED) -/* expand paletted images to rgb, expand grayscale images of +/* Expand paletted images to rgb, expand grayscale images of less then 8 bit depth to 8 bit depth, and expand tRNS chunks - to alpha channels */ + to alpha channels. */ void png_set_expand(png_structp png_ptr) { @@ -458,6 +467,18 @@ png_set_gray_to_rgb(png_structp png_ptr) } #endif +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* Convert a RGB image to a grayscale of the given width. This would + allow us, for example, to convert a 24 bpp RGB image into an 8 or + 16 bpp grayscale image. (Not yet implemented.) */ +void +png_set_rgb_to_gray(png_structp png_ptr, int gray_bits) +{ + png_ptr->transformations |= PNG_RGB_TO_GRAY; + /* Need to do something with gray_bits here. */ +} +#endif + /* initialize everything needed for the read. This includes modifying the palette */ void @@ -804,6 +825,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) void png_do_read_transformations(png_structp png_ptr) { + #if defined(PNG_READ_EXPAND_SUPPORTED) if ((png_ptr->transformations & PNG_EXPAND) && png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) @@ -835,12 +857,18 @@ png_do_read_transformations(png_structp png_ptr) #if defined(PNG_READ_GAMMA_SUPPORTED) if ((png_ptr->transformations & PNG_GAMMA) && - !(png_ptr->transformations & PNG_BACKGROUND)) + !(png_ptr->transformations & PNG_BACKGROUND) && + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->gamma_table, png_ptr->gamma_16_table, png_ptr->gamma_shift); #endif +#if defined(PNG_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + png_do_rgb_to_gray(&(png_ptr->row_info), png_ptr->row_buf + 1); +#endif + #if defined(PNG_READ_16_TO_8_SUPPORTED) if (png_ptr->transformations & PNG_16_TO_8) png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -1097,6 +1125,7 @@ png_do_chop(png_row_infop row_info, png_bytep row) { png_bytep sp, dp; png_uint_32 i; + if (row && row_info && row_info->bit_depth == 16) { sp = row; @@ -1123,7 +1152,7 @@ png_do_chop(png_row_infop row_info, png_bytep row) /* add filler byte */ void png_do_read_filler(png_row_infop row_info, png_bytep row, - png_byte filler, png_byte flags) + png_byte filler, png_uint_32 flags) { png_bytep sp, dp; png_uint_32 i; @@ -1304,8 +1333,8 @@ png_build_grayscale_palette(int bit_depth, png_colorp palette) } } -/* This function is currently unused? */ -#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_CORRECT_PALETTE_SUPPORTED) +/* This function is currently unused. Do we really need it? */ +#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED) void png_correct_palette(png_structp png_ptr, png_colorp palette, int num_palette) @@ -2137,6 +2166,7 @@ png_do_background(png_row_infop row_info, png_bytep row, break; } } + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; @@ -2463,123 +2493,131 @@ png_do_expand(png_row_infop row_info, png_bytep row, if (row && row_info) { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY && - row_info->bit_depth < 8) + if (row_info->color_type == PNG_COLOR_TYPE_GRAY ) { - switch (row_info->bit_depth) + png_uint_16 gray = trans_value ? trans_value->gray : 0; + + if (row_info->bit_depth < 8) { - case 1: + switch (row_info->bit_depth) { - sp = row + (png_size_t)((row_info->width - 1) >> 3); - dp = row + (png_size_t)row_info->width - 1; - shift = 7 - (int)((row_info->width + 7) & 7); - for (i = 0; i < row_info->width; i++) + case 1: { - if ((*sp >> shift) & 0x1) - *dp = 0xff; - else - *dp = 0; - if (shift == 7) + gray *= 0xff; + sp = row + (png_size_t)((row_info->width - 1) >> 3); + dp = row + (png_size_t)row_info->width - 1; + shift = 7 - (int)((row_info->width + 7) & 7); + for (i = 0; i < row_info->width; i++) { - shift = 0; - sp--; - } - else - shift++; + if ((*sp >> shift) & 0x1) + *dp = 0xff; + else + *dp = 0; + if (shift == 7) + { + shift = 0; + sp--; + } + else + shift++; - dp--; + dp--; + } + break; } - break; - } - case 2: - { - sp = row + (png_size_t)((row_info->width - 1) >> 2); - dp = row + (png_size_t)row_info->width - 1; - shift = (int)((3 - ((row_info->width + 3) & 3)) << 1); - for (i = 0; i < row_info->width; i++) + case 2: { - value = (*sp >> shift) & 0x3; - *dp = (png_byte)(value | (value << 2) | (value << 4) | - (value << 6)); - if (shift == 6) + gray *= 0x55; + sp = row + (png_size_t)((row_info->width - 1) >> 2); + dp = row + (png_size_t)row_info->width - 1; + shift = (int)((3 - ((row_info->width + 3) & 3)) << 1); + for (i = 0; i < row_info->width; i++) { - shift = 0; - sp--; - } - else - shift += 2; + value = (*sp >> shift) & 0x3; + *dp = (png_byte)(value | (value << 2) | (value << 4) | + (value << 6)); + if (shift == 6) + { + shift = 0; + sp--; + } + else + shift += 2; - dp--; + dp--; + } + break; } - break; - } - case 4: - { - sp = row + (png_size_t)((row_info->width - 1) >> 1); - dp = row + (png_size_t)row_info->width - 1; - shift = (int)((1 - ((row_info->width + 1) & 1)) << 2); - for (i = 0; i < row_info->width; i++) + case 4: { - value = (*sp >> shift) & 0xf; - *dp = (png_byte)(value | (value << 4)); - if (shift == 4) + gray *= 0x11; + sp = row + (png_size_t)((row_info->width - 1) >> 1); + dp = row + (png_size_t)row_info->width - 1; + shift = (int)((1 - ((row_info->width + 1) & 1)) << 2); + for (i = 0; i < row_info->width; i++) { - shift = 0; - sp--; - } - else - shift = 4; + value = (*sp >> shift) & 0xf; + *dp = (png_byte)(value | (value << 4)); + if (shift == 4) + { + shift = 0; + sp--; + } + else + shift = 4; - dp--; + dp--; + } + break; } - break; } + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_info->width; } - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_info->width; - } - if (row_info->color_type == PNG_COLOR_TYPE_GRAY && trans_value) - { - if (row_info->bit_depth == 8) - { - sp = row + (png_size_t)row_info->width - 1; - dp = row + (png_size_t)(row_info->width << 1) - 1; - for (i = 0; i < row_info->width; i++) - { - if (*sp == trans_value->gray) - *dp-- = 0; - else - *dp-- = 0xff; - *dp-- = *sp--; - } - } - else if (row_info->bit_depth == 16) + + if (trans_value) { - sp = row + (png_size_t)row_info->rowbytes - 1; - dp = row + (png_size_t)(row_info->rowbytes << 1) - 1; - for (i = 0; i < row_info->width; i++) + if (row_info->bit_depth == 8) { - if (((png_uint_16)*(sp) | - ((png_uint_16)*(sp - 1) << 8)) == trans_value->gray) + sp = row + (png_size_t)row_info->width - 1; + dp = row + (png_size_t)(row_info->width << 1) - 1; + for (i = 0; i < row_info->width; i++) { - *dp-- = 0; - *dp-- = 0; + if (*sp == gray) + *dp-- = 0; + else + *dp-- = 0xff; + *dp-- = *sp--; } - else + } + else if (row_info->bit_depth == 16) + { + sp = row + (png_size_t)row_info->rowbytes - 1; + dp = row + (png_size_t)(row_info->rowbytes << 1) - 1; + for (i = 0; i < row_info->width; i++) { - *dp-- = 0xff; - *dp-- = 0xff; + if (((png_uint_16)*(sp) | + ((png_uint_16)*(sp - 1) << 8)) == gray) + { + *dp-- = 0; + *dp-- = 0; + } + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + *dp-- = *sp--; + *dp-- = *sp--; } - *dp-- = *sp--; - *dp-- = *sp--; } + row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + row_info->channels = 2; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); + row_info->rowbytes = + ((row_info->width * row_info->pixel_depth) >> 3); } - row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - row_info->channels = 2; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); - row_info->rowbytes = - ((row_info->width * row_info->pixel_depth) >> 3); } else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value) { @@ -2742,7 +2780,7 @@ png_build_gamma_table(png_structp png_ptr) g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma); - png_ptr->gamma_table = (png_bytep)png_large_malloc(png_ptr, + png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); for (i = 0; i < 256; i++) @@ -2755,7 +2793,7 @@ png_build_gamma_table(png_structp png_ptr) { g = 1.0 / (png_ptr->gamma); - png_ptr->gamma_to_1 = (png_bytep)png_large_malloc(png_ptr, + png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); for (i = 0; i < 256; i++) @@ -2766,7 +2804,7 @@ png_build_gamma_table(png_structp png_ptr) g = 1.0 / (png_ptr->display_gamma); - png_ptr->gamma_from_1 = (png_bytep)png_large_malloc(png_ptr, + png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, (png_uint_32)256); for (i = 0; i < 256; i++) @@ -2818,7 +2856,7 @@ png_build_gamma_table(png_structp png_ptr) g = 1.0 / (png_ptr->gamma * png_ptr->display_gamma); - png_ptr->gamma_16_table = (png_uint_16pp)png_large_malloc(png_ptr, + png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, num * sizeof (png_uint_16p )); if ((png_ptr->transformations & PNG_16_TO_8) && @@ -2829,7 +2867,7 @@ png_build_gamma_table(png_structp png_ptr) for (i = 0; i < num; i++) { - png_ptr->gamma_16_table[i] = (png_uint_16p)png_large_malloc(png_ptr, + png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, 256 * sizeof (png_uint_16)); } @@ -2860,7 +2898,7 @@ png_build_gamma_table(png_structp png_ptr) { for (i = 0; i < num; i++) { - png_ptr->gamma_16_table[i] = (png_uint_16p)png_large_malloc(png_ptr, + png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, 256 * sizeof (png_uint_16)); ig = (((png_uint_32)i * @@ -2878,12 +2916,12 @@ png_build_gamma_table(png_structp png_ptr) { g = 1.0 / (png_ptr->gamma); - png_ptr->gamma_16_to_1 = (png_uint_16pp)png_large_malloc(png_ptr, + png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, num * sizeof (png_uint_16p )); for (i = 0; i < num; i++) { - png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_large_malloc(png_ptr, + png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, 256 * sizeof (png_uint_16)); ig = (((png_uint_32)i * @@ -2897,12 +2935,12 @@ png_build_gamma_table(png_structp png_ptr) } g = 1.0 / (png_ptr->display_gamma); - png_ptr->gamma_16_from_1 = (png_uint_16pp)png_large_malloc(png_ptr, + png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, num * sizeof (png_uint_16p)); for (i = 0; i < num; i++) { - png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_large_malloc(png_ptr, + png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, 256 * sizeof (png_uint_16)); ig = (((png_uint_32)i * |