[libpng15] Fixes to alpha swap on read, simplified write and filler add code
This commit is contained in:
parent
d4973837b2
commit
e6fb691c49
28
pngread.c
28
pngread.c
@ -1804,10 +1804,12 @@ png_image_read_end(png_voidp argument)
|
||||
else /* output needs an alpha channel */
|
||||
{
|
||||
/* This is tricky because it happens before the swap operation has
|
||||
* been accomplished, so always add the alpha channel after the
|
||||
* component channels.
|
||||
* been accomplished however the swap does *not* swap the added
|
||||
* alpha channel (weird API), so it must be added in the correct
|
||||
* place.
|
||||
*/
|
||||
png_uint_32 filler; /* opaque filler */
|
||||
int where;
|
||||
|
||||
if (linear)
|
||||
filler = 65535;
|
||||
@ -1815,9 +1817,21 @@ png_image_read_end(png_voidp argument)
|
||||
else
|
||||
filler = 255;
|
||||
|
||||
png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
|
||||
# ifdef PNG_FORMAT_AFIRST_SUPPORTED
|
||||
if (format & PNG_FORMAT_FLAG_AFIRST)
|
||||
{
|
||||
where = PNG_FILLER_BEFORE;
|
||||
change &= ~PNG_FORMAT_FLAG_AFIRST;
|
||||
}
|
||||
|
||||
else
|
||||
# endif
|
||||
where = PNG_FILLER_AFTER;
|
||||
|
||||
png_set_add_alpha(png_ptr, filler, where);
|
||||
}
|
||||
|
||||
/* This stops the (irrelevant) call to swap_alpha below. */
|
||||
change &= ~PNG_FORMAT_FLAG_ALPHA;
|
||||
}
|
||||
|
||||
@ -1841,7 +1855,7 @@ png_image_read_end(png_voidp argument)
|
||||
}
|
||||
|
||||
# ifdef PNG_FORMAT_BGR_SUPPORTED
|
||||
if (format & PNG_FORMAT_FLAG_BGR)
|
||||
if (change & PNG_FORMAT_FLAG_BGR)
|
||||
{
|
||||
/* Check only the output format; PNG is never BGR, don't do this if
|
||||
* the output is gray, but fix up the 'format' value in that case.
|
||||
@ -1857,7 +1871,7 @@ png_image_read_end(png_voidp argument)
|
||||
# endif
|
||||
|
||||
# ifdef PNG_FORMAT_AFIRST_SUPPORTED
|
||||
if (format & PNG_FORMAT_FLAG_AFIRST)
|
||||
if (change & PNG_FORMAT_FLAG_AFIRST)
|
||||
{
|
||||
/* Only relevant if there is an alpha channel - it's particularly
|
||||
* important to handle this correctly because do_local_compose may
|
||||
@ -1924,7 +1938,9 @@ png_image_read_end(png_voidp argument)
|
||||
# endif
|
||||
|
||||
# ifdef PNG_FORMAT_AFIRST_SUPPORTED
|
||||
if (png_ptr->transformations & PNG_SWAP_ALPHA)
|
||||
if (png_ptr->transformations & PNG_SWAP_ALPHA ||
|
||||
((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
|
||||
(png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
|
||||
info_format |= PNG_FORMAT_FLAG_AFIRST;
|
||||
# endif
|
||||
|
||||
|
18
pngrutil.c
18
pngrutil.c
@ -3900,6 +3900,16 @@ png_read_start_row(png_structp png_ptr)
|
||||
|
||||
max_pixel_depth = png_ptr->pixel_depth;
|
||||
|
||||
/* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
|
||||
* calculations to calculate the final pixel depth, then
|
||||
* png_do_read_transforms actually does the transforms. This means that the
|
||||
* code which effectively calculates this value is actually repeated in three
|
||||
* separate places. They must all match. Innocent changes to the order of
|
||||
* transformations can and will break libpng in a way that causes memory
|
||||
* overwrites.
|
||||
*
|
||||
* TODO: fix this.
|
||||
*/
|
||||
#ifdef PNG_READ_PACK_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
|
||||
max_pixel_depth = 8;
|
||||
@ -3958,10 +3968,7 @@ png_read_start_row(png_structp png_ptr)
|
||||
#ifdef PNG_READ_FILLER_SUPPORTED
|
||||
if (png_ptr->transformations & (PNG_FILLER))
|
||||
{
|
||||
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
max_pixel_depth = 32;
|
||||
|
||||
else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
if (max_pixel_depth <= 8)
|
||||
max_pixel_depth = 16;
|
||||
@ -3970,7 +3977,8 @@ png_read_start_row(png_structp png_ptr)
|
||||
max_pixel_depth = 32;
|
||||
}
|
||||
|
||||
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
|
||||
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
|
||||
png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
if (max_pixel_depth <= 32)
|
||||
max_pixel_depth = 32;
|
||||
|
21
pngwrite.c
21
pngwrite.c
@ -1805,7 +1805,7 @@ png_write_image_16bit(png_voidp argument)
|
||||
++out_ptr;
|
||||
}
|
||||
|
||||
png_write_row(png_ptr, (png_bytep)output_row);
|
||||
png_write_row(png_ptr, display->local_row);
|
||||
input_row += display->row_bytes/(sizeof (png_uint_16));
|
||||
}
|
||||
|
||||
@ -1911,7 +1911,7 @@ png_write_image_8bit(png_voidp argument)
|
||||
++out_ptr;
|
||||
} /* while out_ptr < row_end */
|
||||
|
||||
png_write_row(png_ptr, output_row);
|
||||
png_write_row(png_ptr, display->local_row);
|
||||
input_row += display->row_bytes/(sizeof (png_uint_16));
|
||||
} /* while y */
|
||||
}
|
||||
@ -1998,11 +1998,9 @@ png_image_write_main(png_voidp argument)
|
||||
|
||||
/* Now set up the data transformations (*after* the header is written),
|
||||
* remove the handled transformations from the 'format' flags for checking.
|
||||
*
|
||||
* First check for a little endian system if writing 16 bit files.
|
||||
*/
|
||||
format &= ~(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
|
||||
PNG_FORMAT_FLAG_ALPHA);
|
||||
|
||||
/* Check for a little endian system if writing 16 bit files. */
|
||||
if (write_16bit)
|
||||
{
|
||||
PNG_CONST png_uint_16 le = 0x0001;
|
||||
@ -2014,7 +2012,8 @@ png_image_write_main(png_voidp argument)
|
||||
# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
|
||||
if (format & PNG_FORMAT_FLAG_BGR)
|
||||
{
|
||||
png_set_bgr(png_ptr);
|
||||
if (format & PNG_FORMAT_FLAG_COLOR)
|
||||
png_set_bgr(png_ptr);
|
||||
format &= ~PNG_FORMAT_FLAG_BGR;
|
||||
}
|
||||
# endif
|
||||
@ -2022,13 +2021,15 @@ png_image_write_main(png_voidp argument)
|
||||
# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
||||
if (format & PNG_FORMAT_FLAG_AFIRST)
|
||||
{
|
||||
png_set_swap_alpha(png_ptr);
|
||||
if (format & PNG_FORMAT_FLAG_ALPHA)
|
||||
png_set_swap_alpha(png_ptr);
|
||||
format &= ~PNG_FORMAT_FLAG_AFIRST;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* That should have handled all the transforms. */
|
||||
if (format != 0)
|
||||
/* That should have handled all (both) the transforms. */
|
||||
if ((format & ~(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
|
||||
PNG_FORMAT_FLAG_ALPHA)) != 0)
|
||||
png_error(png_ptr, "png_write_image: unsupported transformation");
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user