[devel] Clean up ALPHA flags and transformations

This commit is contained in:
John Bowler 2011-02-12 09:00:16 -06:00 committed by Glenn Randers-Pehrson
parent 5432c01ffd
commit 9b872f4cf9
6 changed files with 111 additions and 164 deletions

View File

@ -1026,7 +1026,7 @@ png_push_process_row(png_structp png_ptr)
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
#ifdef PNG_READ_INTERLACING_SUPPORTED

View File

@ -340,8 +340,8 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */
#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */
/* 0x200000L unused */
/* 0x400000L unused */
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000L /* Added to libpng-1.4.0 */
/* 0x1000000L unused */
/* 0x2000000L unused */
@ -772,8 +772,8 @@ PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
png_bytep row, png_uint_32 flags));
PNG_EXTERN void png_do_strip_channel PNGARG((png_row_infop row_info,
png_bytep row, int at_start));
#endif
#ifdef PNG_16BIT_SUPPORTED

View File

@ -702,7 +702,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
#endif
if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
#ifdef PNG_READ_INTERLACING_SUPPORTED

View File

@ -149,7 +149,7 @@ png_set_strip_alpha(png_structp png_ptr)
if (png_ptr == NULL)
return;
png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
png_ptr->transformations |= PNG_STRIP_ALPHA;
}
#endif
@ -1073,7 +1073,7 @@ png_init_read_transformations(png_structp png_ptr)
*/
png_ptr->transformations &= ~PNG_BACKGROUND;
png_ptr->transformations &= ~PNG_GAMMA;
png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
png_ptr->transformations |= PNG_STRIP_ALPHA;
}
/* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
@ -1207,7 +1207,7 @@ png_init_read_transformations(png_structp png_ptr)
/* Handled alpha, still need to strip the channel. */
png_ptr->transformations &= ~PNG_BACKGROUND;
png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
png_ptr->transformations |= PNG_STRIP_ALPHA;
}
#endif /* PNG_READ_BACKGROUND_SUPPORTED */
@ -1353,7 +1353,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
info_ptr->channels = 1;
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
if (png_ptr->transformations & PNG_STRIP_ALPHA)
info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
#endif
@ -1454,9 +1454,11 @@ png_do_read_transformations(png_structp png_ptr)
#endif
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
(png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1,
0/*!at_start, because SWAP_ALPHA happens later*/);
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED

View File

@ -424,170 +424,115 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
/* Remove filler or alpha byte(s) */
/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
* somewhat weird combination of flags to determine what to do. All the calls
* to png_do_strip_filler are changed in 1.5.2 to call this instead with the
* correct arguments.
*
* The routine isn't general - the channel must be the channel at the start or
* end (not in the middle) of each pixel.
*/
void /* PRIVATE */
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
{
png_debug(1, "in png_do_strip_filler");
png_bytep sp = row; /* source pointer */
png_bytep dp = row; /* destination pointer */
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
/* At the start sp will point to the first byte to copy and dp to where
* it is copied to. ep always points just beyond the end of the row, so
* the loop simply copies (channels-1) channels until sp reaches ep.
*/
/* GA, GX, XG cases */
if (row_info->channels == 2)
{
png_bytep sp = row;
png_bytep dp = row;
png_uint_32 row_width = row_info->width;
png_uint_32 i;
if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 4)
if (row_info->bit_depth == 8)
{
if (row_info->bit_depth == 8)
{
/* This converts from RGBX or RGBA to RGB */
if (flags & PNG_FLAG_FILLER_AFTER)
{
dp += 3; sp += 4;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp++;
}
}
if (at_start) /* Skip initial filler */
++sp;
else /* Skip initial channels and, for sp, the filler */
sp += 2, ++dp;
/* This converts from XRGB or ARGB to RGB */
else
{
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 24;
row_info->rowbytes = row_width * 3;
}
/* For a 1 pixel wide image there is nothing to do */
while (sp < ep)
*dp++ = *sp, sp += 2;
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
sp += 8; dp += 6;
for (i = 1; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
for (i = 0; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 48;
row_info->rowbytes = row_width * 6;
}
row_info->channels = 3;
row_info->pixel_depth = 8;
}
else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
(row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 2)
else if (row_info->bit_depth == 16)
{
if (row_info->bit_depth == 8)
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from GX or GA to G */
for (i = 0; i < row_width; i++)
{
*dp++ = *sp++;
sp++;
}
}
if (at_start)
sp += 2;
else
sp += 4, dp += 2;
else
{
/* This converts from XG or AG to G */
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
}
}
while (sp < ep)
*dp++ = *sp++, *dp++ = *sp, sp += 3;
row_info->pixel_depth = 8;
row_info->rowbytes = row_width;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from GGXX or GGAA to GG */
sp += 4; dp += 2;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
/* This converts from XXGG or AAGG to GG */
for (i = 0; i < row_width; i++)
{
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 16;
row_info->rowbytes = row_width * 2;
}
row_info->channels = 1;
row_info->pixel_depth = 16;
}
if (flags & PNG_FLAG_STRIP_ALPHA)
row_info->color_type = (png_byte)(row_info->color_type &
~PNG_COLOR_MASK_ALPHA);
else
return; /* bad bit depth */
row_info->channels = 1;
/* Finally fix the color type if it records an alpha channel */
if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
row_info->color_type = PNG_COLOR_TYPE_GRAY;
}
/* RGBA, RGBX, XRGB cases */
else if (row_info->channels == 4)
{
if (row_info->bit_depth == 8)
{
if (at_start) /* Skip initial filler */
++sp;
else /* Skip initial channels and, for sp, the filler */
sp += 4, dp += 3;
/* Note that the loop adds 3 to dp and 4 to sp each time. */
while (sp < ep)
*dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
row_info->pixel_depth = 24;
}
else if (row_info->bit_depth == 16)
{
if (at_start)
sp += 2;
else
sp += 8, dp += 6;
while (sp < ep)
{
/* Copy 6 bytes, skip 2 */
*dp++ = *sp++, *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp, sp += 3;
}
row_info->pixel_depth = 48;
}
else
return; /* bad bit depth */
row_info->channels = 3;
/* Finally fix the color type if it records an alpha channel */
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
row_info->color_type = PNG_COLOR_TYPE_RGB;
}
else
return; /* The filler channel has gone already */
/* Fix the rowbytes value. */
row_info->rowbytes = dp-row;
}
#endif

View File

@ -44,8 +44,8 @@ png_do_write_transformations(png_structp png_ptr)
#ifdef PNG_WRITE_FILLER_SUPPORTED
if (png_ptr->transformations & PNG_FILLER)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->flags);
png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1,
!(png_ptr->flags & PNG_FILLER_AFTER));
#endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED