set default GIF frame delay to 100ms

was 1000ms, see https://github.com/libvips/libvips/issues/2582
This commit is contained in:
John Cupitt 2021-12-18 18:20:18 +00:00
parent 0a824517fa
commit 03a073b68d
6 changed files with 1452 additions and 52 deletions

View File

@ -8,16 +8,14 @@
* http://www.opensource.org/licenses/mit-license.php
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "libnsgif.h"
#include "utils/log.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "lzw.h"
#include "libnsgif.h"
/**
*
@ -67,7 +65,13 @@ enum gif_disposal {
#define GIF_BLOCK_TERMINATOR 0x00
#define GIF_TRAILER 0x3b
static gif_result gif_error_from_lzw(lzw_result l_res)
/**
* Convert an LZW result code to equivalent GIF result code.
*
* \param[in] l_res LZW response code.
* \return GIF result code.
*/
static gif_result gif__error_from_lzw(lzw_result l_res)
{
static const gif_result g_res[] = {
[LZW_OK] = GIF_OK,
@ -91,7 +95,7 @@ static gif_result gif_error_from_lzw(lzw_result l_res)
* \param height The height of the sprite
* \return GIF_INSUFFICIENT_MEMORY for a memory error GIF_OK for success
*/
static gif_result gif_initialise_sprite(
static gif_result gif__initialise_sprite(
struct gif_animation *gif,
uint32_t width,
uint32_t height)
@ -122,7 +126,7 @@ static inline uint32_t* gif__bitmap_get(
gif_result ret;
/* Make sure we have a buffer to decode to. */
ret = gif_initialise_sprite(gif, gif->width, gif->height);
ret = gif__initialise_sprite(gif, gif->width, gif->height);
if (ret != GIF_OK) {
return NULL;
}
@ -150,7 +154,7 @@ static inline void gif__bitmap_modified(
* Helper to tell the client that whether the bitmap is opaque.
*
* \param[in] gif The gif object we're decoding.
* \param[in] frmae The frame that has been decoded.
* \param[in] frame The frame that has been decoded.
*/
static inline void gif__bitmap_set_opaque(
const struct gif_animation *gif,
@ -323,7 +327,7 @@ static gif_result gif__decode_complex(
gif->gif_data, gif->buffer_size,
data + 1 - gif->gif_data);
if (res != LZW_OK) {
return gif_error_from_lzw(res);
return gif__error_from_lzw(res);
}
do {
@ -343,7 +347,7 @@ static gif_result gif__decode_complex(
if (res == LZW_OK_EOD) {
ret = GIF_OK;
} else {
ret = gif_error_from_lzw(res);
ret = gif__error_from_lzw(res);
}
break;
}
@ -396,7 +400,7 @@ static gif_result gif__decode_simple(
gif->gif_data, gif->buffer_size,
data + 1 - gif->gif_data);
if (res != LZW_OK) {
return gif_error_from_lzw(res);
return gif__error_from_lzw(res);
}
frame_data += (offset_y * gif->width);
@ -411,7 +415,7 @@ static gif_result gif__decode_simple(
if (res == LZW_OK_EOD) {
ret = GIF_OK;
} else {
ret = gif_error_from_lzw(res);
ret = gif__error_from_lzw(res);
}
break;
}
@ -646,6 +650,7 @@ static gif_result gif__parse_extension_application(
*
* \param[in] gif The gif object we're decoding.
* \param[in] frame The frame to parse extensions for.
* \param[in] pos Current position in data, updated on exit.
* \param[in] decode Whether to decode or skip over the extension.
* \return GIF_INSUFFICIENT_DATA if more data is needed,
* GIF_OK for success.
@ -754,8 +759,10 @@ static gif_result gif__parse_frame_extensions(
* 2BITS Reserved
* 3BITS Size of Local Colour Table
*
* \param[in] gif The gif object we're decoding.
* \param[in] frame The frame to parse an image descriptor for.
* \param[in] gif The gif object we're decoding.
* \param[in] frame The frame to parse an image descriptor for.
* \param[in] pos Current position in data, updated on exit.
* \param[in] decode Whether to decode the image descriptor.
* \return GIF_OK on success, appropriate error otherwise.
*/
static gif_result gif__parse_image_descriptor(
@ -858,8 +865,10 @@ static gif_result gif__colour_table_extract(
*
* Sets up gif->colour_table for the frame.
*
* \param[in] gif The gif object we're decoding.
* \param[in] frame The frame to get the colour table for.
* \param[in] gif The gif object we're decoding.
* \param[in] frame The frame to get the colour table for.
* \param[in] pos Current position in data, updated on exit.
* \param[in] decode Whether to decode the colour table.
* \return GIF_OK on success, appropriate error otherwise.
*/
static gif_result gif__parse_colour_table(
@ -894,8 +903,10 @@ static gif_result gif__parse_colour_table(
*
* Sets up gif->colour_table for the frame.
*
* \param[in] gif The gif object we're decoding.
* \param[in] frame The frame to get the colour table for.
* \param[in] gif The gif object we're decoding.
* \param[in] frame The frame to parse image data for.
* \param[in] pos Current position in data, updated on exit.
* \param[in] decode Whether to decode the image data.
* \return GIF_OK on success, appropriate error otherwise.
*/
static gif_result gif__parse_image_data(
@ -1003,7 +1014,7 @@ static struct gif_frame *gif__get_frame(
frame->frame_pointer = gif->buffer_position;
frame->redraw_required = false;
frame->disposal_method = 0;
frame->frame_delay = 100;
frame->frame_delay = 10;
frame->display = false;
frame->virgin = true;
}
@ -1327,7 +1338,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, const uint8_t *data)
lzw_result res = lzw_context_create(
(struct lzw_ctx **)&gif->lzw_ctx);
if (res != LZW_OK) {
return gif_error_from_lzw(res);
return gif__error_from_lzw(res);
}
}
@ -1340,7 +1351,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, const uint8_t *data)
}
/* exported function documented in libnsgif.h */
gif_result gif_decode_frame(gif_animation *gif, unsigned int frame)
gif_result gif_decode_frame(gif_animation *gif, uint32_t frame)
{
return gif__process_frame(gif, frame, true);
}

File diff suppressed because it is too large Load Diff

View File

@ -37,12 +37,12 @@ typedef struct gif_frame {
/** whether the frame should be displayed/animated */
bool display;
/** delay (in cs) before animating the frame */
unsigned int frame_delay;
uint32_t frame_delay;
/* Internal members are listed below */
/** offset (in bytes) to the GIF frame data */
unsigned int frame_pointer;
uint32_t frame_pointer;
/** whether the frame has previously been used */
bool virgin;
/** whether the frame is totally opaque */
@ -50,27 +50,27 @@ typedef struct gif_frame {
/** whether a full image redraw is required */
bool redraw_required;
/** how the previous frame should be disposed; affects plotting */
unsigned char disposal_method;
uint8_t disposal_method;
/** whether we acknowledge transparency */
bool transparency;
/** the index designating a transparent pixel */
unsigned int transparency_index;
uint32_t transparency_index;
/** x co-ordinate of redraw rectangle */
unsigned int redraw_x;
uint32_t redraw_x;
/** y co-ordinate of redraw rectangle */
unsigned int redraw_y;
uint32_t redraw_y;
/** width of redraw rectangle */
unsigned int redraw_width;
uint32_t redraw_width;
/** height of redraw rectangle */
unsigned int redraw_height;
uint32_t redraw_height;
/* Frame flags */
unsigned int flags;
uint32_t flags;
} gif_frame;
/* API for Bitmap callbacks */
typedef void* (*gif_bitmap_cb_create)(int width, int height);
typedef void (*gif_bitmap_cb_destroy)(void *bitmap);
typedef unsigned char* (*gif_bitmap_cb_get_buffer)(void *bitmap);
typedef uint8_t* (*gif_bitmap_cb_get_buffer)(void *bitmap);
typedef void (*gif_bitmap_cb_set_opaque)(void *bitmap, bool opaque);
typedef bool (*gif_bitmap_cb_test_opaque)(void *bitmap);
typedef void (*gif_bitmap_cb_modified)(void *bitmap);
@ -103,13 +103,13 @@ typedef struct gif_animation {
/** pointer to GIF data */
const uint8_t *gif_data;
/** width of GIF (may increase during decoding) */
unsigned int width;
uint32_t width;
/** height of GIF (may increase during decoding) */
unsigned int height;
uint32_t height;
/** number of frames decoded */
unsigned int frame_count;
uint32_t frame_count;
/** number of frames partially decoded */
unsigned int frame_count_partial;
uint32_t frame_count_partial;
/** decoded frames */
gif_frame *frames;
/** current frame decoded to bitmap */
@ -122,27 +122,27 @@ typedef struct gif_animation {
/* Internal members are listed below */
/** current index into GIF data */
unsigned int buffer_position;
uint32_t buffer_position;
/** total number of bytes of GIF data available */
unsigned int buffer_size;
uint32_t buffer_size;
/** current number of frame holders */
unsigned int frame_holders;
uint32_t frame_holders;
/** background index */
unsigned int bg_index;
uint32_t bg_index;
/** background colour */
unsigned int bg_colour;
uint32_t bg_colour;
/** image aspect ratio (ignored) */
unsigned int aspect_ratio;
uint32_t aspect_ratio;
/** size of colour table (in entries) */
unsigned int colour_table_size;
uint32_t colour_table_size;
/** whether the GIF has a global colour table */
bool global_colours;
/** global colour table */
unsigned int *global_colour_table;
uint32_t *global_colour_table;
/** local colour table */
unsigned int *local_colour_table;
uint32_t *local_colour_table;
/** current colour table */
unsigned int *colour_table;
uint32_t *colour_table;
/** previous frame for GIF_FRAME_RESTORE */
void *prev_frame;
@ -184,7 +184,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, const uint8_t *data);
* - GIF_INSUFFICIENT_MEMORY for insufficient memory to process
* - GIF_OK for successful decoding
*/
gif_result gif_decode_frame(gif_animation *gif, unsigned int frame);
gif_result gif_decode_frame(gif_animation *gif, uint32_t frame);
/**
* Releases any workspace held by a gif

View File

@ -0,0 +1,11 @@
--- libnsgif.orig.c 2021-12-18 17:58:43.829719505 +0000
+++ libnsgif.c 2021-12-18 17:58:47.773783438 +0000
@@ -1003,7 +1003,7 @@
frame->frame_pointer = gif->buffer_position;
frame->redraw_required = false;
frame->disposal_method = 0;
- frame->frame_delay = 100;
+ frame->frame_delay = 10;
frame->display = false;
frame->virgin = true;
}

View File

@ -10,7 +10,6 @@ echo copying out source files ...
cp libnsgif/src/libnsgif.c .
cp libnsgif/include/libnsgif.h .
cp libnsgif/src/lzw.[ch] .
cp libnsgif/src/utils/log.h utils
if [ -d "patches" ]
then
@ -22,4 +21,3 @@ fi
echo cleaning up ...
rm -rf libnsgif

View File

@ -270,7 +270,6 @@ print_animation( gif_animation *anim )
printf( " frame_image = %p\n", anim->frame_image );
printf( " loop_count = %d\n", anim->loop_count );
printf( " frame_holders = %d\n", anim->frame_holders );
printf( " background_index = %d\n", anim->background_index );
printf( " colour_table_size = %d\n", anim->colour_table_size );
printf( " global_colours = %d\n", anim->global_colours );
printf( " global_colour_table = %p\n", anim->global_colour_table );