safer gifload delay array init

- remove assumptions about n_pages
- minor reformatting
This commit is contained in:
John Cupitt 2019-07-06 11:34:20 +01:00
parent 00676a2166
commit 777c360774
3 changed files with 32 additions and 8 deletions

View File

@ -1,6 +1,7 @@
20/6/19 started 8.9.0
- add vips_image_get/set_array_int()
- disable webp alpha output if all frame fill the canvas and are solid
- support arrays of delays for animated images [deftomat]
24/5/19 started 8.8.1
- improve realpath() use on older libc

View File

@ -22,6 +22,8 @@
* - init pages to 0 before load
* 14/2/19
* - rework as a sequential loader ... simpler, much lower mem use
* 6/7/19
* - support array of delays
*/
/*
@ -135,6 +137,7 @@ typedef struct _VipsForeignLoadGif {
/* Delays between frames (in milliseconds).
*/
int *delays;
int delays_length;
/* Number of times to loop the animation.
*/
@ -519,10 +522,22 @@ vips_foreign_load_gif_scan_extension( VipsForeignLoadGif *gif )
gif->has_transparency = TRUE;
}
if( gif->n_pages % 64 == 0 )
gif->delays = (int *) g_realloc( gif->delays, (gif->n_pages + 64) * sizeof(int) );
if( gif->n_pages >= gif->delays_length ) {
int old = gif->delays_length;
int i;
gif->delays[gif->n_pages] = (extension[2] | (extension[3] << 8)) * 10;
gif->delays_length =
gif->delays_length + gif->n_pages + 64;
gif->delays = (int *) g_realloc( gif->delays,
gif->delays_length * sizeof( int ) );
for( i = old; i < gif->delays_length; i++ )
gif->delays[i] = 40;
}
/* giflib uses centiseconds, we use ms.
*/
gif->delays[gif->n_pages] =
(extension[2] | (extension[3] << 8)) * 10;
while( extension != NULL )
if( vips_foreign_load_gif_ext_next( gif,
@ -575,10 +590,14 @@ vips_foreign_load_gif_set_header( VipsForeignLoadGif *gif, VipsImage *image )
vips_image_set_int( image, "gif-loop", gif->loop );
if( gif->delays ) {
/* The deprecated gif-delay field is in centiseconds.
*/
vips_image_set_int( image,
"gif-delay", VIPS_RINT( gif->delays[0] / 10.0 ) );
vips_image_set_array_int( image, "delay", gif->delays, gif->n_pages );
} else
"gif-delay", VIPS_RINT( gif->delays[0] / 10.0 ) );
vips_image_set_array_int( image,
"delay", gif->delays, gif->n_pages );
}
else
vips_image_set_int( image, "gif-delay", 4 );
if( gif->comment )
@ -1122,6 +1141,7 @@ vips_foreign_load_gif_init( VipsForeignLoadGif *gif )
gif->n = 1;
gif->transparency = -1;
gif->delays = NULL;
gif->delays_length = 0;
gif->loop = 0;
gif->comment = NULL;
gif->dispose = 0;

View File

@ -306,10 +306,13 @@ get_array_int( VipsImage *image, const char *field, int* n )
/* Returns a delay on a given index or the default delay.
*/
static int
extract_delay( int index, int *delays, int delays_length, int default_delay )
extract_delay( int index, const int *delays, int delays_length,
int default_delay )
{
if( delays == NULL || index > delays_length )
if( delays == NULL ||
index > delays_length )
return( default_delay );
return( delays[index] );
}