sBIT code coverage and fixes

Fixes for sBIT handling in the low-bit-depth gray and pngstest cases, extends
sBIT handling to the colormap code in the simplified API which is separately
implemented in pngread.c

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler 2015-09-26 15:24:20 -07:00
parent 8dfa93beed
commit 23324b8559
7 changed files with 295 additions and 102 deletions

View File

@ -1361,6 +1361,60 @@ insert_hIST(png_structp png_ptr, png_infop info_ptr, int nparams,
png_set_hIST(png_ptr, info_ptr, freq);
}
static png_byte
bval(png_charp param)
{
char *endptr = NULL;
unsigned long int l = strtoul(param, &endptr, 0/*base*/);
if (param[0] && *endptr == 0 && l <= 255)
return (png_byte)l;
else
{
fprintf(stderr, "sBIT: invalid sBIT value '%s'\n", param);
exit(1);
}
}
static void
insert_sBIT(png_structp png_ptr, png_infop info_ptr, int nparams,
png_charpp params)
{
const int ct = png_get_color_type(png_ptr, info_ptr);
const int c = channels_of_type(ct);
png_color_8 sBIT;
if (nparams != c)
{
fprintf(stderr, "sBIT: expected parameter count %d, not %d\n", c,
nparams);
exit(1);
}
if (ct & PNG_COLOR_MASK_COLOR)
{
sBIT.red = bval(params[0]);
sBIT.green = bval(params[1]);
sBIT.blue = bval(params[2]);
sBIT.gray = 42;
}
else
{
sBIT.red = sBIT.green = sBIT.blue = 42;
sBIT.gray = bval(params[0]);
}
if (ct & PNG_COLOR_MASK_ALPHA)
sBIT.alpha = bval(params[nparams-1]);
else
sBIT.alpha = 42;
png_set_sBIT(png_ptr, info_ptr, &sBIT);
}
#if 0
static void
insert_sPLT(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params)
@ -1488,6 +1542,11 @@ find_insert(png_const_charp what, png_charp param)
return make_insert(what, insert_hIST, nparams, parameter_list);
break;
case CHUNK(115,66,73,84): /* sBIT */
if (nparams <= 4)
return make_insert(what, insert_sBIT, nparams, parameter_list);
break;
#if 0
case CHUNK(115,80,76,84): /* sPLT */
return make_insert(what, insert_sPLT, nparams, parameter_list);

View File

@ -1949,7 +1949,7 @@ typedef struct png_modifier
unsigned int repeat :1; /* Repeat this transform test. */
unsigned int test_uses_encoding :1;
/* Lowest sbit to test (libpng fails for sbit < 8) */
/* Lowest sbit to test (pre-1.7 libpng fails for sbit < 8) */
png_byte sbitlow;
/* Error control - these are the limits on errors accepted by the gamma tests
@ -2036,7 +2036,7 @@ typedef struct png_modifier
unsigned int test_gamma_expand16 :1;
unsigned int test_exhaustive :1;
/* Whether or not to run the low-bit-depth grayscale tests. This fail on
/* Whether or not to run the low-bit-depth grayscale tests. This fails on
* gamma images in some cases because of gross inaccuracies in the grayscale
* gamma handling for low bit depth.
*/
@ -11125,7 +11125,11 @@ int main(int argc, char **argv)
pm.encodings = test_encodings;
pm.nencodings = ARRAY_SIZE(test_encodings);
# if PNG_LIBPNG_VER < 10700
pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
# else
pm.sbitlow = 1U;
# endif
/* The following allows results to pass if they correspond to anything in the
* transformed range [input-.5,input+.5]; this is is required because of the

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

View File

@ -72,19 +72,8 @@ case "$1" in
done;;
--coverage)
# Comments below indicate cases known to be required and not duplicated
# in other (required) cases; the aim is to get a minimal set that gives
# the maxium code coverage.
mpg none gray-alpha 8 # required: code coverage, sRGB opaque component
mpg none palette 8 # required: basic palette read
mpg 1.8 gray 2 # required: tests gamma threshold code
mpg 1.8 palette 2 # required: code coverage
mpg 1.8 palette 4 # required: code coverage
mpg 1.8 palette 8 # error limits only
mpg linear palette 8 # error limits only
mpg linear rgb-alpha 16 # error limits only
mpg sRGB palette 1 # required: code coverage
mpg sRGB rgb-alpha 16 # required: code coverage: pngread.c:2422 untested
# Extra images made to improve code coverage:
${MAKEPNG} --insert sBIT 1 --tRNS gray 2 gray-2-sBIT-tRNS.png
:;;
*)

View File

@ -2029,13 +2029,13 @@ PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
/* Internal fixed point gamma correction. These APIs are called as
* required to convert single values - they don't need to be fast,
* they are not used when processing image pixel values.
*
* While the input is an 'unsigned' value it must actually be the
* correct bit value - 0..255 or 0..65535 as required.
*/
PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,
(png_const_structrp png_ptr, png_uint_32 value, png_fixed_point gamma_value),
PNG_EMPTY);
PNG_INTERNAL_FUNCTION(unsigned int,png_gamma_nxmbit_correct,
(unsigned int value, png_fixed_point gamma_val, unsigned int n/*input bits*/,
unsigned int m/*output bits */),PNG_EMPTY);
/* In this case the value must have 'n' bits and the output will have 'm'
* bits.
*/
/* Internal check function to saw if the gamma of the PNG data is far enough
* from the given screen gamma to require gamma correction (only needed for a

246
pngread.c
View File

@ -1051,6 +1051,7 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr, int transforms,
# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */
# define P_LINEAR8 4 /* 8-bit linear: only from a file value */
# define P_FILE8 5 /* 8-bit encoded to file gamma but not significant bits */
/* Color-map processing: after libpng has run on the PNG image further
* processing may be needed to convert the data to color-map indices.
@ -1083,6 +1084,7 @@ typedef struct
int file_encoding; /* E_ values above */
png_fixed_point file_to_sRGB; /* Cached correction factor */
int colormap_processing; /* PNG_CMAP_ values above */
png_byte sBIT[4]; /* Significant bits for channels */
} png_image_read_control;
/* Do all the *safe* initialization - 'safe' means that png_error won't be
@ -1242,6 +1244,47 @@ png_image_read_header(png_voidp argument)
return 1;
}
static void
png_image_get_sBIT(png_image_read_control *display)
/* Utility to cache the sBIT values. This uses the information from the
* png_struct not png_info because it may be needed after the sBIT
* information in png_info has been invalidated.
*/
{
if (display->sBIT[0] == 0)
{
const png_const_structrp png_ptr = display->image->opaque->png_ptr;
const unsigned int color_type = png_ptr->color_type;
const png_byte bit_depth =
(color_type & PNG_COLOR_MASK_PALETTE) ? 8U : png_ptr->bit_depth;
memset(display->sBIT, bit_depth, sizeof display->sBIT);
if (color_type & PNG_COLOR_MASK_COLOR)
{
if (png_ptr->sig_bit.red > 0 && png_ptr->sig_bit.red < bit_depth)
display->sBIT[0] = png_ptr->sig_bit.red;
if (png_ptr->sig_bit.green > 0 && png_ptr->sig_bit.green < bit_depth)
display->sBIT[1] = png_ptr->sig_bit.green;
if (png_ptr->sig_bit.blue > 0 && png_ptr->sig_bit.blue < bit_depth)
display->sBIT[2] = png_ptr->sig_bit.blue;
}
else
{
if (png_ptr->sig_bit.gray > 0 && png_ptr->sig_bit.gray < bit_depth)
display->sBIT[2] = display->sBIT[1] = display->sBIT[0] =
png_ptr->sig_bit.gray;
}
if (color_type & PNG_COLOR_MASK_ALPHA)
{
if (png_ptr->sig_bit.alpha > 0 && png_ptr->sig_bit.alpha < bit_depth)
display->sBIT[3] = png_ptr->sig_bit.alpha;
}
}
}
#ifdef PNG_STDIO_SUPPORTED
int PNGAPI
png_image_begin_read_from_stdio(png_imagep image, FILE* file)
@ -1493,40 +1536,74 @@ init_correct(png_const_structrp png_ptr, png_fixed_point *correct)
}
static png_uint_32
convert_to_sRGB(png_image_read_control *display, png_uint_32 value)
update_for_sBIT(png_uint_32 value, unsigned int significant_bits,
unsigned int bit_depth)
/* Return a bit_depth value adjusted for the number of significant bits in
* the value.
*/
{
if (significant_bits < bit_depth)
{
value >>= bit_depth - significant_bits;
/* Now scale back to bit_depth, taking care not to overflow when 'value'
* is (1<<significant_bits)-1 by rounding *down* the rounding add below
* (so, e.g. rather than 2, 1 is used when significant bits is 2).
*/
value = (value * ((1U<<bit_depth)-1U) + ((1U<<(significant_bits-1U))-1U))
/ ((1U<<significant_bits)-1U);
}
return value;
}
static png_uint_32
convert_to_sRGB(png_image_read_control *display, png_uint_32 value,
unsigned int significant_bits)
{
/* Converts an 8-bit value from P_FILE to P_sRGB */
png_const_structrp png_ptr = display->image->opaque->png_ptr;
affirm(value <= 255U);
debug(value <= 255U && significant_bits <= 8U && significant_bits > 0U);
if (display->file_to_sRGB == 0)
init_correct(png_ptr, &display->file_to_sRGB);
/* Now simply apply this correction factor and scale back to 8 bits. */
if (display->file_to_sRGB != PNG_FP_1)
value = PNG_DIV257(
png_gamma_16bit_correct(png_ptr, value*257U, display->file_to_sRGB));
value = png_gamma_nxmbit_correct(value >> (8U-significant_bits),
display->file_to_sRGB, significant_bits, 8U);
else if (significant_bits < 8U)
value = update_for_sBIT(value, significant_bits, 8U);
return value;
}
static png_uint_32
convert_to_linear(png_image_read_control *display, png_uint_32 value)
convert_to_linear(png_image_read_control *display, png_uint_32 value,
unsigned int significant_bits)
{
/* Converts an 8-bit value from P_FILE to 16-bit P_LINEAR */
png_const_structrp png_ptr = display->image->opaque->png_ptr;
affirm(value <= 255U);
debug(value <= 255U && significant_bits <= 8U && significant_bits > 0U);
if (display->file_to_sRGB == 0)
init_correct(png_ptr, &display->file_to_sRGB);
/* Use this correct to get a 16-bit sRGB value: */
/* Use this correction to get a 16-bit sRGB value: */
if (display->file_to_sRGB != PNG_FP_1)
value = png_gamma_nxmbit_correct(value >> (8U-significant_bits),
display->file_to_sRGB, significant_bits, 16U);
else
{
value *= 257U;
if (display->file_to_sRGB != PNG_FP_1)
value = png_gamma_16bit_correct(png_ptr, value, display->file_to_sRGB);
if (significant_bits < 8U)
value = update_for_sBIT(value, significant_bits, 16U);
}
/* Now convert this back to linear, using the correct transfer function. */
if (value <= 2650U /* 65535 * 0.04045 */)
@ -1547,17 +1624,20 @@ convert_to_linear(png_image_read_control *display, png_uint_32 value)
*/
value *= 62119U;
value += 223904831U+32768U; /* cannot overflow; test with 65535 */
value = png_gamma_16bit_correct(png_ptr, value >> 16, 240000);
value = png_gamma_nxmbit_correct(value >> 16, 240000, 16U, 16U);
}
return value;
}
static unsigned int
decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
decode_gamma(png_image_read_control *display, png_uint_32 value,
unsigned int significant_bits, int encoding)
{
int do_sBIT = 0;
if (encoding == P_FILE) /* double check */
encoding = display->file_encoding;
encoding = display->file_encoding, do_sBIT = 1;
if (encoding == P_NOTSET) /* must be the file encoding */
{
@ -1568,18 +1648,26 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
switch (encoding)
{
case P_FILE:
value = convert_to_linear(display, value);
/* This is a file value, so the sBIT, if any, needs to be used. */
value = convert_to_linear(display, value, significant_bits);
break;
case P_sRGB:
if (do_sBIT)
value = update_for_sBIT(value, significant_bits, 8U);
value = png_sRGB_table[value];
break;
case P_LINEAR:
if (do_sBIT)
value = update_for_sBIT(value, significant_bits, 16U);
break;
case P_LINEAR8:
value *= 257;
if (do_sBIT)
value = update_for_sBIT(value, significant_bits, 16U);
break;
default:
@ -1593,7 +1681,8 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
static png_uint_32
png_colormap_compose(png_image_read_control *display,
png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
png_uint_32 foreground, unsigned int foreground_significant_bits,
int foreground_encoding, png_uint_32 alpha,
png_uint_32 background, int encoding)
{
/* The file value is composed on the background, the background has the given
@ -1601,8 +1690,9 @@ png_colormap_compose(png_image_read_control *display,
* file and alpha are 8-bit values. The (output) encoding will always be
* P_LINEAR or P_sRGB.
*/
png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
png_uint_32 b = decode_gamma(display, background, encoding);
png_uint_32 f = decode_gamma(display, foreground,
foreground_significant_bits, foreground_encoding);
png_uint_32 b = decode_gamma(display, background, 0U/*UNUSED*/, encoding);
/* The alpha is always an 8-bit value (it comes from the palette), the value
* scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
@ -1639,9 +1729,16 @@ png_create_colormap_entry(png_image_read_control *display,
P_LINEAR : P_sRGB;
const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
(red != green || green != blue);
int use_sBIT = encoding == P_FILE;
if (ip > 255)
png_error(png_ptr, "color-map index out of range");
affirm(ip <= 255);
implies(encoding != P_LINEAR, red <= 255U && green <= 255U && blue <= 255U
&& display->sBIT[0] <= 8U && display->sBIT[1] <= 8U
&& display->sBIT[2] <= 8U && display->sBIT[3] <= 8U);
/* This is a hack for the grayscale colormap below. */
if (encoding == P_FILE8)
encoding = P_FILE;
/* Update the cache with whether the file gamma is significantly different
* from sRGB.
@ -1653,37 +1750,61 @@ png_create_colormap_entry(png_image_read_control *display,
/* Note that the cached value may be P_FILE too. */
encoding = display->file_encoding;
if (use_sBIT)
png_image_get_sBIT(display);
}
if (encoding == P_FILE)
{
if (convert_to_Y != 0 || output_encoding == P_LINEAR)
{
red = convert_to_linear(display, red);
green = convert_to_linear(display, green);
blue = convert_to_linear(display, blue);
alpha *= 257;
red = convert_to_linear(display, red,
use_sBIT ? display->sBIT[0] : 8U);
green = convert_to_linear(display, green,
use_sBIT ? display->sBIT[1] : 8U);
blue = convert_to_linear(display, blue,
use_sBIT ? display->sBIT[2] : 8U);
alpha *= 257U;
if (use_sBIT)
alpha = update_for_sBIT(alpha, display->sBIT[3], 16U);
encoding = P_LINEAR;
use_sBIT = 0;
}
else
{
red = convert_to_sRGB(display, red);
green = convert_to_sRGB(display, green);
blue = convert_to_sRGB(display, blue);
red = convert_to_sRGB(display, red,
use_sBIT ? display->sBIT[0] : 8U);
green = convert_to_sRGB(display, green,
use_sBIT ? display->sBIT[1] : 8U);
blue = convert_to_sRGB(display, blue,
use_sBIT ? display->sBIT[2] : 8U);
if (use_sBIT)
alpha = update_for_sBIT(alpha, display->sBIT[3], 8U);
encoding = P_sRGB;
use_sBIT = 0;
}
}
else if (encoding == P_LINEAR8)
{
/* This encoding occurs quite frequently in test cases because PngSuite
* includes a gAMA 1.0 chunk with most images.
/* This encoding corresponds to a colormap with linear RGB entries, this
* is not a very sensible encoding but it does happen with the PNGSuite
* test images.
*/
red *= 257;
green *= 257;
blue *= 257;
alpha *= 257;
if (use_sBIT)
{
red = update_for_sBIT(red, display->sBIT[0], 16U);
green = update_for_sBIT(green, display->sBIT[1], 16U);
blue = update_for_sBIT(blue, display->sBIT[2], 16U);
alpha = update_for_sBIT(alpha, display->sBIT[3], 16U);
use_sBIT = 0;
}
encoding = P_LINEAR;
}
@ -1693,13 +1814,38 @@ png_create_colormap_entry(png_image_read_control *display,
/* The values are 8-bit sRGB values, but must be converted to 16-bit
* linear.
*/
if (use_sBIT)
{
red = convert_to_linear(display, red, display->sBIT[0]);
green = convert_to_linear(display, green, display->sBIT[1]);
blue = convert_to_linear(display, blue, display->sBIT[2]);
alpha = update_for_sBIT(alpha * 257U, display->sBIT[3], 16U);
use_sBIT = 0;
}
else
{
red = png_sRGB_table[red];
green = png_sRGB_table[green];
blue = png_sRGB_table[blue];
alpha *= 257;
}
encoding = P_LINEAR;
}
else if (encoding == P_sRGB && use_sBIT)
{
debug(output_encoding == P_sRGB); /* P_LINEAR handled above */
red = update_for_sBIT(red, display->sBIT[0], 8U);
green = update_for_sBIT(green, display->sBIT[1], 8U);
blue = update_for_sBIT(blue, display->sBIT[2], 8U);
alpha = update_for_sBIT(alpha, display->sBIT[3], 8U);
use_sBIT = 0;
}
debug(!use_sBIT); /* it should have been handled above */
/* This is set if the color isn't gray but the output is. */
if (encoding == P_LINEAR)
{
@ -1854,7 +2000,7 @@ make_gray_file_colormap(png_image_read_control *display)
unsigned int i;
for (i=0; i<256; ++i)
png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
png_create_colormap_entry(display, i, i, i, i, 255, P_FILE8);
return i;
}
@ -2467,8 +2613,8 @@ png_image_read_colormap(png_voidp argument)
if (output_encoding == P_sRGB)
gray = png_sRGB_table[gray]; /* now P_LINEAR */
gray = PNG_DIV257(png_gamma_16bit_correct(png_ptr, gray,
png_ptr->colorspace.gamma)); /* now P_FILE */
gray = png_gamma_nxmbit_correct(gray,
png_ptr->colorspace.gamma, 16U, 8U);
/* And make sure the corresponding palette entry contains
* exactly the required sRGB value.
@ -2625,12 +2771,12 @@ png_image_read_colormap(png_voidp argument)
*/
for (b=0; b<256; b = (b << 1) | 0x7f)
png_create_colormap_entry(display, cmap_entries++,
png_colormap_compose(display, r, P_sRGB, 128,
back_r, output_encoding),
png_colormap_compose(display, g, P_sRGB, 128,
back_g, output_encoding),
png_colormap_compose(display, b, P_sRGB, 128,
back_b, output_encoding),
png_colormap_compose(display, r, 8U, P_sRGB,
128U, back_r, output_encoding),
png_colormap_compose(display, g, 8U, P_sRGB,
128U, back_g, output_encoding),
png_colormap_compose(display, b, 8U, P_sRGB,
128U, back_b, output_encoding),
0/*unused*/, output_encoding);
}
}
@ -2706,17 +2852,31 @@ png_image_read_colormap(png_voidp argument)
else
{
unsigned int alpha;
/* Must compose the PNG file color in the color-map entry
* on the sRGB color in 'back'.
*/
png_image_get_sBIT(display);
alpha = update_for_sBIT(trans[i], display->sBIT[3], 8U);
/* Do the sBIT handling here because it only applies to the
* values from the colormap, not the background. Passing
* output_encoding to png_create_colormap_entry prevents
* this being duplicated.
*/
png_create_colormap_entry(display, i,
png_colormap_compose(display, colormap[i].red, P_FILE,
trans[i], back_r, output_encoding),
png_colormap_compose(display, colormap[i].green, P_FILE,
trans[i], back_g, output_encoding),
png_colormap_compose(display, colormap[i].blue, P_FILE,
trans[i], back_b, output_encoding),
output_encoding == P_LINEAR ? trans[i] * 257U :
png_colormap_compose(display, colormap[i].red,
display->sBIT[0], P_FILE, alpha, back_r,
output_encoding),
png_colormap_compose(display, colormap[i].green,
display->sBIT[1], P_FILE, alpha, back_g,
output_encoding),
png_colormap_compose(display, colormap[i].blue,
display->sBIT[2], P_FILE, alpha, back_b,
output_encoding),
output_encoding == P_LINEAR ?
update_for_sBIT(alpha*257U, display->sBIT[3], 16U) :
trans[i],
output_encoding);
}

View File

@ -882,10 +882,7 @@ png_do_expand_lbd_gray(png_transformp *transform, png_transform_controlp tc)
if (bit_depth > 1U /* irrelevant for bit depth 1 */ &&
!(tc->invalid_info & PNG_INFO_sBIT) &&
tc->sBIT_G > 0U/*SAFETY*/ && tc->sBIT_G < bit_depth)
{
insignificant_bits = bit_depth - tc->sBIT_G;
UNTESTED
}
# endif /* READ_sBIT */
# ifdef PNG_READ_tRNS_SUPPORTED
@ -949,10 +946,7 @@ png_do_expand_lbd_gray(png_transformp *transform, png_transform_controlp tc)
* of 1 bit gray + 1 bit alpha (transparency):
*/
if (insignificant_bits /* only 1 bit significant */)
{
*--dp = PNG_BYTE((pixel >> 1) * 255U);
UNTESTED
}
else
# endif
@ -990,10 +984,7 @@ png_do_expand_lbd_gray(png_transformp *transform, png_transform_controlp tc)
* below.
*/
if (insignificant_bits)
{
pixel = ((pixel>>insignificant_bits) * 255U + (div>>1)) / div;
UNTESTED
}
else
# endif
@ -2142,10 +2133,10 @@ png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
}
#endif /* UNUSED */
/* libpng-1.7.0: this internal function converts an n-bit input value to an
/* libpng-1.7.0: this private function converts an n-bit input value to an
* m-bit output value.
*/
static unsigned int
unsigned int
png_gamma_nxmbit_correct(unsigned int value, png_fixed_point gamma_val,
unsigned int n/*input bits*/, unsigned int m/*output bits */)
{
@ -2186,21 +2177,6 @@ png_gamma_nxmbit_correct(unsigned int value, png_fixed_point gamma_val,
}
}
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
png_uint_16
png_gamma_16bit_correct(png_const_structrp png_ptr, unsigned int value,
png_fixed_point gamma_val)
{
/* This is a hook into this code for use by the simplified API (only) */
return png_check_u16(png_ptr,
png_gamma_nxmbit_correct(value, gamma_val, 16U, 16U));
PNG_UNUSED(png_ptr)
}
#endif /* SIMPLIFIED_READ */
#undef png_gamma_16bit_correct /* circumvent the prefix handling */
#define png_gamma_16bit_correct NOT_USED_HERE /* for checking */
#if 0 /*UNUSED*/
static unsigned int
png_gamma_sbit_correct(unsigned int value, png_fixed_point gamma_val,
@ -4899,9 +4875,12 @@ png_do_background_alpha_GA(png_transformp *transform, png_transform_controlp tc)
const int compose = tr->st.compose_background;
affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_GA &&
tr->st.background_bit_depth == 16U &&
(tr->st.background_gamma == tc->gamma ||
tr->st.background_gamma == 0));
tr->st.background_bit_depth == 16U);
/* If gamma transforms are eliminated this might fail: */
debug(tr->st.background_gamma == tc->gamma ||
tr->st.background_gamma == 0 ||
tc->sBIT_G == 1);
tc->sp = tc->dp; /* nothing else changes */
@ -4968,9 +4947,11 @@ png_do_background_alpha_RGBA(png_transformp *transform,
const int compose = tr->st.compose_background;
affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_RGBA &&
tr->st.background_bit_depth == 16U &&
(tr->st.background_gamma == tc->gamma ||
tr->st.background_gamma == 0));
tr->st.background_bit_depth == 16U);
debug(tr->st.background_gamma == tc->gamma ||
tr->st.background_gamma == 0 ||
(tc->sBIT_R == 1 && tc->sBIT_G == 1 && tc->sBIT_B == 1));
tc->sp = tc->dp; /* nothing else changes */