Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibPNG/pngrtran.c view on Meta::CPAN
/* 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*/);
/* 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
* disabled in background handling. There is no evidence (so far) that this
* was being used; however, png_set_background itself accepted and must still
* 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) 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");
/* 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->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_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 */
#endif /* READ_GAMMA */
#ifdef PNG_READ_EXPAND_SUPPORTED
/* Expand paletted images to RGB, expand grayscale images of
* less than 8-bit depth to 8-bit depth, and expand tRNS chunks
* to alpha channels.
*/
void PNGAPI
png_set_expand(png_structrp png_ptr)
{
png_debug(1, "in png_set_expand");
if (png_rtran_ok(png_ptr, 0) == 0)
return;
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
}
/* GRR 19990627: the following three functions currently are identical
* to png_set_expand(). However, it is entirely reasonable that someone
* might wish to expand an indexed image to RGB but *not* expand a single,
* fully transparent palette entry to a full alpha channel--perhaps instead
* convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
* the transparent color with a particular RGB value, or drop tRNS entirely.
* IOW, a future version of the library may make the transformations flag
* a bit more fine-grained, with separate bits for each of these three
* functions.
*
* More to the point, these functions make it obvious what libpng will be
* doing, whereas "expand" can (and does) mean any number of things.
*
* GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
* to expand only the sample depth but not to expand the tRNS to alpha
* and its name was changed to png_set_expand_gray_1_2_4_to_8().
*/
/* Expand paletted images to RGB. */
void PNGAPI
png_set_palette_to_rgb(png_structrp png_ptr)
{
png_debug(1, "in png_set_palette_to_rgb");
if (png_rtran_ok(png_ptr, 0) == 0)
return;
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
}
/* Expand grayscale images of less than 8-bit depth to 8 bits. */
void PNGAPI
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_rtran_ok(png_ptr, 0) == 0)
return;
png_ptr->transformations |= PNG_EXPAND;
}
/* Expand tRNS chunks to alpha channels. */
void PNGAPI
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);
}
#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_structrp png_ptr)
{
png_debug(1, "in png_set_expand_16");
if (png_rtran_ok(png_ptr, 0) == 0)
return;
src/Source/LibPNG/pngrtran.c view on Meta::CPAN
png_error(png_ptr, "Uninitialized row");
}
#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 (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
png_do_expand(row_info, png_ptr->row_buf + 1,
NULL);
}
}
#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_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);
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");
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) &&
((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
( run in 3.041 seconds using v1.01-cache-2.11-cpan-df04353d9ac )