mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
updating for APNG 0.10. splitting out render_op in to dispose_op and blend_op. bug 257197. r=asmith13, sr=vlad
This commit is contained in:
parent
b161ae9326
commit
8c349ca074
@ -909,7 +909,8 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||
png_uint_32 next_frame_y_offset;
|
||||
png_uint_16 next_frame_delay_num;
|
||||
png_uint_16 next_frame_delay_den;
|
||||
png_byte next_frame_render_op;
|
||||
png_byte next_frame_dispose_op;
|
||||
png_byte next_frame_blend_op;
|
||||
#endif
|
||||
|
||||
} png_info;
|
||||
@ -1411,11 +1412,14 @@ struct png_struct_def
|
||||
/* For png_struct.apng_flags: */
|
||||
#define PNG_FIRST_FRAME_HIDDEN 0x0001
|
||||
|
||||
/* dispose_op flags from render_op inside fcTL */
|
||||
#define PNG_RENDER_OP_DISPOSE_MASK 0x07
|
||||
#define PNG_RENDER_OP_DISPOSE_NONE 0x01
|
||||
#define PNG_RENDER_OP_DISPOSE_BACKGROUND 0x02
|
||||
#define PNG_RENDER_OP_DISPOSE_PREVIOUS 0x04
|
||||
/* dispose_op flags from inside fcTL */
|
||||
#define PNG_DISPOSE_OP_NONE 0x00
|
||||
#define PNG_DISPOSE_OP_BACKGROUND 0x01
|
||||
#define PNG_DISPOSE_OP_PREVIOUS 0x02
|
||||
|
||||
/* blend_op flags from inside fcTL */
|
||||
#define PNG_BLEND_OP_SOURCE 0x00
|
||||
#define PNG_BLEND_OP_OVER 0x01
|
||||
|
||||
/* This triggers a compiler error in png.c, if png.c and png.h
|
||||
* do not agree upon the version number.
|
||||
@ -1740,8 +1744,8 @@ extern PNG_EXPORT (void,png_write_frame_head) PNGARG((png_structp png_ptr,
|
||||
png_infop png_info, png_bytepp row_pointers,
|
||||
png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte render_op,
|
||||
png_byte first_frame_hidden));
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
|
||||
png_byte blend_op, png_byte first_frame_hidden));
|
||||
|
||||
extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr,
|
||||
png_infop png_info));
|
||||
@ -2441,17 +2445,19 @@ extern PNG_EXPORT(png_uint_32,png_get_num_iterations)
|
||||
extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
|
||||
png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
|
||||
png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *render_op));
|
||||
png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
|
||||
png_byte *blend_op));
|
||||
extern PNG_EXPORT(png_uint_32,png_set_next_frame_fcTL)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
|
||||
png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte render_op));
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
|
||||
png_byte blend_op));
|
||||
extern PNG_EXPORT(void,png_ensure_fcTL_is_valid)
|
||||
PNGARG((png_structp png_ptr,
|
||||
png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den,
|
||||
png_byte render_op));
|
||||
png_byte dispose_op, png_byte blend_op));
|
||||
extern PNG_EXPORT(png_uint_32,png_get_next_frame_width)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr));
|
||||
extern PNG_EXPORT(png_uint_32,png_get_next_frame_height)
|
||||
@ -2464,7 +2470,9 @@ extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_num)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr));
|
||||
extern PNG_EXPORT(png_uint_16,png_get_next_frame_delay_den)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr));
|
||||
extern PNG_EXPORT(png_byte,png_get_next_frame_render_op)
|
||||
extern PNG_EXPORT(png_byte,png_get_next_frame_dispose_op)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr));
|
||||
extern PNG_EXPORT(png_byte,png_get_next_frame_blend_op)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr));
|
||||
extern PNG_EXPORT(png_byte,png_first_frame_is_hidden)
|
||||
PNGARG((png_structp png_ptr, png_infop info_ptr));
|
||||
@ -3233,7 +3241,8 @@ PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
|
||||
PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
|
||||
png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte render_op));
|
||||
png_uint_16 delay_num, png_uint_16 delay_den,
|
||||
png_byte dispose_op, png_byte blend_op));
|
||||
#endif
|
||||
|
||||
/* Called when finished processing a row of data */
|
||||
|
@ -838,7 +838,7 @@ png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 *width, png_uint_32 *height,
|
||||
png_uint_32 *x_offset, png_uint_32 *y_offset,
|
||||
png_uint_16 *delay_num, png_uint_16 *delay_den,
|
||||
png_byte *render_op)
|
||||
png_byte *dispose_op, png_byte *blend_op)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "fcTL");
|
||||
|
||||
@ -846,7 +846,8 @@ png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
|
||||
(info_ptr->valid & PNG_INFO_fcTL) &&
|
||||
width != NULL && height != NULL &&
|
||||
x_offset != NULL && x_offset != NULL &&
|
||||
delay_num != NULL && delay_den != NULL && render_op != NULL)
|
||||
delay_num != NULL && delay_den != NULL &&
|
||||
dispose_op != NULL && blend_op != NULL)
|
||||
{
|
||||
*width = info_ptr->next_frame_width;
|
||||
*height = info_ptr->next_frame_height;
|
||||
@ -854,7 +855,8 @@ png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
|
||||
*y_offset = info_ptr->next_frame_y_offset;
|
||||
*delay_num = info_ptr->next_frame_delay_num;
|
||||
*delay_den = info_ptr->next_frame_delay_den;
|
||||
*render_op = info_ptr->next_frame_render_op;
|
||||
*dispose_op = info_ptr->next_frame_dispose_op;
|
||||
*blend_op = info_ptr->next_frame_blend_op;
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -922,12 +924,22 @@ png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_next_frame_render_op(png_structp png_ptr, png_infop info_ptr)
|
||||
png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
png_debug(1, "in png_get_next_frame_render_op()\n");
|
||||
png_debug(1, "in png_get_next_frame_dispose_op()\n");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return (info_ptr->next_frame_render_op);
|
||||
return (info_ptr->next_frame_dispose_op);
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
png_debug(1, "in png_get_next_frame_blend_op()\n");
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return (info_ptr->next_frame_blend_op);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -2190,14 +2190,15 @@ png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
|
||||
void /* PRIVATE */
|
||||
png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
|
||||
{
|
||||
png_byte data[21];
|
||||
png_byte data[22];
|
||||
png_uint_32 width;
|
||||
png_uint_32 height;
|
||||
png_uint_32 x_offset;
|
||||
png_uint_32 y_offset;
|
||||
png_uint_16 delay_num;
|
||||
png_uint_16 delay_den;
|
||||
png_byte render_op;
|
||||
png_byte dispose_op;
|
||||
png_byte blend_op;
|
||||
|
||||
png_debug(1, "in png_handle_fcTL\n");
|
||||
|
||||
@ -2220,7 +2221,7 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
|
||||
png_crc_finish(png_ptr, length);
|
||||
return;
|
||||
}
|
||||
else if (length != 25)
|
||||
else if (length != 26)
|
||||
{
|
||||
png_warning(png_ptr, "fcTL with invalid length skipped");
|
||||
png_crc_finish(png_ptr, length);
|
||||
@ -2229,7 +2230,7 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
|
||||
|
||||
png_ensure_sequence_number(png_ptr, length);
|
||||
|
||||
png_crc_read(png_ptr, data, 21);
|
||||
png_crc_read(png_ptr, data, 22);
|
||||
png_crc_finish(png_ptr, 0);
|
||||
|
||||
width = png_get_uint_31(png_ptr, data);
|
||||
@ -2238,7 +2239,8 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
|
||||
y_offset = png_get_uint_31(png_ptr, data + 12);
|
||||
delay_num = png_get_uint_16(data + 16);
|
||||
delay_den = png_get_uint_16(data + 18);
|
||||
render_op = data[20];
|
||||
dispose_op = data[20];
|
||||
blend_op = data[21];
|
||||
|
||||
if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
|
||||
png_error(png_ptr, "fcTL for the first frame must have zero offset");
|
||||
@ -2250,7 +2252,7 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
|
||||
/* the set function will do more error checking */
|
||||
png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
|
||||
x_offset, y_offset, delay_num, delay_den,
|
||||
render_op);
|
||||
dispose_op, blend_op);
|
||||
|
||||
png_read_reinit(png_ptr, info_ptr);
|
||||
|
||||
|
@ -1046,7 +1046,7 @@ png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den,
|
||||
png_byte render_op)
|
||||
png_byte dispose_op, png_byte blend_op)
|
||||
{
|
||||
png_debug1(1, "in %s storage function\n", "fcTL");
|
||||
|
||||
@ -1059,7 +1059,7 @@ png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
|
||||
}
|
||||
|
||||
png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
|
||||
delay_num, delay_den, render_op);
|
||||
delay_num, delay_den, dispose_op, blend_op);
|
||||
|
||||
info_ptr->next_frame_width = width;
|
||||
info_ptr->next_frame_height = height;
|
||||
@ -1067,7 +1067,8 @@ png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
|
||||
info_ptr->next_frame_y_offset = y_offset;
|
||||
info_ptr->next_frame_delay_num = delay_num;
|
||||
info_ptr->next_frame_delay_den = delay_den;
|
||||
info_ptr->next_frame_render_op = render_op;
|
||||
info_ptr->next_frame_dispose_op = dispose_op;
|
||||
info_ptr->next_frame_blend_op = blend_op;
|
||||
|
||||
info_ptr->valid |= PNG_INFO_fcTL;
|
||||
|
||||
@ -1079,7 +1080,7 @@ png_ensure_fcTL_is_valid(png_structp png_ptr,
|
||||
png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den,
|
||||
png_byte render_op)
|
||||
png_byte dispose_op, png_byte blend_op)
|
||||
{
|
||||
if (width > png_ptr->first_frame_width ||
|
||||
height > png_ptr->first_frame_height)
|
||||
@ -1093,23 +1094,25 @@ png_ensure_fcTL_is_valid(png_structp png_ptr,
|
||||
png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
|
||||
if (y_offset > PNG_UINT_31_MAX)
|
||||
png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
|
||||
if (render_op & 0xF0)
|
||||
/* Bits 4 through 7 are reserved and must be set to zero (APNG spec) */
|
||||
png_error(png_ptr, "invalid render_op in fcTL");
|
||||
if (render_op & 0x08 && png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
png_error(png_ptr, "APNG_RENDER_OP_BLEND_FLAG is not valid for "
|
||||
"color type 'greyscale without alpha'");
|
||||
if ((render_op & 0x08) &&
|
||||
(png_ptr->color_type & PNG_COLOR_MASK_COLOR) &&
|
||||
!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA))
|
||||
png_error(png_ptr, "APNG_RENDER_OP_BLEND_FLAG is not valid for "
|
||||
"color type 'truecolor without alpha'");
|
||||
if (!(render_op & PNG_RENDER_OP_DISPOSE_MASK))
|
||||
png_error(png_ptr, "no DISPOSE_ flag found in fcTL");
|
||||
if ( (render_op & PNG_RENDER_OP_DISPOSE_MASK) != PNG_RENDER_OP_DISPOSE_NONE &&
|
||||
(render_op & PNG_RENDER_OP_DISPOSE_MASK) != PNG_RENDER_OP_DISPOSE_BACKGROUND &&
|
||||
(render_op & PNG_RENDER_OP_DISPOSE_MASK) != PNG_RENDER_OP_DISPOSE_PREVIOUS)
|
||||
png_error(png_ptr, "multiple DISPOSE_ flags set in fcTL");
|
||||
|
||||
if (dispose_op != PNG_DISPOSE_OP_NONE &&
|
||||
dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
|
||||
dispose_op != PNG_DISPOSE_OP_PREVIOUS)
|
||||
png_error(png_ptr, "invalid dispose_op in fcTL");
|
||||
|
||||
if (blend_op != PNG_BLEND_OP_SOURCE &&
|
||||
blend_op != PNG_BLEND_OP_OVER)
|
||||
png_error(png_ptr, "invalid blend_op in fcTL");
|
||||
|
||||
if (blend_op == PNG_BLEND_OP_OVER) {
|
||||
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for "
|
||||
"color type 'greyscale without alpha'");
|
||||
else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) &&
|
||||
!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA))
|
||||
png_error(png_ptr, "PNG_BLEND_OP_OVER is not valid for "
|
||||
"color type 'truecolor without alpha'");
|
||||
}
|
||||
}
|
||||
#endif /* PNG_APNG_SUPPORTED */
|
||||
|
||||
|
@ -1524,8 +1524,8 @@ void PNGAPI
|
||||
png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
|
||||
png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte render_op,
|
||||
png_byte first_frame_hidden)
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
|
||||
png_byte blend_op, png_byte first_frame_hidden)
|
||||
{
|
||||
png_debug(1, "in png_write_frame_head\n");
|
||||
|
||||
@ -1540,7 +1540,7 @@ png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
|
||||
|
||||
if ( !(png_ptr->num_frames_written == 0 && first_frame_hidden) )
|
||||
png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
|
||||
delay_num, delay_den, render_op);
|
||||
delay_num, delay_den, dispose_op, blend_op);
|
||||
}
|
||||
|
||||
void PNGAPI
|
||||
|
@ -1754,12 +1754,12 @@ png_write_acTL(png_structp png_ptr,
|
||||
void /* PRIVATE */
|
||||
png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
|
||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte render_op)
|
||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, png_byte blend_op)
|
||||
{
|
||||
#ifdef PNG_USE_LOCAL_ARRAYS
|
||||
PNG_fcTL;
|
||||
#endif
|
||||
png_byte data[25];
|
||||
png_byte data[26];
|
||||
|
||||
png_debug(1, "in png_write_fcTL\n");
|
||||
|
||||
@ -1773,7 +1773,7 @@ png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
|
||||
|
||||
/* more error checking */
|
||||
png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
|
||||
delay_num, delay_den, render_op);
|
||||
delay_num, delay_den, dispose_op, blend_op);
|
||||
|
||||
png_save_uint_32(data, png_ptr->next_seq_num);
|
||||
png_save_uint_32(data + 4, width);
|
||||
@ -1782,9 +1782,10 @@ png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
|
||||
png_save_uint_32(data + 16, y_offset);
|
||||
png_save_uint_16(data + 20, delay_num);
|
||||
png_save_uint_16(data + 22, delay_den);
|
||||
data[24] = render_op;
|
||||
data[24] = dispose_op;
|
||||
data[25] = blend_op;
|
||||
|
||||
png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)25);
|
||||
png_write_chunk(png_ptr, (png_bytep)png_fcTL, data, (png_size_t)26);
|
||||
|
||||
png_ptr->next_seq_num++;
|
||||
}
|
||||
|
@ -114,13 +114,15 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
void nsPNGDecoder::SetAnimFrameInfo()
|
||||
{
|
||||
png_uint_16 delay_num, delay_den; /* in seconds */
|
||||
png_byte render_op;
|
||||
png_byte dispose_op;
|
||||
PRInt32 timeout; /* in milliseconds */
|
||||
|
||||
delay_num = png_get_next_frame_delay_num(mPNG, mInfo);
|
||||
delay_den = png_get_next_frame_delay_den(mPNG, mInfo);
|
||||
render_op = png_get_next_frame_render_op(mPNG, mInfo);
|
||||
|
||||
dispose_op = png_get_next_frame_dispose_op(mPNG, mInfo);
|
||||
|
||||
// XXX need to handle blend_op here!
|
||||
|
||||
if (delay_num == 0) {
|
||||
timeout = 0; // gfxImageFrame::SetTimeout() will set to a minimum
|
||||
} else {
|
||||
@ -134,9 +136,9 @@ void nsPNGDecoder::SetAnimFrameInfo()
|
||||
}
|
||||
mFrame->SetTimeout(timeout);
|
||||
|
||||
if (render_op & PNG_RENDER_OP_DISPOSE_PREVIOUS)
|
||||
if (dispose_op == PNG_DISPOSE_OP_PREVIOUS)
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeRestorePrevious);
|
||||
else if (render_op & PNG_RENDER_OP_DISPOSE_BACKGROUND)
|
||||
else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClear);
|
||||
else
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeKeep);
|
||||
|
Loading…
Reference in New Issue
Block a user