diff options
author | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2009-10-29 23:47:05 -0500 |
---|---|---|
committer | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2009-10-29 23:47:05 -0500 |
commit | 4b14b35208b3777ec138377bc347d48f7d7cb5d6 (patch) | |
tree | 24bb170cd5a4765c2327a7162e8af9bfbe641c77 /pngrtran.c | |
parent | bc2ab12f99f4def34b8b510870c54bccb652b08d (diff) | |
download | libpng-4b14b35208b3777ec138377bc347d48f7d7cb5d6.tar.gz |
[master] Ported functions from libpng-1.4.0rc01:
png_calloc(), png_get_io_state(),
png_get_io_chunk_name(), png_set_premultiply_alpha, and
png_do_read_premultiply_alpha().
Diffstat (limited to 'pngrtran.c')
-rw-r--r-- | pngrtran.c | 156 |
1 files changed, 139 insertions, 17 deletions
diff --git a/pngrtran.c b/pngrtran.c index 2af37fd60..296993f84 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -140,6 +140,22 @@ png_set_strip_alpha(png_structp png_ptr) } #endif +#ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED +void PNGAPI +png_set_premultiply_alpha(png_structp png_ptr) +{ + png_debug(1, "in png_set_premultiply_alpha"); + + if(png_ptr == NULL) + return; + png_ptr->transformations |= + (PNG_PREMULTIPLY_ALPHA | PNG_EXPAND_tRNS); + png_ptr->transformations |= + PNG_EXPAND; /* This shouldn't be necessary */ + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} +#endif + #ifdef PNG_READ_DITHER_SUPPORTED /* Dither file to 8 bit. Supply a palette, the current number * of elements in the palette, the maximum number of elements @@ -335,9 +351,8 @@ png_set_dither(png_structp png_ptr, png_colorp palette, png_ptr->palette_to_index[i] = (png_byte)i; } - hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * + hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * png_sizeof(png_dsortp))); - png_memset(hash, 0, 769 * png_sizeof(png_dsortp)); num_new_palette = num_palette; @@ -483,10 +498,9 @@ png_set_dither(png_structp png_ptr, png_colorp palette, 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_ptr->palette_lookup = (png_bytep )png_calloc(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))); @@ -1437,6 +1451,11 @@ png_do_read_transformations(png_structp png_ptr) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif +#ifdef 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); +#endif + #ifdef PNG_READ_BACKGROUND_SUPPORTED if ((png_ptr->transformations & PNG_BACKGROUND) && ((png_ptr->num_trans != 0 ) || @@ -1466,11 +1485,6 @@ png_do_read_transformations(png_structp png_ptr) png_ptr->gamma_shift); #endif -#ifdef 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); -#endif - #ifdef PNG_READ_DITHER_SUPPORTED if (png_ptr->transformations & PNG_DITHER) { @@ -1520,6 +1534,12 @@ png_do_read_transformations(png_structp png_ptr) (png_uint_32)png_ptr->filler, png_ptr->flags); #endif +#ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED + if (png_ptr->transformations & PNG_PREMULTIPLY_ALPHA) + png_do_read_premultiply_alpha(&(png_ptr->row_info), + png_ptr->row_buf + 1); +#endif + #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED if (png_ptr->transformations & PNG_INVERT_ALPHA) png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -2023,6 +2043,85 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) } #endif +#ifdef PNG_READ_PREMULTIPLY_ALPHA_SUPPORTED +void /* PRIVATE */ +png_do_read_premultiply_alpha(png_row_infop row_info, png_bytep row) +{ + png_debug(1, "in png_do_read_premultiply_alpha"); + + { + png_uint_32 row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + /* This premultiplies the pixels with the alpha channel in RGBA */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_16 a = 0; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + a = *(--sp); --dp; + + *(--dp) = (*(--sp) * a) / 255; + *(--dp) = (*(--sp) * a) / 255; + *(--dp) = (*(--sp) * a) / 255; + } + } + /* This premultiplies the pixels with the alpha channel in RRGGBBAA */ + else + { + png_uint_16p sp = (png_uint_16p)(row + row_info->rowbytes); + png_uint_16p dp = sp; + png_uint_32 a = 0; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + a = *(--sp); --dp; + *(--dp) = (png_uint_16) ((*(--sp) * a) / 65535); + *(--dp) = (png_uint_16) ((*(--sp) * a) / 65535); + *(--dp) = (png_uint_16) ((*(--sp) * a) / 65535); + } + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This premultiplies the pixels with the alpha channel in GA */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_16 a = 0; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + a = *(--sp); --dp; + *(--dp) = (*(--sp) * a) / 255; + } + } + /* This premultiplies the pixels with the alpha channel in GGAA */ + else + { + png_uint_16p sp = (png_uint_16p) (row + row_info->rowbytes); + png_uint_16p dp = sp; + png_uint_32 a = 0; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + a = *(--sp); --dp; + *(--dp) = (png_uint_16) ((*(--sp) * a) / 65535); + } + } + } + } +} +#endif + #ifdef PNG_READ_FILLER_SUPPORTED /* Add filler channel if we have RGB color */ void /* PRIVATE */ @@ -4129,6 +4228,33 @@ static PNG_CONST int png_gamma_shift[] = * tables, we don't make a full table if we are reducing to 8-bit in * the future. Note also how the gamma_16 tables are segmented so that * we don't need to allocate > 64K chunks for a full 16-bit table. + * + * See the PNG extensions document for an integer algorithm for creating + * the gamma tables. Maybe we will implement that here someday. + * + * We should only reach this point if + * + * the file_gamma is known (i.e., the gAMA or sRGB chunk is present, + * or the application has provided a file_gamma) + * + * AND + * { + * the screen_gamma is known + * OR + * + * RGB_to_gray transformation is being performed + * } + * + * AND + * { + * the screen_gamma is different from the reciprocal of the + * file_gamma by more than the specified threshold + * + * OR + * + * a background color has been specified and the file_gamma + * and screen_gamma are not 1.0, within the specified threshold. + * } */ void /* PRIVATE */ @@ -4240,9 +4366,8 @@ png_build_gamma_table(png_structp png_ptr) else g = 1.0; - png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, + png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr, (png_uint_32)(num * png_sizeof(png_uint_16p))); - png_memset(png_ptr->gamma_16_table, 0, num * png_sizeof(png_uint_16p)); if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) { @@ -4302,9 +4427,8 @@ png_build_gamma_table(png_structp png_ptr) g = 1.0 / (png_ptr->gamma); - png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, + png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr, (png_uint_32)(num * png_sizeof(png_uint_16p ))); - png_memset(png_ptr->gamma_16_to_1, 0, num * png_sizeof(png_uint_16p)); for (i = 0; i < num; i++) { @@ -4327,10 +4451,8 @@ png_build_gamma_table(png_structp png_ptr) else g = png_ptr->gamma; /* Probably doing rgb_to_gray */ - png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, + png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr, (png_uint_32)(num * png_sizeof(png_uint_16p))); - png_memset(png_ptr->gamma_16_from_1, 0, - num * png_sizeof(png_uint_16p)); for (i = 0; i < num; i++) { |