various small fixes for APNG. bug 257197. patch from asmith15@learn.senecac.on.ca. r=me

This commit is contained in:
pavlov@pavlov.net 2007-04-19 13:40:53 -07:00
parent fb9ff8dfde
commit 30e525feb6
10 changed files with 80 additions and 59 deletions

View File

@ -1,6 +1,8 @@
Changes made to pristine png source by mozilla.org developers.
2007/03/20 -- Added support for APNG
2006/06/27 -- Synced with libpng-1.2.12 tree
2004/10/07 -- Synced with libpng-1.2.7 tree

View File

@ -918,8 +918,8 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
#endif
#if defined(PNG_APNG_SUPPORTED)
png_uint_32 num_frames;
png_uint_32 num_iterations;
png_uint_32 num_frames; /* including default image */
png_uint_32 num_plays;
png_uint_32 next_frame_width;
png_uint_32 next_frame_height;
png_uint_32 next_frame_x_offset;
@ -1424,7 +1424,7 @@ struct png_struct_def
#endif
#if defined(PNG_WRITE_APNG_SUPPORTED)
png_uint_32 num_frames_to_write; /* copy of info_ptr->num_frames */
png_uint_32 num_frames_to_write;
png_uint_32 num_frames_written;
#endif
@ -1766,7 +1766,7 @@ extern PNG_EXPORT (void,png_write_frame_head) 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 dispose_op,
png_byte blend_op, png_byte first_frame_hidden));
png_byte blend_op));
extern PNG_EXPORT (void,png_write_frame_tail) PNGARG((png_structp png_ptr,
png_infop png_info));
@ -2455,12 +2455,12 @@ extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
#if defined(PNG_APNG_SUPPORTED)
extern PNG_EXPORT(png_uint_32,png_get_acTL) PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_iterations));
png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
extern PNG_EXPORT(png_uint_32,png_set_acTL) PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_iterations));
png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
extern PNG_EXPORT(png_uint_32,png_get_num_frames) PNGARG((png_structp png_ptr,
png_infop info_ptr));
extern PNG_EXPORT(png_uint_32,png_get_num_iterations)
extern PNG_EXPORT(png_uint_32,png_get_num_plays)
PNGARG((png_structp png_ptr, png_infop info_ptr));
extern PNG_EXPORT(png_uint_32,png_get_next_frame_fcTL)
@ -2495,8 +2495,10 @@ 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)
extern PNG_EXPORT(png_byte,png_get_first_frame_is_hidden)
PNGARG((png_structp png_ptr, png_infop info_ptr));
extern PNG_EXPORT(png_uint_32,png_set_first_frame_is_hidden)
PNGARG((png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
#endif /* PNG_APNG_SUPPORTED */
#if defined(PNG_READ_APNG_SUPPORTED)
@ -3259,7 +3261,7 @@ PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
#if defined(PNG_WRITE_APNG_SUPPORTED)
PNG_EXTERN void png_write_acTL PNGARG((png_structp png_ptr,
png_uint_32 num_frames, png_uint_32 num_iterations));
png_uint_32 num_frames, png_uint_32 num_plays));
PNG_EXTERN void png_write_fcTL PNGARG((png_structp png_ptr,
png_uint_32 width, png_uint_32 height,
@ -3553,6 +3555,7 @@ PNG_EXTERN void png_handle_acTL PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
PNG_EXTERN void png_handle_fcTL PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
PNG_EXTERN void png_have_info PNGARG((png_structp png_ptr, png_infop info_ptr));
PNG_EXTERN void png_handle_fdAT PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
PNG_EXTERN void png_ensure_sequence_number PNGARG((png_structp png_ptr,

View File

@ -797,16 +797,16 @@ png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
#if defined(PNG_APNG_SUPPORTED)
png_uint_32 PNGAPI
png_get_acTL(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *num_frames, png_uint_32 *num_iterations)
png_uint_32 *num_frames, png_uint_32 *num_plays)
{
png_debug1(1, "in %s retrieval function\n", "acTL");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_acTL) &&
num_frames != NULL && num_iterations != NULL)
num_frames != NULL && num_plays != NULL)
{
*num_frames = info_ptr->num_frames;
*num_iterations = info_ptr->num_iterations;
*num_plays = info_ptr->num_plays;
return (1);
}
@ -824,12 +824,12 @@ png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
}
png_uint_32 PNGAPI
png_get_num_iterations(png_structp png_ptr, png_infop info_ptr)
png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
{
png_debug(1, "in png_get_num_iterations()\n");
png_debug(1, "in png_get_num_plays()\n");
if (png_ptr != NULL && info_ptr != NULL)
return (info_ptr->num_iterations);
return (info_ptr->num_plays);
return (0);
}
@ -944,14 +944,12 @@ png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
}
png_byte PNGAPI
png_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
{
png_debug(1, "in png_first_frame_is_hidden()\n");
if (png_ptr != NULL && info_ptr != NULL &&
info_ptr->valid & PNG_INFO_acTL &&
!(info_ptr->valid & PNG_INFO_fcTL))
return 1;
if (png_ptr != NULL)
return png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN;
return 0;
}

View File

@ -397,6 +397,9 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_error(png_ptr, "Too many IDAT's found");
}
#if defined(PNG_READ_APNG_SUPPORTED)
png_have_info(png_ptr, info_ptr);
#endif
png_ptr->idat_size = png_ptr->push_length;
png_ptr->mode |= PNG_HAVE_IDAT;
png_ptr->process_mode = PNG_READ_IDAT_MODE;

View File

@ -459,6 +459,9 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
!(png_ptr->mode & PNG_HAVE_PLTE))
png_error(png_ptr, "Missing PLTE before IDAT");
#if defined(PNG_READ_APNG_SUPPORTED)
png_have_info(png_ptr, info_ptr);
#endif
png_ptr->idat_size = length;
png_ptr->mode |= PNG_HAVE_IDAT;
break;

View File

@ -2144,7 +2144,7 @@ png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_byte data[8];
png_uint_32 num_frames;
png_uint_32 num_iterations;
png_uint_32 num_plays;
png_uint_32 didSet;
png_debug(1, "in png_handle_acTL\n");
@ -2176,18 +2176,12 @@ png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_crc_finish(png_ptr, 0);
num_frames = png_get_uint_31(png_ptr, data);
num_iterations = png_get_uint_31(png_ptr, data + 4);
num_plays = png_get_uint_31(png_ptr, data + 4);
/* the set function will do error checking on num_frames */
didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_iterations);
didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
if(didSet)
{
png_ptr->mode |= PNG_HAVE_acTL;
/* if there is an fcTL this flag will be unset in png_handle_fcTL() */
if (num_frames > 1)
png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
}
}
void /* PRIVATE */
@ -2260,8 +2254,16 @@ png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
png_read_reinit(png_ptr, info_ptr);
png_ptr->mode |= PNG_HAVE_fcTL;
png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
}
void /* PRIVATE */
png_have_info(png_structp png_ptr, png_infop info_ptr)
{
if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
{
png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
info_ptr->num_frames++;
}
}
void /* PRIVATE */

View File

@ -1001,7 +1001,7 @@ png_set_sPLT(png_structp png_ptr,
#if defined(PNG_APNG_SUPPORTED)
png_uint_32 PNGAPI
png_set_acTL(png_structp png_ptr, png_infop info_ptr,
png_uint_32 num_frames, png_uint_32 num_iterations)
png_uint_32 num_frames, png_uint_32 num_plays)
{
png_debug1(1, "in %s storage function\n", "acTL");
@ -1012,28 +1012,28 @@ png_set_acTL(png_structp png_ptr, png_infop info_ptr,
"or info_ptr ignored");
return (0);
}
if(num_frames == 0)
if (num_frames == 0)
{
png_warning(png_ptr,
"Ignoring attempt to set acTL with num_frames zero");
return (0);
}
if(num_frames > PNG_UINT_31_MAX)
if (num_frames > PNG_UINT_31_MAX)
{
png_warning(png_ptr,
"Ignoring attempt to set acTL with num_frames > 2^31-1");
return (0);
}
if(num_iterations > PNG_UINT_31_MAX)
if (num_plays > PNG_UINT_31_MAX)
{
png_warning(png_ptr,
"Ignoring attempt to set acTL with num_iterations "
"Ignoring attempt to set acTL with num_plays "
"> 2^31-1");
return (0);
}
info_ptr->num_frames = num_frames;
info_ptr->num_iterations = num_iterations;
info_ptr->num_plays = num_plays;
info_ptr->valid |= PNG_INFO_acTL;
@ -1114,6 +1114,23 @@ png_ensure_fcTL_is_valid(png_structp png_ptr,
"color type 'truecolor without alpha'");
}
}
png_uint_32 PNGAPI
png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
png_byte is_hidden)
{
png_debug(1, "in png_first_frame_is_hidden()\n");
if (png_ptr == NULL)
return 0;
if(is_hidden)
png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
else
png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
return 1;
}
#endif /* PNG_APNG_SUPPORTED */
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)

View File

@ -263,7 +263,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
#endif
#if defined(PNG_WRITE_APNG_SUPPORTED)
if (info_ptr->valid & PNG_INFO_acTL)
png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_iterations);
png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
#endif
#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
if (info_ptr->unknown_chunks_num)
@ -1530,7 +1530,7 @@ 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 dispose_op,
png_byte blend_op, png_byte first_frame_hidden)
png_byte blend_op)
{
png_debug(1, "in png_write_frame_head\n");
@ -1543,7 +1543,8 @@ png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
png_write_reinit(png_ptr, info_ptr, width, height);
if ( !(png_ptr->num_frames_written == 0 && first_frame_hidden) )
if ( !(png_ptr->num_frames_written == 0 &&
(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
delay_num, delay_den, dispose_op, blend_op);
}

View File

@ -1752,7 +1752,7 @@ png_write_tIME(png_structp png_ptr, png_timep mod_time)
#if defined(PNG_WRITE_APNG_SUPPORTED)
void /* PRIVATE */
png_write_acTL(png_structp png_ptr,
png_uint_32 num_frames, png_uint_32 num_iterations)
png_uint_32 num_frames, png_uint_32 num_plays)
{
#ifdef PNG_USE_LOCAL_ARRAYS
PNG_acTL;
@ -1761,19 +1761,13 @@ png_write_acTL(png_structp png_ptr,
png_debug(1, "in png_write_acTL\n");
if (num_frames == 0)
png_error(png_ptr, "png_write_acTL: invalid number of frames (0)");
if (num_frames > PNG_UINT_31_MAX)
png_error(png_ptr, "png_write_acTL: invalid number of frames "
"(> 2^31-1)");
if (num_iterations > PNG_UINT_31_MAX)
png_error(png_ptr, "png_write_acTL: invalid number of iterations "
"(> 2^31-1)");
png_ptr->num_frames_to_write = num_frames;
if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
num_frames--;
png_save_uint_32(data, num_frames);
png_save_uint_32(data + 4, num_iterations);
png_save_uint_32(data + 4, num_plays);
png_write_chunk(png_ptr, (png_bytep)png_acTL, data, (png_size_t)8);
}
@ -1781,7 +1775,8 @@ 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 dispose_op, png_byte blend_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;

View File

@ -381,7 +381,7 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL))
png_set_progressive_frame_fn(png_ptr, frame_info_callback, NULL);
if (png_first_frame_is_hidden(png_ptr, info_ptr)) {
if (png_get_first_frame_is_hidden(png_ptr, info_ptr)) {
decoder->apngFlags |= FRAME_HIDDEN;
// create a frame just to get bpr, to allocate interlacebuf
@ -409,7 +409,7 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
}
}
if (png_first_frame_is_hidden(png_ptr, info_ptr))
if (png_get_first_frame_is_hidden(png_ptr, info_ptr))
decoder->mFrame = nsnull;
return;
@ -557,11 +557,8 @@ end_callback(png_structp png_ptr, png_infop info_ptr)
nsPNGDecoder *decoder = NS_STATIC_CAST(nsPNGDecoder*, png_get_progressive_ptr(png_ptr));
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) {
PRInt32 num_iterations = png_get_num_iterations(png_ptr, info_ptr);
if (num_iterations <= 0) /* forever */
num_iterations = -1;
decoder->mImage->SetLoopCount(num_iterations);
PRInt32 num_plays = png_get_num_plays(png_ptr, info_ptr);
decoder->mImage->SetLoopCount(num_plays - 1);
}
if (!(decoder->apngFlags & FRAME_HIDDEN)) {