X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fdll%2F3rdparty%2Flibpng%2Fpngrtran.c;h=e233178863950ff5a8fcee91623f42b8aebdb171;hp=064d92b7e44967f9acc720338e3b5192a6e44f9c;hb=66d24776ffe0b7c6c9bd4cb24dde88ecaf537965;hpb=9f24fbfec9b4f6aeba383d4ac148cecd969deb39 diff --git a/reactos/dll/3rdparty/libpng/pngrtran.c b/reactos/dll/3rdparty/libpng/pngrtran.c index 064d92b7e44..e2331788639 100644 --- a/reactos/dll/3rdparty/libpng/pngrtran.c +++ b/reactos/dll/3rdparty/libpng/pngrtran.c @@ -1,8 +1,8 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.5.14 [January 24, 2013] - * Copyright (c) 1998-2013 Glenn Randers-Pehrson + * Last changed in libpng 1.6.19 [November 12, 2015] + * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -22,7 +22,7 @@ /* Set the action on getting a CRC error for an ancillary or critical chunk. */ void PNGAPI -png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) +png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) { png_debug(1, "in png_set_crc_action"); @@ -88,16 +88,47 @@ png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) } } +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +/* Is it OK to set a transformation now? Only if png_start_read_image or + * png_read_update_info have not been called. It is not necessary for the IHDR + * to have been read in all cases; the need_IHDR parameter allows for this + * check too. + */ +static int +png_rtran_ok(png_structrp png_ptr, int need_IHDR) +{ + if (png_ptr != NULL) + { + if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) + png_app_error(png_ptr, + "invalid after png_start_read_image or png_read_update_info"); + + else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) + png_app_error(png_ptr, "invalid before the PNG header has been read"); + + else + { + /* Turn on failure to initialize correctly for all transforms. */ + png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; + + return 1; /* Ok */ + } + } + + return 0; /* no png_error possible! */ +} +#endif + #ifdef PNG_READ_BACKGROUND_SUPPORTED /* Handle alpha and tRNS via a background color */ void PNGFAPI -png_set_background_fixed(png_structp png_ptr, +png_set_background_fixed(png_structrp png_ptr, png_const_color_16p background_color, int background_gamma_code, int need_expand, png_fixed_point background_gamma) { png_debug(1, "in png_set_background_fixed"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL) return; if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) @@ -110,11 +141,10 @@ png_set_background_fixed(png_structp png_ptr, png_ptr->transformations &= ~PNG_ENCODE_ALPHA; png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - png_memcpy(&(png_ptr->background), background_color, - png_sizeof(png_color_16)); + png_ptr->background = *background_color; png_ptr->background_gamma = background_gamma; png_ptr->background_gamma_type = (png_byte)(background_gamma_code); - if (need_expand) + if (need_expand != 0) png_ptr->transformations |= PNG_BACKGROUND_EXPAND; else png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; @@ -122,7 +152,7 @@ png_set_background_fixed(png_structp png_ptr, # ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI -png_set_background(png_structp png_ptr, +png_set_background(png_structrp png_ptr, png_const_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma) { @@ -138,11 +168,11 @@ png_set_background(png_structp png_ptr, */ #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED void PNGAPI -png_set_scale_16(png_structp png_ptr) +png_set_scale_16(png_structrp png_ptr) { png_debug(1, "in png_set_scale_16"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= PNG_SCALE_16_TO_8; @@ -152,11 +182,11 @@ png_set_scale_16(png_structp png_ptr) #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED /* Chop 16-bit depth files to 8-bit depth */ void PNGAPI -png_set_strip_16(png_structp png_ptr) +png_set_strip_16(png_structrp png_ptr) { png_debug(1, "in png_set_strip_16"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= PNG_16_TO_8; @@ -165,11 +195,11 @@ png_set_strip_16(png_structp png_ptr) #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED void PNGAPI -png_set_strip_alpha(png_structp png_ptr) +png_set_strip_alpha(png_structrp png_ptr) { png_debug(1, "in png_set_strip_alpha"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= PNG_STRIP_ALPHA; @@ -178,7 +208,7 @@ png_set_strip_alpha(png_structp png_ptr) #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) static png_fixed_point -translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, +translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, int is_screen) { /* Check for flag values. The main reason for having the old Mac value as a @@ -194,8 +224,10 @@ translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, */ # ifdef PNG_READ_sRGB_SUPPORTED png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; +# else + PNG_UNUSED(png_ptr) # endif - if (is_screen) + if (is_screen != 0) output_gamma = PNG_GAMMA_sRGB; else output_gamma = PNG_GAMMA_sRGB_INVERSE; @@ -204,7 +236,7 @@ translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, else if (output_gamma == PNG_GAMMA_MAC_18 || output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) { - if (is_screen) + if (is_screen != 0) output_gamma = PNG_GAMMA_MAC_OLD; else output_gamma = PNG_GAMMA_MAC_INVERSE; @@ -215,7 +247,7 @@ translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma, # ifdef PNG_FLOATING_POINT_SUPPORTED static png_fixed_point -convert_gamma_value(png_structp png_ptr, double output_gamma) +convert_gamma_value(png_structrp png_ptr, double output_gamma) { /* The following silently ignores cases where fixed point (times 100,000) * gamma values are passed to the floating point API. This is safe and it @@ -240,7 +272,7 @@ convert_gamma_value(png_structp png_ptr, double output_gamma) #ifdef PNG_READ_ALPHA_MODE_SUPPORTED void PNGFAPI -png_set_alpha_mode_fixed(png_structp png_ptr, int mode, +png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, png_fixed_point output_gamma) { int compose = 0; @@ -248,7 +280,7 @@ png_set_alpha_mode_fixed(png_structp png_ptr, int mode, png_debug(1, "in png_set_alpha_mode"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); @@ -320,8 +352,11 @@ png_set_alpha_mode_fixed(png_structp png_ptr, int mode, * the side effect that the gamma in a second call to png_set_alpha_mode will * be ignored.) */ - if (png_ptr->gamma == 0) - png_ptr->gamma = file_gamma; + if (png_ptr->colorspace.gamma == 0) + { + png_ptr->colorspace.gamma = file_gamma; + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; + } /* But always set the output gamma: */ png_ptr->screen_gamma = output_gamma; @@ -329,28 +364,25 @@ png_set_alpha_mode_fixed(png_structp png_ptr, int mode, /* Finally, if pre-multiplying, set the background fields to achieve the * desired result. */ - if (compose) + if (compose != 0) { /* And obtain alpha pre-multiplication by composing on black: */ - png_memset(&png_ptr->background, 0, sizeof png_ptr->background); - png_ptr->background_gamma = png_ptr->gamma; /* just in case */ + memset(&png_ptr->background, 0, (sizeof png_ptr->background)); + png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; - if (png_ptr->transformations & PNG_COMPOSE) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) png_error(png_ptr, "conflicting calls to set alpha mode and background"); png_ptr->transformations |= PNG_COMPOSE; } - - /* New API, make sure apps call the correct initializers: */ - png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; } # ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI -png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) +png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) { png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, output_gamma)); @@ -362,7 +394,7 @@ png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) /* Dither file to 8-bit. Supply a palette, the current number * of elements in the palette, the maximum number of elements * allowed, and a histogram if possible. If the current number - * of colors is greater then the maximum number, the palette will be + * of colors is greater than the maximum number, the palette will be * modified to fit in the maximum number. "full_quantize" indicates * whether we need a quantizing cube set up for RGB images, or if we * simply are reducing the number of colors in a paletted image. @@ -370,31 +402,31 @@ png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma) typedef struct png_dsort_struct { - struct png_dsort_struct FAR * next; + struct png_dsort_struct * next; png_byte left; png_byte right; } png_dsort; -typedef png_dsort FAR * png_dsortp; -typedef png_dsort FAR * FAR * png_dsortpp; +typedef png_dsort * png_dsortp; +typedef png_dsort * * png_dsortpp; void PNGAPI -png_set_quantize(png_structp png_ptr, png_colorp palette, +png_set_quantize(png_structrp png_ptr, png_colorp palette, int num_palette, int maximum_colors, png_const_uint_16p histogram, int full_quantize) { png_debug(1, "in png_set_quantize"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= PNG_QUANTIZE; - if (!full_quantize) + if (full_quantize == 0) { int i; png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * (sizeof (png_byte)))); for (i = 0; i < num_palette; i++) png_ptr->quantize_index[i] = (png_byte)i; } @@ -411,7 +443,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, /* Initialize an array to sort colors */ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * (sizeof (png_byte)))); /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) @@ -444,12 +476,12 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, } } - if (done) + if (done != 0) break; } /* Swap the palette around, and set up a table, if necessary */ - if (full_quantize) + if (full_quantize != 0) { int j = num_palette; @@ -545,9 +577,9 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, /* Initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * (sizeof (png_byte)))); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * (sizeof (png_byte)))); /* Initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -557,7 +589,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, } hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * - png_sizeof(png_dsortp))); + (sizeof (png_dsortp)))); num_new_palette = num_palette; @@ -587,7 +619,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, { t = (png_dsortp)png_malloc_warn(png_ptr, - (png_uint_32)(png_sizeof(png_dsort))); + (png_uint_32)(sizeof (png_dsort))); if (t == NULL) break; @@ -632,7 +664,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, num_new_palette--; palette[png_ptr->index_to_palette[j]] = palette[num_new_palette]; - if (!full_quantize) + if (full_quantize == 0) { int k; @@ -700,7 +732,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, } png_ptr->num_palette = (png_uint_16)num_palette; - if (full_quantize) + if (full_quantize != 0) { int i; png_bytep distance; @@ -712,12 +744,12 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, png_size_t num_entries = ((png_size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_uint_32)(num_entries * png_sizeof(png_byte))); + (png_uint_32)(num_entries * (sizeof (png_byte)))); distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * - png_sizeof(png_byte))); + (sizeof (png_byte)))); - png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); + memset(distance, 0xff, num_entries * (sizeof (png_byte))); for (i = 0; i < num_palette; i++) { @@ -762,23 +794,22 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, png_free(png_ptr, distance); } } -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ +#endif /* READ_QUANTIZE */ #ifdef PNG_READ_GAMMA_SUPPORTED void PNGFAPI -png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, +png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, png_fixed_point file_gamma) { png_debug(1, "in png_set_gamma_fixed"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; /* New in libpng-1.5.4 - reserve particular negative values as flags. */ scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); -#if PNG_LIBPNG_VER >= 10600 /* Checking the gamma values for being >0 was added in 1.5.4 along with the * premultiplied alpha support; this actually hides an undocumented feature * of the previous implementation which allowed gamma processing to be @@ -787,31 +818,32 @@ png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, * accept '0' for the gamma value it takes, because it isn't always used. * * Since this is an API change (albeit a very minor one that removes an - * undocumented API feature) it will not be made until libpng-1.6.0. + * undocumented API feature) the following checks were only enabled in + * libpng-1.6.0. */ if (file_gamma <= 0) png_error(png_ptr, "invalid file gamma in png_set_gamma"); if (scrn_gamma <= 0) png_error(png_ptr, "invalid screen gamma in png_set_gamma"); -#endif /* Set the gamma values unconditionally - this overrides the value in the PNG * file if a gAMA chunk was present. png_set_alpha_mode provides a * different, easier, way to default the file gamma. */ - png_ptr->gamma = file_gamma; + png_ptr->colorspace.gamma = file_gamma; + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; png_ptr->screen_gamma = scrn_gamma; } # ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI -png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) { png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), convert_gamma_value(png_ptr, file_gamma)); } -# endif /* FLOATING_POINT_SUPPORTED */ +# endif /* FLOATING_POINT */ #endif /* READ_GAMMA */ #ifdef PNG_READ_EXPAND_SUPPORTED @@ -820,15 +852,14 @@ png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) * to alpha channels. */ void PNGAPI -png_set_expand(png_structp png_ptr) +png_set_expand(png_structrp png_ptr) { png_debug(1, "in png_set_expand"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } /* GRR 19990627: the following three functions currently are identical @@ -851,90 +882,85 @@ png_set_expand(png_structp png_ptr) /* Expand paletted images to RGB. */ void PNGAPI -png_set_palette_to_rgb(png_structp png_ptr) +png_set_palette_to_rgb(png_structrp png_ptr) { png_debug(1, "in png_set_palette_to_rgb"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } /* Expand grayscale images of less than 8-bit depth to 8 bits. */ void PNGAPI -png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) +png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) { png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= PNG_EXPAND; - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } - - /* Expand tRNS chunks to alpha channels. */ void PNGAPI -png_set_tRNS_to_alpha(png_structp png_ptr) +png_set_tRNS_to_alpha(png_structrp png_ptr) { png_debug(1, "in png_set_tRNS_to_alpha"); + if (png_rtran_ok(png_ptr, 0) == 0) + return; + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } -#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ +#endif /* READ_EXPAND */ #ifdef PNG_READ_EXPAND_16_SUPPORTED /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise * it may not work correctly.) */ void PNGAPI -png_set_expand_16(png_structp png_ptr) +png_set_expand_16(png_structrp png_ptr) { png_debug(1, "in png_set_expand_16"); - if (png_ptr == NULL) + if (png_rtran_ok(png_ptr, 0) == 0) return; png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - - /* New API, make sure apps call the correct initializers: */ - png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; } #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED void PNGAPI -png_set_gray_to_rgb(png_structp png_ptr) +png_set_gray_to_rgb(png_structrp png_ptr) { png_debug(1, "in png_set_gray_to_rgb"); - if (png_ptr != NULL) - { - /* Because rgb must be 8 bits or more: */ - png_set_expand_gray_1_2_4_to_8(png_ptr); - png_ptr->transformations |= PNG_GRAY_TO_RGB; - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - } + if (png_rtran_ok(png_ptr, 0) == 0) + return; + + /* Because rgb must be 8 bits or more: */ + png_set_expand_gray_1_2_4_to_8(png_ptr); + png_ptr->transformations |= PNG_GRAY_TO_RGB; } #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED void PNGFAPI -png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, +png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, png_fixed_point red, png_fixed_point green) { png_debug(1, "in png_set_rgb_to_gray"); - if (png_ptr == NULL) + /* Need the IHDR here because of the check on color_type below. */ + /* TODO: fix this */ + if (png_rtran_ok(png_ptr, 1) == 0) return; - switch(error_action) + switch (error_action) { case PNG_ERROR_ACTION_NONE: png_ptr->transformations |= PNG_RGB_TO_GRAY; @@ -950,17 +976,20 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, default: png_error(png_ptr, "invalid error action to rgb_to_gray"); - break; } + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) #ifdef PNG_READ_EXPAND_SUPPORTED png_ptr->transformations |= PNG_EXPAND; #else { - png_warning(png_ptr, + /* Make this an error in 1.6 because otherwise the application may assume + * that it just worked and get a memory overwrite. + */ + png_error(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); - png_ptr->transformations &= ~PNG_RGB_TO_GRAY; + /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ } #endif { @@ -969,7 +998,7 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, png_uint_16 red_int, green_int; /* NOTE: this calculation does not round, but this behavior is retained - * for consistency, the inaccuracy is very small. The code here always + * for consistency; the inaccuracy is very small. The code here always * overwrites the coefficients, regardless of whether they have been * defaulted or set already. */ @@ -984,7 +1013,7 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, else { if (red >= 0 && green >= 0) - png_warning(png_ptr, + png_app_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); /* Use the defaults, from the cHRM chunk if set, else the historical @@ -1010,31 +1039,25 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, */ void PNGAPI -png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, +png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, double green) { - if (png_ptr == NULL) - return; - png_set_rgb_to_gray_fixed(png_ptr, error_action, png_fixed(png_ptr, red, "rgb to gray red coefficient"), png_fixed(png_ptr, green, "rgb to gray green coefficient")); } #endif /* FLOATING POINT */ -#endif +#endif /* RGB_TO_GRAY */ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) void PNGAPI -png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr +png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr read_user_transform_fn) { png_debug(1, "in png_set_read_user_transform_fn"); - if (png_ptr == NULL) - return; - #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED png_ptr->transformations |= PNG_USER_TRANSFORM; png_ptr->read_user_transform_fn = read_user_transform_fn; @@ -1068,13 +1091,13 @@ png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) * the palette. */ -/*For the moment 'png_init_palette_transformations' and +/* For the moment 'png_init_palette_transformations' and * 'png_init_rgb_transformations' only do some flag canceling optimizations. * The intent is that these two routines should have palette or rgb operations * extracted from 'png_init_read_transformations'. */ static void /* PRIVATE */ -png_init_palette_transformations(png_structp png_ptr) +png_init_palette_transformations(png_structrp png_ptr) { /* Called to handle the (input) palette case. In png_do_read_transformations * the first step is to expand the palette if requested, so this code must @@ -1093,25 +1116,31 @@ png_init_palette_transformations(png_structp png_ptr) /* Ignore if all the entries are opaque (unlikely!) */ for (i=0; inum_trans; ++i) + { if (png_ptr->trans_alpha[i] == 255) continue; else if (png_ptr->trans_alpha[i] == 0) input_has_transparency = 1; else + { + input_has_transparency = 1; input_has_alpha = 1; + break; + } + } } /* If no alpha we can optimize. */ - if (!input_has_alpha) + if (input_has_alpha == 0) { /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA + * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA * and ENCODE_ALPHA are irrelevant. */ png_ptr->transformations &= ~PNG_ENCODE_ALPHA; png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - if (!input_has_transparency) + if (input_has_transparency == 0) png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); } @@ -1124,8 +1153,8 @@ png_init_palette_transformations(png_structp png_ptr) /* The following code cannot be entered in the alpha pre-multiplication case * because PNG_BACKGROUND_EXPAND is cancelled below. */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - (png_ptr->transformations & PNG_EXPAND)) + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && + (png_ptr->transformations & PNG_EXPAND) != 0) { { png_ptr->background.red = @@ -1136,9 +1165,9 @@ png_init_palette_transformations(png_structp png_ptr) png_ptr->palette[png_ptr->background.index].blue; #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) { - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) { /* Invert the alpha channel (in tRNS) unless the pixels are * going to be expanded, in which case leave it for later @@ -1150,14 +1179,14 @@ png_init_palette_transformations(png_structp png_ptr) png_ptr->trans_alpha[i]); } } -#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ +#endif /* READ_INVERT_ALPHA */ } } /* background expand and (therefore) no alpha association. */ -#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ +#endif /* READ_EXPAND && READ_BACKGROUND */ } static void /* PRIVATE */ -png_init_rgb_transformations(png_structp png_ptr) +png_init_rgb_transformations(png_structrp png_ptr) { /* Added to libpng-1.5.4: check the color type to determine whether there * is any alpha or transparency in the image and simply cancel the @@ -1167,10 +1196,10 @@ png_init_rgb_transformations(png_structp png_ptr) int input_has_transparency = png_ptr->num_trans > 0; /* If no alpha we can optimize. */ - if (!input_has_alpha) + if (input_has_alpha == 0) { /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA + * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA * and ENCODE_ALPHA are irrelevant. */ # ifdef PNG_READ_ALPHA_MODE_SUPPORTED @@ -1178,7 +1207,7 @@ png_init_rgb_transformations(png_structp png_ptr) png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; # endif - if (!input_has_transparency) + if (input_has_transparency == 0) png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); } @@ -1191,9 +1220,9 @@ png_init_rgb_transformations(png_structp png_ptr) /* The following code cannot be entered in the alpha pre-multiplication case * because PNG_BACKGROUND_EXPAND is cancelled below. */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - (png_ptr->transformations & PNG_EXPAND) && - !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && + (png_ptr->transformations & PNG_EXPAND) != 0 && + (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* i.e., GRAY or GRAY_ALPHA */ { { @@ -1221,7 +1250,7 @@ png_init_rgb_transformations(png_structp png_ptr) default: case 8: - /* FALL THROUGH (already 8 bits) */ + /* FALL THROUGH (Already 8 bits) */ case 16: /* Already a full 16 bits */ @@ -1231,18 +1260,18 @@ png_init_rgb_transformations(png_structp png_ptr) png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = (png_uint_16)gray; - if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) { png_ptr->trans_color.red = png_ptr->trans_color.green = png_ptr->trans_color.blue = (png_uint_16)trans_gray; } } } /* background expand and (therefore) no alpha association. */ -#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ +#endif /* READ_EXPAND && READ_BACKGROUND */ } void /* PRIVATE */ -png_init_read_transformations(png_structp png_ptr) +png_init_read_transformations(png_structrp png_ptr) { png_debug(1, "in png_init_read_transformations"); @@ -1267,17 +1296,17 @@ png_init_read_transformations(png_structp png_ptr) */ int gamma_correction = 0; - if (png_ptr->gamma != 0) /* has been set */ + if (png_ptr->colorspace.gamma != 0) /* has been set */ { if (png_ptr->screen_gamma != 0) /* screen set too */ - gamma_correction = png_gamma_threshold(png_ptr->gamma, + gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, png_ptr->screen_gamma); else /* Assume the output matches the input; a long time default behavior * of libpng, although the standard has nothing to say about this. */ - png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma); + png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); } else if (png_ptr->screen_gamma != 0) @@ -1286,7 +1315,7 @@ png_init_read_transformations(png_structp png_ptr) * png_set_alpha_mode (even if the alpha handling mode isn't required * or isn't changed from the default.) */ - png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma); + png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); else /* neither are set */ /* Just in case the following prevents any processing - file and screen @@ -1294,7 +1323,10 @@ png_init_read_transformations(png_structp png_ptr) * third gamma value other than png_set_background with 'UNIQUE', and, * prior to 1.5.4 */ - png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1; + png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; + + /* We have a gamma value now. */ + png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; /* Now turn the gamma transformation on or off as appropriate. Notice * that PNG_GAMMA just refers to the file->screen correction. Alpha @@ -1304,7 +1336,7 @@ png_init_read_transformations(png_structp png_ptr) * the code immediately below if the transform can be handled outside the * row loop. */ - if (gamma_correction) + if (gamma_correction != 0) png_ptr->transformations |= PNG_GAMMA; else @@ -1313,7 +1345,7 @@ png_init_read_transformations(png_structp png_ptr) #endif /* Certain transformations have the effect of preventing other - * transformations that happen afterward in png_do_read_transformations, + * transformations that happen afterward in png_do_read_transformations; * resolve the interdependencies here. From the code of * png_do_read_transformations the order is: * @@ -1331,19 +1363,19 @@ png_init_read_transformations(png_structp png_ptr) * 12) PNG_EXPAND_16 * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY * 14) PNG_INVERT_MONO - * 15) PNG_SHIFT - * 16) PNG_PACK - * 17) PNG_BGR - * 18) PNG_PACKSWAP - * 19) PNG_FILLER (includes PNG_ADD_ALPHA) - * 20) PNG_INVERT_ALPHA + * 15) PNG_INVERT_ALPHA + * 16) PNG_SHIFT + * 17) PNG_PACK + * 18) PNG_BGR + * 19) PNG_PACKSWAP + * 20) PNG_FILLER (includes PNG_ADD_ALPHA) * 21) PNG_SWAP_ALPHA * 22) PNG_SWAP_BYTES * 23) PNG_USER_TRANSFORM [must be last] */ #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - !(png_ptr->transformations & PNG_COMPOSE)) + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) == 0) { /* Stripping the alpha channel happens immediately after the 'expand' * transformations, before all other transformation, so it cancels out @@ -1369,16 +1401,23 @@ png_init_read_transformations(png_structp png_ptr) /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA * settings will have no effect. */ - if (!png_gamma_significant(png_ptr->screen_gamma)) + if (png_gamma_significant(png_ptr->screen_gamma) == 0) { png_ptr->transformations &= ~PNG_ENCODE_ALPHA; png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; } #endif -#if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Make sure the coefficients for the rgb to gray conversion are set + * appropriately. + */ + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + png_colorspace_set_rgb_coefficients(png_ptr); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED +#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) /* Detect gray background and attempt to enable optimization for * gray --> RGB case. * @@ -1394,23 +1433,23 @@ png_init_read_transformations(png_structp png_ptr) * png_set_background, along with the bit depth, then the code has a record * of exactly what color space the background is currently in. */ - if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) { /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if * the file was grayscale the background value is gray. */ - if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) + if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; } - else if (png_ptr->transformations & PNG_COMPOSE) + else if ((png_ptr->transformations & PNG_COMPOSE) != 0) { /* PNG_COMPOSE: png_set_background was called with need_expand false, * so the color is in the color space of the output or png_set_alpha_mode * was called and the color is black. Ignore RGB_TO_GRAY because that * happens before GRAY_TO_RGB. */ - if (png_ptr->transformations & PNG_GRAY_TO_RGB) + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) { if (png_ptr->background.red == png_ptr->background.green && png_ptr->background.red == png_ptr->background.blue) @@ -1420,7 +1459,8 @@ png_init_read_transformations(png_structp png_ptr) } } } -#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */ +#endif /* READ_EXPAND && READ_BACKGROUND */ +#endif /* READ_GRAY_TO_RGB */ /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations * can be performed directly on the palette, and some (such as rgb to gray) @@ -1441,10 +1481,10 @@ png_init_read_transformations(png_structp png_ptr) #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ defined(PNG_READ_EXPAND_16_SUPPORTED) - if ((png_ptr->transformations & PNG_EXPAND_16) && - (png_ptr->transformations & PNG_COMPOSE) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - png_ptr->bit_depth != 16) + if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && + png_ptr->bit_depth != 16) { /* TODO: fix this. Because the expand_16 operation is after the compose * handling the background color must be 8, not 16, bits deep, but the @@ -1456,22 +1496,22 @@ png_init_read_transformations(png_structp png_ptr) * NOTE: this discards the low 16 bits of the user supplied background * color, but until expand_16 works properly there is no choice! */ -# define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16)) +# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) CHOP(png_ptr->background.red); CHOP(png_ptr->background.green); CHOP(png_ptr->background.blue); CHOP(png_ptr->background.gray); # undef CHOP } -#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */ +#endif /* READ_BACKGROUND && READ_EXPAND_16 */ #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) - if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) && - (png_ptr->transformations & PNG_COMPOSE) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - png_ptr->bit_depth == 16) + if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && + png_ptr->bit_depth == 16) { /* On the other hand, if a 16-bit file is to be reduced to 8-bits per * component this will also happen after PNG_COMPOSE and so the background @@ -1514,25 +1554,24 @@ png_init_read_transformations(png_structp png_ptr) * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the * tables. */ - if ((png_ptr->transformations & PNG_GAMMA) - || ((png_ptr->transformations & PNG_RGB_TO_GRAY) - && (png_gamma_significant(png_ptr->gamma) || - png_gamma_significant(png_ptr->screen_gamma))) - || ((png_ptr->transformations & PNG_COMPOSE) - && (png_gamma_significant(png_ptr->gamma) - || png_gamma_significant(png_ptr->screen_gamma) + if ((png_ptr->transformations & PNG_GAMMA) != 0 || + ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && + (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || + png_gamma_significant(png_ptr->screen_gamma) != 0)) || + ((png_ptr->transformations & PNG_COMPOSE) != 0 && + (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || + png_gamma_significant(png_ptr->screen_gamma) != 0 # ifdef PNG_READ_BACKGROUND_SUPPORTED - || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE - && png_gamma_significant(png_ptr->background_gamma)) + || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && + png_gamma_significant(png_ptr->background_gamma) != 0) # endif - )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) - && png_gamma_significant(png_ptr->screen_gamma)) - ) + )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && + png_gamma_significant(png_ptr->screen_gamma) != 0)) { png_build_gamma_table(png_ptr, png_ptr->bit_depth); #ifdef PNG_READ_BACKGROUND_SUPPORTED - if (png_ptr->transformations & PNG_COMPOSE) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) { /* Issue a warning about this combination: because RGB_TO_GRAY is * optimized to do the gamma transform if present yet do_background has @@ -1540,11 +1579,11 @@ png_init_read_transformations(png_structp png_ptr) * double-gamma-correction happens. This is true in all versions of * libpng to date. */ - if (png_ptr->transformations & PNG_RGB_TO_GRAY) + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) png_warning(png_ptr, "libpng does not support gamma+background+rgb_to_gray"); - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) { /* We don't get to here unless there is a tRNS chunk with non-opaque * entries - see the checking code at the start of this function. @@ -1576,8 +1615,8 @@ png_init_read_transformations(png_structp png_ptr) break; case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->gamma); - gs = png_reciprocal2(png_ptr->gamma, + g = png_reciprocal(png_ptr->colorspace.gamma); + gs = png_reciprocal2(png_ptr->colorspace.gamma, png_ptr->screen_gamma); break; @@ -1592,7 +1631,7 @@ png_init_read_transformations(png_structp png_ptr) break; } - if (png_gamma_significant(gs)) + if (png_gamma_significant(gs) != 0) { back.red = png_gamma_8bit_correct(png_ptr->background.red, gs); @@ -1609,7 +1648,7 @@ png_init_read_transformations(png_structp png_ptr) back.blue = (png_byte)png_ptr->background.blue; } - if (png_gamma_significant(g)) + if (png_gamma_significant(g) != 0) { back_1.red = png_gamma_8bit_correct(png_ptr->background.red, g); @@ -1685,8 +1724,9 @@ png_init_read_transformations(png_structp png_ptr) break; case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->gamma); - gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->colorspace.gamma); + gs = png_reciprocal2(png_ptr->colorspace.gamma, + png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: @@ -1702,11 +1742,11 @@ png_init_read_transformations(png_structp png_ptr) g_sig = png_gamma_significant(g); gs_sig = png_gamma_significant(gs); - if (g_sig) + if (g_sig != 0) png_ptr->background_1.gray = png_gamma_correct(png_ptr, png_ptr->background.gray, g); - if (gs_sig) + if (gs_sig != 0) png_ptr->background.gray = png_gamma_correct(png_ptr, png_ptr->background.gray, gs); @@ -1715,7 +1755,7 @@ png_init_read_transformations(png_structp png_ptr) (png_ptr->background.red != png_ptr->background.gray)) { /* RGB or RGBA with color background */ - if (g_sig) + if (g_sig != 0) { png_ptr->background_1.red = png_gamma_correct(png_ptr, png_ptr->background.red, g); @@ -1727,7 +1767,7 @@ png_init_read_transformations(png_structp png_ptr) png_ptr->background.blue, g); } - if (gs_sig) + if (gs_sig != 0) { png_ptr->background.red = png_gamma_correct(png_ptr, png_ptr->background.red, gs); @@ -1757,7 +1797,7 @@ png_init_read_transformations(png_structp png_ptr) else /* Transformation does not include PNG_BACKGROUND */ -#endif /* PNG_READ_BACKGROUND_SUPPORTED */ +#endif /* READ_BACKGROUND */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ @@ -1787,11 +1827,11 @@ png_init_read_transformations(png_structp png_ptr) #ifdef PNG_READ_BACKGROUND_SUPPORTED else #endif -#endif /* PNG_READ_GAMMA_SUPPORTED */ +#endif /* READ_GAMMA */ #ifdef PNG_READ_BACKGROUND_SUPPORTED /* No GAMMA transformation (see the hanging else 4 lines above) */ - if ((png_ptr->transformations & PNG_COMPOSE) && + if ((png_ptr->transformations & PNG_COMPOSE) != 0 && (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) { int i; @@ -1826,11 +1866,11 @@ png_init_read_transformations(png_structp png_ptr) png_ptr->transformations &= ~PNG_COMPOSE; } -#endif /* PNG_READ_BACKGROUND_SUPPORTED */ +#endif /* READ_BACKGROUND */ #ifdef PNG_READ_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) && - !(png_ptr->transformations & PNG_EXPAND) && + if ((png_ptr->transformations & PNG_SHIFT) != 0 && + (png_ptr->transformations & PNG_EXPAND) == 0 && (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) { int i; @@ -1843,33 +1883,36 @@ png_init_read_transformations(png_structp png_ptr) * the number of significant bits is 0 then no shift is done (this is an * error condition which is silently ignored.) */ - if (shift > 0 && shift < 8) for (i=0; ipalette[i].red; + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].red; - component >>= shift; - png_ptr->palette[i].red = (png_byte)component; - } + component >>= shift; + png_ptr->palette[i].red = (png_byte)component; + } shift = 8 - png_ptr->sig_bit.green; - if (shift > 0 && shift < 8) for (i=0; ipalette[i].green; + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].green; - component >>= shift; - png_ptr->palette[i].green = (png_byte)component; - } + component >>= shift; + png_ptr->palette[i].green = (png_byte)component; + } shift = 8 - png_ptr->sig_bit.blue; - if (shift > 0 && shift < 8) for (i=0; ipalette[i].blue; + if (shift > 0 && shift < 8) + for (i=0; ipalette[i].blue; - component >>= shift; - png_ptr->palette[i].blue = (png_byte)component; - } + component >>= shift; + png_ptr->palette[i].blue = (png_byte)component; + } } -#endif /* PNG_READ_SHIFT_SUPPORTED */ +#endif /* READ_SHIFT */ } /* Modify the info structure to reflect the transformations. The @@ -1877,12 +1920,12 @@ png_init_read_transformations(png_structp png_ptr) * assuming the transformations result in valid PNG data. */ void /* PRIVATE */ -png_read_transform_info(png_structp png_ptr, png_infop info_ptr) +png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) { png_debug(1, "in png_read_transform_info"); #ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) + if ((png_ptr->transformations & PNG_EXPAND) != 0) { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { @@ -1898,12 +1941,15 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) info_ptr->bit_depth = 8; info_ptr->num_trans = 0; + + if (png_ptr->palette == NULL) + png_error (png_ptr, "Palette is NULL in indexed image"); } else { - if (png_ptr->num_trans) + if (png_ptr->num_trans != 0) { - if (png_ptr->transformations & PNG_EXPAND_tRNS) + if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; } if (info_ptr->bit_depth < 8) @@ -1919,7 +1965,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) /* The following is almost certainly wrong unless the background value is in * the screen space! */ - if (png_ptr->transformations & PNG_COMPOSE) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) info_ptr->background = png_ptr->background; #endif @@ -1928,25 +1974,29 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) * however it seems that the code in png_init_read_transformations, which has * been called before this from png_read_update_info->png_read_start_row * sometimes does the gamma transform and cancels the flag. + * + * TODO: this looks wrong; the info_ptr should end up with a gamma equal to + * the screen_gamma value. The following probably results in weirdness if + * the info_ptr is used by the app after the rows have been read. */ - info_ptr->gamma = png_ptr->gamma; + info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; #endif if (info_ptr->bit_depth == 16) { # ifdef PNG_READ_16BIT_SUPPORTED # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_SCALE_16_TO_8) + if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) info_ptr->bit_depth = 8; # endif # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_16_TO_8) + if ((png_ptr->transformations & PNG_16_TO_8) != 0) info_ptr->bit_depth = 8; # endif # else - /* No 16 bit support: force chopping 16-bit input down to 8, in this case + /* No 16-bit support: force chopping 16-bit input down to 8, in this case * the app program can chose if both APIs are available by setting the * correct scaling to use. */ @@ -1967,27 +2017,27 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) CONFIGURATION ERROR: you must enable at least one 16 to 8 method # endif # endif -#endif /* !READ_16BIT_SUPPORTED */ +#endif /* !READ_16BIT */ } #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if (png_ptr->transformations & PNG_GRAY_TO_RGB) + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) info_ptr->color_type = (png_byte)(info_ptr->color_type | PNG_COLOR_MASK_COLOR); #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if (png_ptr->transformations & PNG_RGB_TO_GRAY) + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) info_ptr->color_type = (png_byte)(info_ptr->color_type & ~PNG_COLOR_MASK_COLOR); #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED - if (png_ptr->transformations & PNG_QUANTIZE) + if ((png_ptr->transformations & PNG_QUANTIZE) != 0) { if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && - png_ptr->palette_lookup && info_ptr->bit_depth == 8) + png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) { info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; } @@ -1995,29 +2045,31 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_READ_EXPAND_16_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 && - info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) + if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && + info_ptr->bit_depth == 8 && + info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) { info_ptr->bit_depth = 16; } #endif #ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8)) + if ((png_ptr->transformations & PNG_PACK) != 0 && + (info_ptr->bit_depth < 8)) info_ptr->bit_depth = 8; #endif if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; - else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) + else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) info_ptr->channels = 3; else info_ptr->channels = 1; #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_STRIP_ALPHA) + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) { info_ptr->color_type = (png_byte)(info_ptr->color_type & ~PNG_COLOR_MASK_ALPHA); @@ -2025,30 +2077,30 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) } #endif - if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) + if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) info_ptr->channels++; #ifdef PNG_READ_FILLER_SUPPORTED /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ - if ((png_ptr->transformations & PNG_FILLER) && - ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) + if ((png_ptr->transformations & PNG_FILLER) != 0 && + (info_ptr->color_type == PNG_COLOR_TYPE_RGB || + info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) { info_ptr->channels++; /* If adding a true alpha channel not just filler */ - if (png_ptr->transformations & PNG_ADD_ALPHA) + if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; } #endif #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - if (png_ptr->transformations & PNG_USER_TRANSFORM) + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) { - if (info_ptr->bit_depth < png_ptr->user_transform_depth) + if (png_ptr->user_transform_depth != 0) info_ptr->bit_depth = png_ptr->user_transform_depth; - if (info_ptr->channels < png_ptr->user_transform_channels) + if (png_ptr->user_transform_channels != 0) info_ptr->channels = png_ptr->user_transform_channels; } #endif @@ -2067,442 +2119,146 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_ptr->info_rowbytes = info_ptr->rowbytes; #ifndef PNG_READ_EXPAND_SUPPORTED - if (png_ptr) + if (png_ptr != NULL) return; #endif } -/* Transform the row. The order of transformations is significant, - * and is very touchy. If you add a transformation, take care to - * decide how it fits in with the other transformations here. +#ifdef PNG_READ_PACK_SUPPORTED +/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, + * without changing the actual values. Thus, if you had a row with + * a bit depth of 1, you would end up with bytes that only contained + * the numbers 0 or 1. If you would rather they contain 0 and 255, use + * png_do_shift() after this. */ -void /* PRIVATE */ -png_do_read_transformations(png_structp png_ptr, png_row_infop row_info) +static void +png_do_unpack(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_read_transformations"); - - if (png_ptr->row_buf == NULL) - { - /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this - * error is incredibly rare and incredibly easy to debug without this - * information. - */ - png_error(png_ptr, "NULL row buffer"); - } + png_debug(1, "in png_do_unpack"); - /* The following is debugging; prior to 1.5.4 the code was never compiled in; - * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro - * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for - * selected new APIs to ensure that there is no API change. - */ - if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && - !(png_ptr->flags & PNG_FLAG_ROW_INIT)) + if (row_info->bit_depth < 8) { - /* Application has failed to call either png_read_start_image() or - * png_read_update_info() after setting transforms that expand pixels. - * This check added to libpng-1.2.19 (but not enabled until 1.5.4). - */ - png_error(png_ptr, "Uninitialized row"); - } + png_uint_32 i; + png_uint_32 row_width=row_info->width; -#ifdef PNG_READ_EXPAND_SUPPORTED - if (png_ptr->transformations & PNG_EXPAND) - { - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + switch (row_info->bit_depth) { - png_do_expand_palette(row_info, png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); - } + case 1: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x01); - else - { - if (png_ptr->num_trans && - (png_ptr->transformations & PNG_EXPAND_tRNS)) - png_do_expand(row_info, png_ptr->row_buf + 1, - &(png_ptr->trans_color)); + if (shift == 7) + { + shift = 0; + sp--; + } - else - png_do_expand(row_info, png_ptr->row_buf + 1, - NULL); + else + shift++; + + dp--; + } + break; + } + + case 2: + { + + png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x03); + + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); + png_bytep dp = row + (png_size_t)row_width - 1; + png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + *dp = (png_byte)((*sp >> shift) & 0x0f); + + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift = 4; + + dp--; + } + break; + } + + default: + break; } + row_info->bit_depth = 8; + row_info->pixel_depth = (png_byte)(8 * row_info->channels); + row_info->rowbytes = row_width * row_info->channels; } +} #endif -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - !(png_ptr->transformations & PNG_COMPOSE) && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif +#ifdef PNG_READ_SHIFT_SUPPORTED +/* Reverse the effects of png_do_shift. This routine merely shifts the + * pixels back to their significant bits values. Thus, if you have + * a row of bit depth 8, but only 5 are significant, this will shift + * the values back to 0 through 31. + */ +static void +png_do_unshift(png_row_infop row_info, png_bytep row, + png_const_color_8p sig_bits) +{ + int color_type; -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if (png_ptr->transformations & PNG_RGB_TO_GRAY) + png_debug(1, "in png_do_unshift"); + + /* The palette case has already been handled in the _init routine. */ + color_type = row_info->color_type; + + if (color_type != PNG_COLOR_TYPE_PALETTE) { - int rgb_error = - png_do_rgb_to_gray(png_ptr, row_info, - png_ptr->row_buf + 1); + int shift[4]; + int channels = 0; + int bit_depth = row_info->bit_depth; - if (rgb_error) + if ((color_type & PNG_COLOR_MASK_COLOR) != 0) { - png_ptr->rgb_to_gray_status=1; - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_WARN) - png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + shift[channels++] = bit_depth - sig_bits->red; + shift[channels++] = bit_depth - sig_bits->green; + shift[channels++] = bit_depth - sig_bits->blue; + } - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_ERR) - png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + else + { + shift[channels++] = bit_depth - sig_bits->gray; } - } -#endif -/* From Andreas Dilger e-mail to png-implement, 26 March 1998: - * - * In most cases, the "simple transparency" should be done prior to doing - * gray-to-RGB, or you will have to test 3x as many bytes to check if a - * pixel is transparent. You would also need to make sure that the - * transparency information is upgraded to RGB. - * - * To summarize, the current flow is: - * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite - * with background "in place" if transparent, - * convert to RGB if necessary - * - Gray + alpha -> composite with gray background and remove alpha bytes, - * convert to RGB if necessary - * - * To support RGB backgrounds for gray images we need: - * - Gray + simple transparency -> convert to RGB + simple transparency, - * compare 3 or 6 bytes and composite with - * background "in place" if transparent - * (3x compare/pixel compared to doing - * composite with gray bkgrnd) - * - Gray + alpha -> convert to RGB + alpha, composite with background and - * remove alpha bytes (3x float - * operations/pixel compared with composite - * on gray background) - * - * Greg's change will do this. The reason it wasn't done before is for - * performance, as this increases the per-pixel operations. If we would check - * in advance if the background was gray or RGB, and position the gray-to-RGB - * transform appropriately, then it would save a lot of work/time. - */ - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* If gray -> RGB, do so now only if background is non-gray; else do later - * for performance reasons - */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && - !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) - if (png_ptr->transformations & PNG_COMPOSE) - png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - if ((png_ptr->transformations & PNG_GAMMA) && -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Because RGB_TO_GRAY does the gamma transform. */ - !(png_ptr->transformations & PNG_RGB_TO_GRAY) && -#endif -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) - /* Because PNG_COMPOSE does the gamma transform if there is something to - * do (if there is an alpha channel or transparency.) - */ - !((png_ptr->transformations & PNG_COMPOSE) && - ((png_ptr->num_trans != 0) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && -#endif - /* Because png_init_read_transformations transforms the palette, unless - * RGB_TO_GRAY will do the transform. - */ - (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) - png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) && - (png_ptr->transformations & PNG_COMPOSE) && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && - (row_info->color_type & PNG_COLOR_MASK_ALPHA)) - png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if (png_ptr->transformations & PNG_SCALE_16_TO_8) - png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* There is no harm in doing both of these because only one has any effect, - * by putting the 'scale' option first if the app asks for scale (either by - * calling the API or in a TRANSFORM flag) this is what happens. - */ - if (png_ptr->transformations & PNG_16_TO_8) - png_do_chop(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if (png_ptr->transformations & PNG_QUANTIZE) - { - png_do_quantize(row_info, png_ptr->row_buf + 1, - png_ptr->palette_lookup, png_ptr->quantize_index); - - if (row_info->rowbytes == 0) - png_error(png_ptr, "png_do_quantize returned rowbytes=0"); - } -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - /* Do the expansion now, after all the arithmetic has been done. Notice - * that previous transformations can handle the PNG_EXPAND_16 flag if this - * is efficient (particularly true in the case of gamma correction, where - * better accuracy results faster!) - */ - if (png_ptr->transformations & PNG_EXPAND_16) - png_do_expand_16(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* NOTE: moved here in 1.5.4 (from much later in this list.) */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && - (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_INVERT_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_MONO) - png_do_invert(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED - if (png_ptr->transformations & PNG_SHIFT) - png_do_unshift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if (png_ptr->transformations & PNG_PACK) - png_do_unpack(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Added at libpng-1.5.10 */ - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max >= 0) - png_do_check_palette_indexes(png_ptr, row_info); -#endif - -#ifdef PNG_READ_BGR_SUPPORTED - if (png_ptr->transformations & PNG_BGR) - png_do_bgr(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if (png_ptr->transformations & PNG_PACKSWAP) - png_do_packswap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if (png_ptr->transformations & PNG_FILLER) - png_do_read_filler(row_info, png_ptr->row_buf + 1, - (png_uint_32)png_ptr->filler, png_ptr->flags); -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_INVERT_ALPHA) - png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_ALPHA) - png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_16BIT_SUPPORTED -#ifdef PNG_READ_SWAP_SUPPORTED - if (png_ptr->transformations & PNG_SWAP_BYTES) - png_do_swap(row_info, png_ptr->row_buf + 1); -#endif -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if (png_ptr->transformations & PNG_USER_TRANSFORM) - { - if (png_ptr->read_user_transform_fn != NULL) - (*(png_ptr->read_user_transform_fn)) /* User read transform function */ - (png_ptr, /* png_ptr */ - row_info, /* row_info: */ - /* png_uint_32 width; width of row */ - /* png_size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - if (png_ptr->user_transform_depth) - row_info->bit_depth = png_ptr->user_transform_depth; - - if (png_ptr->user_transform_channels) - row_info->channels = png_ptr->user_transform_channels; -#endif - row_info->pixel_depth = (png_byte)(row_info->bit_depth * - row_info->channels); - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); - } -#endif -} - -#ifdef PNG_READ_PACK_SUPPORTED -/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, - * without changing the actual values. Thus, if you had a row with - * a bit depth of 1, you would end up with bytes that only contained - * the numbers 0 or 1. If you would rather they contain 0 and 255, use - * png_do_shift() after this. - */ -void /* PRIVATE */ -png_do_unpack(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_unpack"); - - if (row_info->bit_depth < 8) - { - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - switch (row_info->bit_depth) - { - case 1: - { - png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); - png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x01); - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - - png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); - png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x03); - - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); - png_bytep dp = row + (png_size_t)row_width - 1; - png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x0f); - - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED -/* Reverse the effects of png_do_shift. This routine merely shifts the - * pixels back to their significant bits values. Thus, if you have - * a row of bit depth 8, but only 5 are significant, this will shift - * the values back to 0 through 31. - */ -void /* PRIVATE */ -png_do_unshift(png_row_infop row_info, png_bytep row, - png_const_color_8p sig_bits) -{ - int color_type; - - png_debug(1, "in png_do_unshift"); - - /* The palette case has already been handled in the _init routine. */ - color_type = row_info->color_type; - - if (color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift[4]; - int channels = 0; - int bit_depth = row_info->bit_depth; - - if (color_type & PNG_COLOR_MASK_COLOR) - { - shift[channels++] = bit_depth - sig_bits->red; - shift[channels++] = bit_depth - sig_bits->green; - shift[channels++] = bit_depth - sig_bits->blue; - } - - else - { - shift[channels++] = bit_depth - sig_bits->gray; - } - - if (color_type & PNG_COLOR_MASK_ALPHA) + if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) { shift[channels++] = bit_depth - sig_bits->alpha; } @@ -2522,7 +2278,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, have_shift = 1; } - if (!have_shift) + if (have_shift == 0) return; } @@ -2600,7 +2356,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, if (++channel >= channels) channel = 0; *bp++ = (png_byte)(value >> 8); - *bp++ = (png_byte)(value & 0xff); + *bp++ = (png_byte)value; } break; } @@ -2612,7 +2368,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED /* Scale rows of bit depth 16 down to 8 accurately */ -void /* PRIVATE */ +static void png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_scale_16_to_8"); @@ -2625,8 +2381,8 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) while (sp < ep) { - /* The input is an array of 16 bit components, these must be scaled to - * 8 bits each. For a 16 bit value V the required value (from the PNG + /* The input is an array of 16-bit components, these must be scaled to + * 8 bits each. For a 16-bit value V the required value (from the PNG * specification) is: * * (V * 255) / 65535 @@ -2647,7 +2403,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) * * The approximate differs from the exact answer only when (vlo-vhi) is * 128; it then gives a correction of +1 when the exact correction is - * 0. This gives 128 errors. The exact answer (correct for all 16 bit + * 0. This gives 128 errors. The exact answer (correct for all 16-bit * input values) is: * * error = (vlo-vhi+128)*65535 >> 24; @@ -2670,7 +2426,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -void /* PRIVATE */ +static void /* Simply discard the low byte. This was the default behavior prior * to libpng-1.5.4. */ @@ -2698,7 +2454,7 @@ png_do_chop(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -void /* PRIVATE */ +static void png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_read_swap_alpha"); @@ -2795,7 +2551,7 @@ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -void /* PRIVATE */ +static void png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) { png_uint_32 row_width; @@ -2897,7 +2653,7 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) #ifdef PNG_READ_FILLER_SUPPORTED /* Add filler channel if we have RGB color */ -void /* PRIVATE */ +static void png_do_read_filler(png_row_infop row_info, png_bytep row, png_uint_32 filler, png_uint_32 flags) { @@ -2905,9 +2661,9 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, png_uint_32 row_width = row_info->width; #ifdef PNG_READ_16BIT_SUPPORTED - png_byte hi_filler = (png_byte)((filler>>8) & 0xff); + png_byte hi_filler = (png_byte)(filler>>8); #endif - png_byte lo_filler = (png_byte)(filler & 0xff); + png_byte lo_filler = (png_byte)filler; png_debug(1, "in png_do_read_filler"); @@ -2916,7 +2672,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from G to GX */ png_bytep sp = row + (png_size_t)row_width; @@ -2951,20 +2707,20 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from GG to GGXX */ png_bytep sp = row + (png_size_t)row_width * 2; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 1; i < row_width; i++) { - *(--dp) = hi_filler; *(--dp) = lo_filler; + *(--dp) = hi_filler; *(--dp) = *(--sp); *(--dp) = *(--sp); } - *(--dp) = hi_filler; *(--dp) = lo_filler; + *(--dp) = hi_filler; row_info->channels = 2; row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; @@ -2979,8 +2735,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, { *(--dp) = *(--sp); *(--dp) = *(--sp); - *(--dp) = hi_filler; *(--dp) = lo_filler; + *(--dp) = hi_filler; } row_info->channels = 2; row_info->pixel_depth = 32; @@ -2993,7 +2749,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from RGB to RGBX */ png_bytep sp = row + (png_size_t)row_width * 3; @@ -3032,15 +2788,15 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { - if (flags & PNG_FLAG_FILLER_AFTER) + if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from RRGGBB to RRGGBBXX */ png_bytep sp = row + (png_size_t)row_width * 6; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 1; i < row_width; i++) { - *(--dp) = hi_filler; *(--dp) = lo_filler; + *(--dp) = hi_filler; *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); @@ -3048,8 +2804,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, *(--dp) = *(--sp); *(--dp) = *(--sp); } - *(--dp) = hi_filler; *(--dp) = lo_filler; + *(--dp) = hi_filler; row_info->channels = 4; row_info->pixel_depth = 64; row_info->rowbytes = row_width * 8; @@ -3068,8 +2824,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, *(--dp) = *(--sp); *(--dp) = *(--sp); *(--dp) = *(--sp); - *(--dp) = hi_filler; *(--dp) = lo_filler; + *(--dp) = hi_filler; } row_info->channels = 4; @@ -3084,7 +2840,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED /* Expand grayscale files to RGB, with or without alpha */ -void /* PRIVATE */ +static void png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) { png_uint_32 i; @@ -3093,7 +2849,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) png_debug(1, "in png_do_gray_to_rgb"); if (row_info->bit_depth >= 8 && - !(row_info->color_type & PNG_COLOR_MASK_COLOR)) + (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) { if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { @@ -3223,16 +2979,16 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) * calculated to make the sum 32768. This will result in different rounding * to that used above. */ -int /* PRIVATE */ -png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) +static int +png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) { int rgb_error = 0; png_debug(1, "in png_do_rgb_to_gray"); - if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && - (row_info->color_type & PNG_COLOR_MASK_COLOR)) + if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && + (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) { PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; @@ -3243,7 +2999,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) if (row_info->bit_depth == 8) { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED /* Notice that gamma to/from 1 are not necessarily inverses (if * there is an overall gamma correction). Prior to 1.5.5 this code * checked the linearized values for equality; this doesn't match @@ -3283,7 +3039,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) *(dp++) = red; } - if (have_alpha) + if (have_alpha != 0) *(dp++) = *(sp++); } } @@ -3312,7 +3068,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) else *(dp++) = red; - if (have_alpha) + if (have_alpha != 0) *(dp++) = *(sp++); } } @@ -3320,7 +3076,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) else /* RGB bit_depth == 16 */ { -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) { png_bytep sp = row; @@ -3330,16 +3086,17 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) for (i = 0; i < row_width; i++) { png_uint_16 red, green, blue, w; + png_byte hi,lo; - red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); if (red == green && red == blue) { if (png_ptr->gamma_16_table != NULL) - w = png_ptr->gamma_16_table[(red&0xff) - >> png_ptr->gamma_shift][red>>8]; + w = png_ptr->gamma_16_table[(red & 0xff) + >> png_ptr->gamma_shift][red >> 8]; else w = red; @@ -3347,16 +3104,16 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) else { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff) >> png_ptr->gamma_shift][red>>8]; png_uint_16 green_1 = - png_ptr->gamma_16_to_1[(green&0xff) >> + png_ptr->gamma_16_to_1[(green & 0xff) >> png_ptr->gamma_shift][green>>8]; - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff) >> png_ptr->gamma_shift][blue>>8]; png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 + bc*blue_1 + 16384)>>15); - w = png_ptr->gamma_16_from_1[(gray16&0xff) >> + w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >> png_ptr->gamma_shift][gray16 >> 8]; rgb_error |= 1; } @@ -3364,7 +3121,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) *(dp++) = (png_byte)((w>>8) & 0xff); *(dp++) = (png_byte)(w & 0xff); - if (have_alpha) + if (have_alpha != 0) { *(dp++) = *(sp++); *(dp++) = *(sp++); @@ -3381,24 +3138,25 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) for (i = 0; i < row_width; i++) { png_uint_16 red, green, blue, gray16; + png_byte hi,lo; - red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); + hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); if (red != green || red != blue) rgb_error |= 1; - /* From 1.5.5 in the 16 bit case do the accurate conversion even + /* From 1.5.5 in the 16-bit case do the accurate conversion even * in the 'fast' case - this is because this is where the code - * ends up when handling linear 16 bit data. + * ends up when handling linear 16-bit data. */ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> 15); - *(dp++) = (png_byte)((gray16>>8) & 0xff); + *(dp++) = (png_byte)((gray16 >> 8) & 0xff); *(dp++) = (png_byte)(gray16 & 0xff); - if (have_alpha) + if (have_alpha != 0) { *(dp++) = *(sp++); *(dp++) = *(sp++); @@ -3417,74 +3175,15 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) return rgb_error; } #endif -#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth - * large of png_color. This lets grayscale images be treated as - * paletted. Most useful for gamma correction and simplification - * of code. This API is not used internally. - */ -void PNGAPI -png_build_grayscale_palette(int bit_depth, png_colorp palette) -{ - int num_palette; - int color_inc; - int i; - int v; - - png_debug(1, "in png_do_build_grayscale_palette"); - - if (palette == NULL) - return; - - switch (bit_depth) - { - case 1: - num_palette = 2; - color_inc = 0xff; - break; - - case 2: - num_palette = 4; - color_inc = 0x55; - break; - - case 4: - num_palette = 16; - color_inc = 0x11; - break; - - case 8: - num_palette = 256; - color_inc = 1; - break; - - default: - num_palette = 0; - color_inc = 0; - break; - } - - for (i = 0, v = 0; i < num_palette; i++, v += color_inc) - { - palette[i].red = (png_byte)v; - palette[i].green = (png_byte)v; - palette[i].blue = (png_byte)v; - } -} -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ - (defined PNG_READ_ALPHA_MODE_SUPPORTED) +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) /* Replace any alpha or transparency with the supplied background color. * "background" is already in the screen gamma, while "background_1" is * at a gamma of 1.0. Paletted files have already been taken care of. */ -void /* PRIVATE */ -png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) +static void +png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { #ifdef PNG_READ_GAMMA_SUPPORTED png_const_bytep gamma_table = png_ptr->gamma_table; @@ -3494,12 +3193,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; int gamma_shift = png_ptr->gamma_shift; + int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; #endif png_bytep sp; png_uint_32 i; png_uint_32 row_width = row_info->width; - int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; int shift; png_debug(1, "in png_do_compose"); @@ -3520,11 +3219,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x01) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 7; sp++; @@ -3548,20 +3248,22 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x03) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } else { - png_byte p = (png_byte)((*sp >> shift) & 0x03); - png_byte g = (png_byte)((gamma_table [p | (p << 2) | - (p << 4) | (p << 6)] >> 6) & 0x03); - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(g << shift); + unsigned int p = (*sp >> shift) & 0x03; + unsigned int g = (gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03; + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= g << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 6; sp++; @@ -3582,11 +3284,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x03) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 6; sp++; @@ -3611,20 +3314,22 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x0f) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } else { - png_byte p = (png_byte)((*sp >> shift) & 0x0f); - png_byte g = (png_byte)((gamma_table[p | - (p << 4)] >> 4) & 0x0f); - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(g << shift); + unsigned int p = (*sp >> shift) & 0x0f; + unsigned int g = (gamma_table[p | (p << 4)] >> 4) & + 0x0f; + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= g << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 4; sp++; @@ -3645,11 +3350,12 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) if ((png_uint_16)((*sp >> shift) & 0x0f) == png_ptr->trans_color.gray) { - *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *sp |= (png_byte)(png_ptr->background.gray << shift); + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } - if (!shift) + if (shift == 0) { shift = 4; sp++; @@ -3902,7 +3608,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) v = gamma_to_1[*sp]; png_composite(w, v, a, png_ptr->background_1.gray); - if (!optimize) + if (optimize == 0) w = gamma_from_1[w]; *sp = w; } @@ -3959,10 +3665,11 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; png_composite_16(v, g, a, png_ptr->background_1.gray); - if (optimize) + if (optimize != 0) w = v; else - w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8]; + w = gamma_16_from_1[(v & 0xff) >> + gamma_shift][v >> 8]; *sp = (png_byte)((w >> 8) & 0xff); *(sp + 1) = (png_byte)(w & 0xff); } @@ -4033,17 +3740,17 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) v = gamma_to_1[*sp]; png_composite(w, v, a, png_ptr->background_1.red); - if (!optimize) w = gamma_from_1[w]; + if (optimize == 0) w = gamma_from_1[w]; *sp = w; v = gamma_to_1[*(sp + 1)]; png_composite(w, v, a, png_ptr->background_1.green); - if (!optimize) w = gamma_from_1[w]; + if (optimize == 0) w = gamma_from_1[w]; *(sp + 1) = w; v = gamma_to_1[*(sp + 2)]; png_composite(w, v, a, png_ptr->background_1.blue); - if (!optimize) w = gamma_from_1[w]; + if (optimize == 0) w = gamma_from_1[w]; *(sp + 2) = w; } } @@ -4125,26 +3832,26 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; png_composite_16(w, v, a, png_ptr->background_1.red); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)] - [w >> 8]; + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; *sp = (png_byte)((w >> 8) & 0xff); *(sp + 1) = (png_byte)(w & 0xff); v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; png_composite_16(w, v, a, png_ptr->background_1.green); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)] - [w >> 8]; + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; *(sp + 2) = (png_byte)((w >> 8) & 0xff); *(sp + 3) = (png_byte)(w & 0xff); v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; png_composite_16(w, v, a, png_ptr->background_1.blue); - if (!optimize) - w = gamma_16_from_1[((w&0xff) >> gamma_shift)] - [w >> 8]; + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; *(sp + 4) = (png_byte)((w >> 8) & 0xff); *(sp + 5) = (png_byte)(w & 0xff); @@ -4207,7 +3914,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) } } } -#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */ +#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ #ifdef PNG_READ_GAMMA_SUPPORTED /* Gamma correct the image, avoiding the alpha channel. Make sure @@ -4216,8 +3923,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr) * is 16, use gamma_16_table and gamma_shift. Build these with * build_gamma_table(). */ -void /* PRIVATE */ -png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) +static void +png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { png_const_bytep gamma_table = png_ptr->gamma_table; png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; @@ -4417,14 +4124,14 @@ png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr) * linear.) Called only with color types that have an alpha channel. Needs the * from_1 tables. */ -void /* PRIVATE */ -png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) +static void +png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { png_uint_32 row_width = row_info->width; png_debug(1, "in png_do_encode_alpha"); - if (row_info->color_type & PNG_COLOR_MASK_ALPHA) + if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) { if (row_info->bit_depth == 8) { @@ -4483,7 +4190,7 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr) /* Expands a palette row to an RGB or RGBA row depending * upon whether you supply trans and num_trans. */ -void /* PRIVATE */ +static void png_do_expand_palette(png_row_infop row_info, png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) { @@ -4636,7 +4343,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, /* If the bit depth < 8, it is expanded to 8. Also, if the already * expanded transparency value is supplied, an alpha channel is built. */ -void /* PRIVATE */ +static void png_do_expand(png_row_infop row_info, png_bytep row, png_const_color_16p trans_color) { @@ -4650,7 +4357,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, { if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { - png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0); + unsigned int gray = trans_color != NULL ? trans_color->gray : 0; if (row_info->bit_depth < 8) { @@ -4658,7 +4365,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, { case 1: { - gray = (png_uint_16)((gray & 0x01) * 0xff); + gray = (gray & 0x01) * 0xff; sp = row + (png_size_t)((row_width - 1) >> 3); dp = row + (png_size_t)row_width - 1; shift = 7 - (int)((row_width + 7) & 0x07); @@ -4686,7 +4393,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, case 2: { - gray = (png_uint_16)((gray & 0x03) * 0x55); + gray = (gray & 0x03) * 0x55; sp = row + (png_size_t)((row_width - 1) >> 2); dp = row + (png_size_t)row_width - 1; shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); @@ -4711,7 +4418,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, case 4: { - gray = (png_uint_16)((gray & 0x0f) * 0x11); + gray = (gray & 0x0f) * 0x11; sp = row + (png_size_t)((row_width - 1) >> 1); dp = row + (png_size_t)row_width - 1; shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); @@ -4746,15 +4453,13 @@ png_do_expand(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - /* NOTE: prior to libpng 1.5.14 this cleared out the top bits of - * 'gray', however if those are set it is an error. - */ + gray = gray & 0xff; sp = row + (png_size_t)row_width - 1; dp = row + (png_size_t)(row_width << 1) - 1; for (i = 0; i < row_width; i++) { - if (*sp == gray) + if ((*sp & 0xffU) == gray) *dp-- = 0; else @@ -4766,13 +4471,14 @@ png_do_expand(png_row_infop row_info, png_bytep row, else if (row_info->bit_depth == 16) { - png_byte gray_high = (png_byte)((gray >> 8) & 0xff); - png_byte gray_low = (png_byte)(gray & 0xff); + unsigned int gray_high = (gray >> 8) & 0xff; + unsigned int gray_low = gray & 0xff; sp = row + row_info->rowbytes - 1; dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) { - if (*(sp - 1) == gray_high && *(sp) == gray_low) + if ((*(sp - 1) & 0xffU) == gray_high && + (*(sp) & 0xffU) == gray_low) { *dp-- = 0; *dp-- = 0; @@ -4796,7 +4502,8 @@ png_do_expand(png_row_infop row_info, png_bytep row, row_width); } } - else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color) + else if (row_info->color_type == PNG_COLOR_TYPE_RGB && + trans_color != NULL) { if (row_info->bit_depth == 8) { @@ -4868,7 +4575,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, /* If the bit depth is 8 and the color type is not a palette type expand the * whole row to 16 bits. Has no effect otherwise. */ -void /* PRIVATE */ +static void png_do_expand_16(png_row_infop row_info, png_bytep row) { if (row_info->bit_depth == 8 && @@ -4896,7 +4603,7 @@ png_do_expand_16(png_row_infop row_info, png_bytep row) #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED -void /* PRIVATE */ +static void png_do_quantize(png_row_infop row_info, png_bytep row, png_const_bytep palette_lookup, png_const_bytep quantize_lookup) { @@ -4987,70 +4694,304 @@ png_do_quantize(png_row_infop row_info, png_bytep row, } } } -#endif /* PNG_READ_QUANTIZE_SUPPORTED */ -#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ +#endif /* READ_QUANTIZE */ -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Undoes intrapixel differencing */ +/* Transform the row. The order of transformations is significant, + * and is very touchy. If you add a transformation, take care to + * decide how it fits in with the other transformations here. + */ void /* PRIVATE */ -png_do_read_intrapixel(png_row_infop row_info, png_bytep row) +png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) { - png_debug(1, "in png_do_read_intrapixel"); + png_debug(1, "in png_do_read_transformations"); - if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR)) + if (png_ptr->row_buf == NULL) { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; + /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this + * error is incredibly rare and incredibly easy to debug without this + * information. + */ + png_error(png_ptr, "NULL row buffer"); + } - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; + /* The following is debugging; prior to 1.5.4 the code was never compiled in; + * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro + * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for + * all transformations, however in practice the ROW_INIT always gets done on + * demand, if necessary. + */ + if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && + (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) + { + /* Application has failed to call either png_read_start_image() or + * png_read_update_info() after setting transforms that expand pixels. + * This check added to libpng-1.2.19 (but not enabled until 1.5.4). + */ + png_error(png_ptr, "Uninitialized row"); + } - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; +#ifdef PNG_READ_EXPAND_SUPPORTED + if ((png_ptr->transformations & PNG_EXPAND) != 0) + { + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_do_expand_palette(row_info, png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); + } - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; + else + { + if (png_ptr->num_trans != 0 && + (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) + png_do_expand(row_info, png_ptr->row_buf + 1, + &(png_ptr->trans_color)); else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); - *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); - } + png_do_expand(row_info, png_ptr->row_buf + 1, + NULL); } - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; + } +#endif - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) == 0 && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) + { + int rgb_error = + png_do_rgb_to_gray(png_ptr, row_info, + png_ptr->row_buf + 1); - else - return; + if (rgb_error != 0) + { + png_ptr->rgb_to_gray_status=1; + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_WARN) + png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (s0 + s1 + 65536) & 0xffff; - png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp + 1) = (png_byte)(red & 0xff); - *(rp + 4) = (png_byte)((blue >> 8) & 0xff); - *(rp + 5) = (png_byte)(blue & 0xff); - } + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == + PNG_RGB_TO_GRAY_ERR) + png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); } } +#endif + +/* From Andreas Dilger e-mail to png-implement, 26 March 1998: + * + * In most cases, the "simple transparency" should be done prior to doing + * gray-to-RGB, or you will have to test 3x as many bytes to check if a + * pixel is transparent. You would also need to make sure that the + * transparency information is upgraded to RGB. + * + * To summarize, the current flow is: + * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite + * with background "in place" if transparent, + * convert to RGB if necessary + * - Gray + alpha -> composite with gray background and remove alpha bytes, + * convert to RGB if necessary + * + * To support RGB backgrounds for gray images we need: + * - Gray + simple transparency -> convert to RGB + simple transparency, + * compare 3 or 6 bytes and composite with + * background "in place" if transparent + * (3x compare/pixel compared to doing + * composite with gray bkgrnd) + * - Gray + alpha -> convert to RGB + alpha, composite with background and + * remove alpha bytes (3x float + * operations/pixel compared with composite + * on gray background) + * + * Greg's change will do this. The reason it wasn't done before is for + * performance, as this increases the per-pixel operations. If we would check + * in advance if the background was gray or RGB, and position the gray-to-RGB + * transform appropriately, then it would save a lot of work/time. + */ + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* If gray -> RGB, do so now only if background is non-gray; else do later + * for performance reasons + */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + if ((png_ptr->transformations & PNG_COMPOSE) != 0) + png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED + if ((png_ptr->transformations & PNG_GAMMA) != 0 && +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED + /* Because RGB_TO_GRAY does the gamma transform. */ + (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && +#endif +#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ + defined(PNG_READ_ALPHA_MODE_SUPPORTED) + /* Because PNG_COMPOSE does the gamma transform if there is something to + * do (if there is an alpha channel or transparency.) + */ + !((png_ptr->transformations & PNG_COMPOSE) != 0 && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && +#endif + /* Because png_init_read_transformations transforms the palette, unless + * RGB_TO_GRAY will do the transform. + */ + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && + (png_ptr->transformations & PNG_COMPOSE) != 0 && + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || + row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) + png_do_strip_channel(row_info, png_ptr->row_buf + 1, + 0 /* at_start == false, because SWAP_ALPHA happens later */); +#endif + +#ifdef PNG_READ_ALPHA_MODE_SUPPORTED + if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && + (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) + png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); +#endif + +#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) + png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED + /* There is no harm in doing both of these because only one has any effect, + * by putting the 'scale' option first if the app asks for scale (either by + * calling the API or in a TRANSFORM flag) this is what happens. + */ + if ((png_ptr->transformations & PNG_16_TO_8) != 0) + png_do_chop(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_QUANTIZE_SUPPORTED + if ((png_ptr->transformations & PNG_QUANTIZE) != 0) + { + png_do_quantize(row_info, png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->quantize_index); + + if (row_info->rowbytes == 0) + png_error(png_ptr, "png_do_quantize returned rowbytes=0"); + } +#endif /* READ_QUANTIZE */ + +#ifdef PNG_READ_EXPAND_16_SUPPORTED + /* Do the expansion now, after all the arithmetic has been done. Notice + * that previous transformations can handle the PNG_EXPAND_16 flag if this + * is efficient (particularly true in the case of gamma correction, where + * better accuracy results faster!) + */ + if ((png_ptr->transformations & PNG_EXPAND_16) != 0) + png_do_expand_16(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED + /* NOTE: moved here in 1.5.4 (from much later in this list.) */ + if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && + (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) + png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) + png_do_invert(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_SHIFT_SUPPORTED + if ((png_ptr->transformations & PNG_SHIFT) != 0) + png_do_unshift(row_info, png_ptr->row_buf + 1, + &(png_ptr->shift)); +#endif + +#ifdef PNG_READ_PACK_SUPPORTED + if ((png_ptr->transformations & PNG_PACK) != 0) + png_do_unpack(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED + /* Added at libpng-1.5.10 */ + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= 0) + png_do_check_palette_indexes(png_ptr, row_info); +#endif + +#ifdef PNG_READ_BGR_SUPPORTED + if ((png_ptr->transformations & PNG_BGR) != 0) + png_do_bgr(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_PACKSWAP_SUPPORTED + if ((png_ptr->transformations & PNG_PACKSWAP) != 0) + png_do_packswap(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_FILLER_SUPPORTED + if ((png_ptr->transformations & PNG_FILLER) != 0) + png_do_read_filler(row_info, png_ptr->row_buf + 1, + (png_uint_32)png_ptr->filler, png_ptr->flags); +#endif + +#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) + png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); +#endif + +#ifdef PNG_READ_16BIT_SUPPORTED +#ifdef PNG_READ_SWAP_SUPPORTED + if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) + png_do_swap(row_info, png_ptr->row_buf + 1); +#endif +#endif + +#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED + if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) + { + if (png_ptr->read_user_transform_fn != NULL) + (*(png_ptr->read_user_transform_fn)) /* User read transform function */ + (png_ptr, /* png_ptr */ + row_info, /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ +#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED + if (png_ptr->user_transform_depth != 0) + row_info->bit_depth = png_ptr->user_transform_depth; + + if (png_ptr->user_transform_channels != 0) + row_info->channels = png_ptr->user_transform_channels; +#endif + row_info->pixel_depth = (png_byte)(row_info->bit_depth * + row_info->channels); + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); + } +#endif } -#endif /* PNG_MNG_FEATURES_SUPPORTED */ -#endif /* PNG_READ_SUPPORTED */ + +#endif /* READ_TRANSFORMS */ +#endif /* READ */